Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Recyclerview duplicated items on scroll

It seems like this is a pretty common question, but none of the other questions helped me on figuring this out. So, the problem is, I have a recyclerview that is duplicating the items when i scroll. Like this: duplicated items.

It looks like there's a fixed list below the scrollable list. Here's my Adapter:

public class FriendsListAdapter extends   RecyclerView.Adapter<FriendsListAdapter.ViewHolder> {
    private ArrayList<Friend> mDataset;
    private Context ctx;

    public class ViewHolder extends RecyclerView.ViewHolder {

        public TextView friendName;
        public ImageView friendPicture;

        public ViewHolder(View v) {
            super(v);
            friendName = (TextView) v.findViewById(R.id.friendName);
            friendPicture = (ImageView) v.findViewById(R.id.friendPicture);
        }
    }

    public FriendsListAdapter(ArrayList<Friend> myDataset, Context context) {
        mDataset = myDataset;
        ctx = context;
    }

    @Override
    public FriendsListAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,    int viewType) {
        View v =   LayoutInflater.from(parent.getContext()).inflate(R.layout.friend_item,   parent, false);
        ViewHolder vh = new ViewHolder(v);
        return vh;
    }


    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        holder.friendName.setText(mDataset.get(position).getName());
        holder.friendName.setTag(mDataset.get(position));

//
//        if(mDataset.get(position).getImageUrl() != null &&    !mDataset.get(position).getImageUrl().isEmpty()) {
//            holder.friendPicture.setImageBitmap(null);
//
//            Transformation transformation = new       RoundedTransformationBuilder()
//                    .cornerRadiusDp(50)
//                    .oval(false)
//                    .build();
//
//            Picasso.with(ctx)
//                    .load(mDataset.get(position).getImageUrl())
//                    .fit()
//                    .transform(transformation)
//                    .into(holder.friendPicture);
//        }

    }

    // Return the size of your dataset (invoked by the layout manager)
    @Override
    public int getItemCount() {
        return mDataset.size();
    }

}

The picasso part is commented because I was testing to see if that was the problem.

Here's my fragment's onCreateView:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {

    super.onCreateView(inflater, container, savedInstanceState);

    View view = inflater.inflate(R.layout.fragment_friends_list, container, false);
    mRecyclerView = (RecyclerView) view.findViewById(R.id.my_recycler_view);
    mLayoutManager = new LinearLayoutManager(getActivity());
    mRecyclerView.setLayoutManager(mLayoutManager);
    mDataset = new ArrayList<>();

    final ArrayList<String> values = new ArrayList<String>();

    if(MyApp.getConfigHelper().getFriends() == null || MyApp.getConfigHelper().getFriends().isEmpty()) {
        Bundle params = new Bundle();
        params.putString("fields", "id, name, picture");

        GraphRequest request = GraphRequest.newMyFriendsRequest(
                AccessToken.getCurrentAccessToken(),
                new GraphRequest.GraphJSONArrayCallback() {
                    @Override
                    public void onCompleted(JSONArray array, GraphResponse response) {
                        FacebookRequestError error = response.getError();
                        if (error == null) {
                            try {
                                Friend pictureByName;
                                for (int i = 0; i < array.length(); i++) {
                                    values.add(array.getJSONObject(i).getString("name"));
                                    JSONObject arrayObject = array.getJSONObject(i);
                                    JSONObject picObject = arrayObject.getJSONObject("picture");
                                    String fbId = arrayObject.getString("id");
                                    String picUrl = picObject.getJSONObject("data").getString("url");
                                    pictureByName = new Friend(fbId, values.get(i), picUrl);
                                    mDataset.add(pictureByName);
                                }

                                Collections.sort(mDataset);
                                MyApp.getConfigHelper().setFriends(mDataset);

                                mAdapter = new FriendsListAdapter(mDataset, getActivity());
                                mRecyclerView.setAdapter(mAdapter);

                            } catch (JSONException e) {

                            }
                        }

                    }
                });
        request.setParameters(params);
        request.executeAsync();
    } else {
        mDataset = MyApp.getConfigHelper().getFriends();
        mAdapter = new FriendsListAdapter(mDataset, getActivity());
        mRecyclerView.setAdapter(mAdapter);
    }
    return view;
}

An this is the frament:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_height="match_parent"
    tools:context="com.myApp.Activity.FriendsListActivity">


<android.support.v7.widget.RecyclerView
    android:id="@+id/my_recycler_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:scrollbars="vertical" />


</RelativeLayout>

Do you guys have any idea of what's happening?

like image 861
hrss Avatar asked Mar 26 '16 21:03

hrss


People also ask

Why does RecyclerView repeat?

RecyclerView asks the adapter to create a new list item view for the first data item in your list. Once it has the view, it asks the adapter to provide the data to draw the item. This process repeats until the RecyclerView doesn't need any more views to fill the screen.

How do I make my RecyclerView scroll smooth?

Use the setHasFixedsize method If the height of our RecyclerView items is fixed then we should use the setHasFixedsize method in our XML of our card item. This will fix the height of our RecyclerView item and prevent it from increasing or decreasing the size of our Card Layout.

What is setHasStableIds?

setHasStableIds is an optimization hint that you can give to the recycler. You're telling it "when I provide a ViewHolder , its id is unique and will not change." It's very easy to write an Adapter that does otherwise - for example, linking the id to item position.

How do I add space between items in RecyclerView?

The simplest way is to add top/bottom margins around the first item in the adapter's row. android:layout_marginBottom="4dp". (Note adding the margins to the parent layout won't cut it.)


2 Answers

Try to change

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_height="match_parent"
    tools:context="com.myApp.Activity.FriendsListActivity">

<android.support.v7.widget.RecyclerView
    android:id="@+id/my_recycler_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:scrollbars="vertical" />

</RelativeLayout>

By:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_height="match_parent"
    tools:context="com.myApp.Activity.FriendsListActivity">


<android.support.v7.widget.RecyclerView
    android:id="@+id/my_recycler_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:scrollbars="vertical" />


</LinearLayout>

I think the RelativeLayout superimpose each page of your Recycler

like image 55
Raphael Teyssandier Avatar answered Sep 27 '22 22:09

Raphael Teyssandier


@Override
public long getItemId(int position) {
    return position;
}

@Override
public int getItemViewType(int position) {
   return position;
}
like image 23
Avinash Manohar Avatar answered Sep 27 '22 22:09

Avinash Manohar