问题
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:
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
来源:https://stackoverflow.com/questions/48861878/android-view-setactive-setselected-and-recyclerview-states