2

I asked a question about parsing a JSON array a couple of days ago:

How do you parse a JSON Array w/o a defined array?

I'm downloading a list of 11 items(displayed in a vertical layout in an activity by a RecyclerView LinearLayoutManager). For some reason, two identical lists are being downloaded. I double checked the JSON data tested the Url in Postman and there are no duplicate values. Also, the API doesn't have a pagination parameter.

To moderator. I found a few threads on here about duplicate values in JSON. Again, there are no duplicate values in mine. Thank you in advance.

Remove Duplicate objects from JSON Array

remove duplicate values from json data

JSONUtils class from the above mentioned thread:

public class JSONUtils
{
    /**
     * Tag for the log messages
     */
    private static final String LOG_TAG = JSONUtils.class.getSimpleName();

    private static final String KEY_LINE_ID = "id";
    private static final String KEY_LINE_NAME = "name";


    public JSONUtils()
    {
    }

    public static Lines extractFeatureFromJson (String linesJSON)
    {
        // If the JSON string is empty or null, then return early.
        if (TextUtils.isEmpty(linesJSON)) {
            return null;
        }

        Lines line = null;
        try
        {
            // Create a JSONObject from the JSON file
            JSONObject jsonObject = new JSONObject(linesJSON);

            String id = "";
            if (jsonObject.has("id"))
            {
                id = jsonObject.optString(KEY_LINE_ID);
            }


            String name = "";
            if (jsonObject.has("name"))
            {
                name= jsonObject.optString(KEY_LINE_NAME);
            }

            line = new Lines(id, name);
    }
        catch (JSONException e)
    {
        // If an error is thrown when executing any of the above statements in the "try" block,
        // catch the exception here, so the app doesn't crash. Print a log message
        // with the message from the exception.
        Log.e("QueryUtils", "Problem parsing lines JSON results", e);

    }
        // Return the list of lines
        return line;
}
}

RecyclerViewAdapter class:

public class LinesAdapter extends RecyclerView.Adapter<LinesAdapter.LinesAdapterViewHolder>
{
    private static final String TAG = LinesAdapter.class.getSimpleName();

    private ArrayList<Lines> linesList = new ArrayList<Lines>();
    private Context context;
    private LinesAdapterOnClickHandler mLineClickHandler;

    /**
     * The interface that receives onClick messages.
     */
    public interface LinesAdapterOnClickHandler
    {
        void onClick(Lines textLineClick);
    }

    /**
     * Creates a Lines Adapter.
     *
     *  @param lineClickHandler The on-click handler for this adapter. This single handler is called
     *      *                     when an item is clicked.
     */
    public LinesAdapter(LinesAdapterOnClickHandler lineClickHandler, ArrayList<Lines> linesList, Context context)
    {
        mLineClickHandler = lineClickHandler;
        this.linesList = linesList;
        this.context = context;
    }

    /**
     * Cache of the children views for a line list item.
     */
    public class LinesAdapterViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener
    {
        @BindView(R.id.line_name)
        public TextView lineName;

        public LinesAdapterViewHolder(View view)
        {
            super(view);
            ButterKnife.bind(this, view);
            view.setOnClickListener(this);
        }

        /**
         * This gets called by the child views during a click.
         *
         * @param v The View that was clicked
         */
        @Override
        public void onClick(View v)
        {
            int adapterPosition = getAdapterPosition();
            Lines textLineClick = linesList.get(adapterPosition);
            mLineClickHandler.onClick(textLineClick);
        }
    }

    @Override
    public LinesAdapterViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType)
    {
        Context context = viewGroup.getContext();
        int layoutIdForListItem = R.layout.line_list_item;
        LayoutInflater inflater = LayoutInflater.from(context);
        boolean shouldAttachToParentImmediately = false;
        View view = inflater.inflate(layoutIdForListItem, viewGroup, shouldAttachToParentImmediately);
        return new LinesAdapterViewHolder(view);
    }

    /**
     * Cache of the children views for a line list item.
     */
    @Override
    public void onBindViewHolder(LinesAdapterViewHolder holder, int position)
    {
        //Binding data
        final Lines lineView = linesList.get(position);

        holder.lineName.setText(lineView.getLineName());
    }

    @Override
    public int getItemCount()
    {
        return linesList.size();
    }

    public void setLinesList(ArrayList<Lines> mLinesList)
    {
        this.linesList.addAll(mLinesList);
        notifyDataSetChanged();
    }
}
LeadBox4
  • 83
  • 2
  • 11

1 Answers1

2

This method look suspicious:

public void setLinesList(ArrayList<Lines> mLinesList)
{
    this.linesList.addAll(mLinesList);
    notifyDataSetChanged();
}

It has a name like a "setter", but it's not actually setting lines, it is adding lines. If you had code that called this twice with the same arguments, you'd wind up with duplicates.

Here are two ways to write this method so that it actually overwrites the list every time:

public void setLinesList(ArrayList<Lines> mLinesList)
{
    this.linesList.clear();
    this.linesList.addAll(mLinesList);
    notifyDataSetChanged();
}
public void setLinesList(ArrayList<Lines> mLinesList)
{
    this.linesList = new ArrayList<>(mLinesList);
    notifyDataSetChanged();
}
Ben P.
  • 52,661
  • 6
  • 95
  • 123
  • Solved! Thanks for the code sample. I did it a little bit differently: this.linesList = mLinesList; notifyDataSetChanged(); – LeadBox4 Jan 08 '19 at 04:07
  • Great, glad to help! If you found this useful, please consider upvoting and/or accepting the answer, so that other visitors can see that it worked for you. Comments can be deleted at any time. – Ben P. Jan 08 '19 at 04:40
  • Unfortunately I don't have enough points to upvote. Maybe one of the moderators could do it. I will upvote it as soon as I'm eligible to do it. Thank you again. – LeadBox4 Jan 08 '19 at 06:24