我有一个RecyclerView,里面有9个项目,当我点击一个项目时,它应该被选中,但是当我选择另一个项目时,它应该被选中而另一个项目应该被自动取消选择。
我做错了什么,任何帮助都值得感谢。
这是我的适配器代码
class ItemAdapter extends RecyclerView.Adapter<ItemAdapter.DataViewHolder> {
private final int mItemCount;
List<ServicesMenuModel> mServiceList;
SparseBooleanArray mArray = new SparseBooleanArray();
int pos;
ItemAdapter(int itemCount, List<ServicesMenuModel> mServiceList) {
mItemCount = itemCount;
this.mServiceList = mServiceList;
}
@Override
public DataViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.fragment_item_list_dialog_item6, parent, false);
return new DataViewHolder(v);
}
public void changeAt(int position, DataViewHolder holder) {
mArray.delete(position);
notifyItemChanged(position);
holder.mServiceText.setSelected(false);
}
@Override
public void onBindViewHolder(final DataViewHolder holder, int position) {
holder.mServiceText.setText(mServiceList.get(position).getMenuText());
holder.mServiceText.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
holder.mServiceText.setSelected(mArray.get(holder.getAdapterPosition(), false));
pos = holder.getAdapterPosition();
//When same item is clicked
if (mArray.get(holder.getAdapterPosition(), false)) {
mArray.delete(pos);
holder.mServiceText.setSelected(false);
} else
//When new item is selected
{
for (int i = 0; i < mServiceList.size(); i++) {
changeAt(i, holder);//checking to remove other items
}
mArray.put(holder.getAdapterPosition(), true);
holder.mServiceText.setSelected(true);
}
if (mListener != null) {
mListener.onItemClicked(holder.getAdapterPosition());
dismiss();
}
}
});
}
@Override
public int getItemCount() {
return mServiceList.size();
}
class DataViewHolder extends RecyclerView.ViewHolder {
TextView mServiceText;
DataViewHolder(View v) {
super(v);
mServiceText = (TextView) v.findViewById(R.id.text);
}
}
}
答案 0 :(得分:1)
这当然是一种错误的方法:
holder.mServiceText.setSelected(false);
因为此ViewHolder
也会被重复用于RecyclerView
的其他项目,因此当您向上和向后滚动时,会选择RecyclerView
的其他项目。
相反,在ViewHolder
中声明一个字段,例如boolean isSelected
并改变该字段:
holder.isSelected = true;
然后在onBindViewHolder()
中显示取决于该布尔值的内容:
if (holder.isSelected) {
// display selected content
} else {
// display unselected content
}
答案 1 :(得分:1)
我认为您的要求是一次选择一个项目。我建议使用以下方法,而不是保留一个布尔数组。
声明一个变量来保存适配器类中的最后一个选定项的索引。
ViewHolder
在void setUpOnClick(final int position) {
boolean selection = position == mLastSelectedPosition;
mServiceText.setSelected(selection);
mServiceText.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int tempOldIndex = mLastSelectedPosition;
mLastSelectedPosition = position;
if (tempOldIndex >= 0) {
notifyItemChanged(tempOldIndex);
}
notifyItemChanged(position);
// your regular code
}
}
}
内部定义像这样的onClick方法。
@Override
public void onBindViewHolder(final DataViewHolder holder, int position {
holder.setUpOnClick(position);
// your regular code
}
最后,在onBindViewHolder中调用它
describe
答案 2 :(得分:0)
我没有测试,但它会起作用。主键是使用列表实例。
希望它有所帮助。另外,如果你的监听器进行了一些UI更改,我会将notify~函数放到你的适配器使用的地方。
package net.deali.ssmarket.view;
import android.support.v7.widget.RecyclerView;
import android.util.SparseBooleanArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import net.deali.ssmarket.R;
import java.util.List;
import static android.media.CamcorderProfile.get;
/**
* Created by soochun on 2017-04-24.
*/
class ItemAdapter extends RecyclerView.Adapter<ItemAdapter.DataViewHolder> {
List<ServicesMenuModel> mServiceList;
ItemAdapter(int itemCount, List<ServicesMenuModel> mServiceList) {
this.mServiceList = mServiceList;
}
@Override
public DataViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.fragment_item_list_dialog_item6, parent, false);
return new DataViewHolder(v);
}
public void changeAt(int position, DataViewHolder holder) {
notifyItemChanged(position);
holder.mServiceText.setSelected(false);
}
@Override
public void onBindViewHolder(final DataViewHolder holder, final int position) {
final ServicesMenuModel item = mServiceList.get(position);
holder.mServiceText.setText(item.getMenuText());
holder.mServiceText.setSelected(item.isSelected());
holder.mServiceText.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
boolean setValue = !item.isSelected();
item.setSelected(setValue);
notifyItemChanged(position, item);
//if even one item is selected, should make other items make unselected.
if (setValue) {
int i = 0;
for (ServicesMenuModel servicesMenuModel : mServiceList) {
if (i != position) {
servicesMenuModel.setSelected(false);
}
i++;
}
notifyDataSetChanged(); //if recyclerView move top postion try to use notifyItemRangeChanged(0, mServiceList.size());
}
if (mListener != null) {
mListener.onItemClicked(position);
dismiss();
}
}
});
}
@Override
public int getItemCount() {
return mServiceList.size();
}
class DataViewHolder extends RecyclerView.ViewHolder {
TextView mServiceText;
DataViewHolder(View v) {
super(v);
mServiceText = (TextView) v.findViewById(R.id.text);
}
}
class ServicesMenuModel {
String menuText;
boolean isSelected;
public String getMenuText() {
return menuText;
}
public void setMenuText(String menuText) {
this.menuText = menuText;
}
public boolean isSelected() {
return isSelected;
}
public void setSelected(boolean selected) {
isSelected = selected;
}
}
}