n1m1
n1m1

Reputation: 979

Android RecyclerView is not saving its state when scrolling back

I have a recyclerview in which onLongClick() of an item, I am showing a button. But when scroll down the recycler view and scrolling back, that button is showing on top of another item or sometimes it is not showing at all. Here is my code

public static class TextViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener,View.OnLongClickListener{
    public LinearLayout enq_layout;
    public LinearLayout item_layout;
    public TextView enquire;
    public int position;

    public TextViewHolder(View itemView) {
        super(itemView);
        item_layout= (LinearLayout) itemView.findViewById(R.id.item_layout);
        enq_layout= (LinearLayout) itemView.findViewById(R.id.enq_layout);
        enquire=(TextView) itemView.findViewById(R.id.enquire);
        //position=getLayoutPosition();
    }
}

@Override
public int getItemViewType(int position) {
    return product.get(position)!=null? VIEW_ITEM: VIEW_PROG;
}

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

        View v = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.cardlayout_product, parent, false);
        RecyclerView.ViewHolder vh = new TextViewHolder(v);
    return vh;
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
   // Toast.makeText(act, "onBindViewHolder" +position, Toast.LENGTH_LONG).show();
        final ProductDetails item = product.get(position);
        final TextViewHolder hold=((TextViewHolder)holder);

        //hold.position=position;
      //  hold.item_layout.setTag(position);

        hold.item_layout.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
             // go to next activity
            }
        });
        hold.item_layout.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View view) {
               // show enquiry button
                hold.enq_layout.setVisibility(View.VISIBLE);
            }
        });
        hold.enquire.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
               //do some operation
                int productid = Integer.parseInt(product.get(item.getPosition()).getProduct_id());
            }
        });
}
@Override
public int getItemCount() {
    return product.size();
}

I tried this way Why doesn't RecyclerView have onItemClickListener()? And how RecyclerView is different from Listview?, but I am not able to access the views inside onCreateViewHolder's onclick methods.

Upvotes: 2

Views: 2275

Answers (3)

Taras Vovkovych
Taras Vovkovych

Reputation: 4252

I had the same problem and solved this. You need to use the method of RecyclerView and set the items cache size: mRecyclerView.setItemViewCacheSize(300);

Upvotes: 1

shivpal jodha
shivpal jodha

Reputation: 102

you can try this

        public View getViewByPosition(int position, ListView lv1) {
        final int firstListItemPosition = lv1.getFirstVisiblePosition();
        final int lastListItemPosition = firstListItemPosition +     
        lv1.getChildCount() - 1;
        if (position < firstListItemPosition || position >  
       lastListItemPosition ) {
            return lv1.getAdapter().getView(position, null, lv1);
        } else {
            final int childIndex = position - firstListItemPosition;
            return lv1.getChildAt(childIndex);
        }
    }

And in your declare it like this

             selectedids ="";
                for (int i = 0; i < len; i++){

                    //View childv = lv1.getChildAt(i);
                    View childv=getViewByPosition(i, lv1);

Upvotes: 0

Smashing
Smashing

Reputation: 1710

You are going to have to create a global variable called for instance boolean shouldShowView like this:

public static class TextViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener,View.OnLongClickListener{
    public LinearLayout enq_layout;
private boolean shouldShowView;

Then in onBindViewHolder use can use the following code:

@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
   // Toast.makeText(act, "onBindViewHolder" +position, Toast.LENGTH_LONG).show();
        final ProductDetails item = product.get(position);
        final TextViewHolder hold=((TextViewHolder)holder);

if (shouldShowView) {
    hold.enq_layout.setVisibility(View.VISIBLE);
    } else {
    hold.enq_layout.setVisibility(View.INVISIBLE);
    }

Then in your onLongClick method just set the shouldShowView variable to true if there was a long click. You should also set it to false somewhere else when you want to hide the button. You might also have to keep track of which item was selected in global variable state and check whether the current position is equal to the selected position.

You might also want to move the shouldShowView check below the click listeners.

Let me know if you have any questions.

Upvotes: 0

Related Questions