Android View setActive, setSelected and RecyclerVi

2019-07-27 12:19发布

Currently I have a RecyclerView with a check box that can have three states. ticked, unticked or Locked.

I understand I can make a custom view state. The question is more understand the behavior and of the recyclerview view holder binding.

When the RecylcerView loads everything works as expected everything is unticked except for the locked items. When I clicked on an unlocked checkbox everything works as normal it check the box and un-checks the box fine.

The problem comes as soon as I click on a locked checkbox in the recylerview. After I click it every row I click on after that becomes locked whether it is locked or not. It is probably an error in my code but also might be my understanding of the view holder binding.

This is how I set up the view binding:

I have a view selector which I use to set the imageview for the check box. I used setSelected and setSetActive to give me three view states this:

<?xml version="1.0" encoding="utf-8" ?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:state_selected="true" android:state_activated="false"
        android:drawable="@drawable/check36boxchecked"/>
    <item
        android:state_selected="false" android:state_activated="false"
        android:drawable="@drawable/check36boxunchecked"/>
    <item
        android:state_selected="true" android:state_activated="true"
        android:drawable="@drawable/lock48"/>
    <item
        android:state_selected="false" android:state_activated="true"
        android:drawable="@drawable/lock48"/>
</selector>

Then obviously in my view holder I set the image to the selector.

In the onBindView holder I set it like this:

 @Override
    public void onBindViewHolder(final CreateAlarmLocalAlarmHolder holder, final int position) {
        final DownloadAlarmInfo downloadingAlarm = this.alarmToDownload.get(position);

        // Set every view holder that is locked to the locked symbol
        if (downloadingAlarm.getAlarmFreeorPaid().equals("PAID") && !downloadingAlarm.getAlarmPurchased()){
            holder.itemView.setActivated(true);
        }

        // Update the background with checked or unchecked (keeping track of the selected position)
        if (selected_position != 101){
            if(selected_position == position){
                holder.itemView.setSelected(true);
            }else{
                holder.itemView.setSelected(false);
            }
        }

        // set click listener
        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // Update the old position button background
                notifyItemChanged(selected_position);
                // Change to the new button selected position
                selected_position = position;
                // Update the new selected position background
                notifyItemChanged(selected_position);
                // Run the item click listener to play audio or video
                itemClickListener.onItemClicked(holder, downloadingAlarm, position);

            }
        });

Thanks for your help

1条回答
一纸荒年 Trace。
2楼-- · 2019-07-27 13:10

problem at below lines

 // Set every view holder that is locked to the locked symbol
    if (downloadingAlarm.getAlarmFreeorPaid().equals("PAID") && !downloadingAlarm.getAlarmPurchased()){
        holder.itemView.setActivated(true);
    }

    // Update the background with checked or unchecked (keeping track of the selected position)
    if (selected_position != 101){
        if(selected_position == position){
            holder.itemView.setSelected(true);
        }else{
            holder.itemView.setSelected(false);
        }
    }

You should use else for your if condition. Because views will reuse so if you not have else for you if,it's will keep previous state of views.

So use else for your if.

 // Set every view holder that is locked to the locked symbol
    if (downloadingAlarm.getAlarmFreeorPaid().equals("PAID") && !downloadingAlarm.getAlarmPurchased()){
        holder.itemView.setActivated(true);
    }else{
        holder.itemView.setActivated(false);
   }

    // Update the background with checked or unchecked (keeping track of the selected position)
    if (selected_position != 101){
        if(selected_position == position){
            holder.itemView.setSelected(true);
        }else{
            holder.itemView.setSelected(false);
        }
    }
  else{
    //reset your data on views
   }

Thanks

查看更多
登录 后发表回答