0

I have a RecyclerView with different Views in each item: different number of views, different type and different positions. They come from a database.

Item 1

View type A, View type B, View type E

Item 2

View type B, View type B, View type J, View type C

. . .

Item n

View type F, View type S

A is for example a TextView, B for example a CheckBox ...

In the Holder constructor I get the Layout of the item:

public ViewHolderXXX(final View itemView) {
    super(itemView);
    mainLayout = itemView.findViewById(R.id.ly_main_layout);
}

Then, in the bindViews (), depending on the type of the view, I add another layout to the mainLayout and add the corresponding logic.

if(customObject == TextView){
    mainLayout.addView(layoutForTextView);
}

if(customObject == CheckBox){
    mainLayout.addView(layoutForCheckBox);
}
        .
        .
        .
TextView textView = layoutForTextView.findViewById(R.id.tv_text_view);

textView.setOnClickListener(new View.OnClickListener(){

    @Override
    public void onClick(View view) {

        final Intent intent = new Intent(context, OtherActivity.class);
        context.startActivity(intent);  

    }
}

Also, in the Holder I have a static class that is called from OtherActivity.

public static void notifyXXX(){
    //do something
}

In OtherActivity:

ViewHolderXXX.notifyXXX();
finish();

When I return to the Holder the items do "weird things". In the last item there are layouts that I have not added. I can not find the pattern with which they appear.

I'm pretty confused. I do not know if I designed Adapter and the ViewHolder well or if a RecyclerView is not suitable for this particular task. Also, I have had to solve other quite complicated problems.

Jose
  • 71
  • 7
  • check this https://stackoverflow.com/a/53779566/7666442 – AskNilesh Jan 31 '19 at 13:08
  • "In the last item there are layouts that I have not added." – Your item `View`s are being recycled, but you're not removing any of the `View`s that you may have added the last time the item's `View` was used. – Mike M. Jan 31 '19 at 15:36
  • Thanks, Mike! I have read and thought about your answer but I can not understand it. After adding the layouts I have to remove them (from where)? If you could extend your answer a little please... – Jose Jan 31 '19 at 17:32
  • Imagine you have an item where `customObject == TextView` is true, so you're adding `layoutForTextView` to `mainLayout` the first time around. When that item scrolls off-screen, it's eligible for recycling, which means the same overall `View` will be used for another item. That `layoutForTextView` you added last time is still there, because you've not removed it, and `RecyclerView` isn't going to remove it, either. You need to remove those `View`s yourself, before setting up the current item, or otherwise account somehow for what's already there. – Mike M. Jan 31 '19 at 19:34
  • I think I understand, but I can not get it to work. I have removed the layoutForTextView from the mainLayout before adding another one of that same type (layoutForTextView). I think I'm not removing it in the right way or in the right place (or both) :( – Jose Jan 31 '19 at 20:06
  • Finally I think I solved the problem by not having the views recycled: holder.setIsRecyclable (false); But now I have another question: if I do not use recycling, why use a RecyclerView? – Jose Feb 01 '19 at 11:40

1 Answers1

0

The solution in my case was to combine all the three array list into one from type Object and instantiates with the adapter constructor and then check the current position using an instance with the corresponding model.

@Override


 public int getItemViewType(int position) {

//Gallery.Photo and Gallery.Vedio are the models
if (objects.get(position) instanceof Gallery.Photo) {
  return VIEW_TYPE_PHOTO;
} else if (objects.get(position) instanceof Gallery.Vedio) {
  return VIEW_TYPE_VIDEO;
} else {
  return VIEW_TYPE_ESSAY;
}
  }
bugfreerammohan
  • 1,471
  • 1
  • 7
  • 22