RecyclerView适配器项目根据需要点击不工作

时间:2017-04-24 06:34:18

标签: android android-recyclerview recycler-adapter

我有一个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);
        }
    }
}

3 个答案:

答案 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;
        }
    }
}