简体   繁体   English

如何在 RecyclerView OnClickListener 中管理多个位置

[英]How to manage multiple positions in RecyclerView OnClickListener

I want to know how I can get access to other elements of the array in this onclicklistener for a Recycler view.我想知道如何在这个 onclicklistener 中访问数组的其他元素以获取 Recycler 视图。 Specifically, I want to be able to change the enabled state of a position other than the current Listener position, but within the click event.具体来说,我希望能够更改当前侦听器 position 以外的 position 的启用 state,但在点击事件中。

I'm trying to make it such that if three colors are checked (those are check boxes) every box not checked will be disabled until the number of boxes checked is < 3.我试图做到这一点,如果三个 colors 被选中(这些是复选框),每个未选中的框都将被禁用,直到选中的框数小于 3。

The for-loops I have I wrote make sense, but I can't programmatically change the enabled state within the onClickListener for some reason.我编写的 for 循环是有意义的,但由于某种原因,我无法以编程方式更改 onClickListener 中启用的 state。

  private void buildRecyclerView() {

            mRecyclerView = findViewById(R.id.recyclerView);
            mRecyclerView.setHasFixedSize(true);
            mLayoutManager = new LinearLayoutManager(this);
            mAdapter = new ExampleAdapter(mExampleList);

            mRecyclerView.setLayoutManager(mLayoutManager);
            mRecyclerView.setAdapter(mAdapter);

            mAdapter.setOnItemClickListener(new ExampleAdapter.OnItemClickListener() {
                @Override
                public void onItemClick(int position) {

                    boolean checkedState;

                    if (mExampleList.get(position).getChecked1() == false) {

                        checkedState = true;

                    } else {

                        checkedState = false;

                    }

                    changeItem(position, checkedState);

                    int sum = 0;

                    for (int i = 0; i < stringArray.length; i++) {

                        Boolean checked = mExampleList.get(i).getChecked1();

                        if (checked == true) {

                            sum = sum + 1;

                        }

                    }

                    for (int i = 0; i < stringArray.length; i++) {

                        Boolean checked = mExampleList.get(i).getChecked1();

                        if (!checked && sum == 3) {

                            mExampleList.get(i).setEnabled1(false);

                        } else {

                            mExampleList.get(i).setEnabled1(true);

                        }

                    }

                }

            });

        }

adapter适配器

public class ExampleAdapter extends RecyclerView.Adapter<ExampleAdapter.ExampleViewHolder> {

    private ArrayList<ExampleItem> mExampleList;
    private OnItemClickListener mListener;

    public interface OnItemClickListener {

        void onItemClick(int position);

    }

    public void setOnItemClickListener(OnItemClickListener listener) {

        mListener = listener;

    }

    public static class ExampleViewHolder extends RecyclerView.ViewHolder {

        public CheckBox mCheckBox;

        public ExampleViewHolder(@NonNull View itemView, final OnItemClickListener listener) {
            super(itemView);

            mCheckBox = itemView.findViewById(R.id.checkBox);

            itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {

                    if (listener != null){

                        int position = getAdapterPosition();

                        if (position != RecyclerView.NO_POSITION);
                        listener.onItemClick(position);

                    }

                }
            });

        }
    }

    public ExampleAdapter(ArrayList<ExampleItem> exampleList) {

        mExampleList = exampleList;

    }

    @NonNull
    @Override
    public ExampleViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {

        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.example_item, parent, false);
        ExampleViewHolder evh = new ExampleViewHolder(v, mListener);
        return evh;

    }

    @Override
    public void onBindViewHolder(@NonNull ExampleViewHolder holder, int position) {

        ExampleItem currentItem = mExampleList.get(position);

        holder.mCheckBox.setText(currentItem.getCheckText());
        holder.mCheckBox.setEnabled(currentItem.getEnabled1());
        holder.mCheckBox.setChecked(currentItem.getChecked1());

    }

    @Override
    public int getItemCount() {

        return mExampleList.size();

    }
}

Item Class项目 Class

public class ExampleItem {

    public String mCheckText;
    public Boolean mEnabled;
    public Boolean mChecked;

    public ExampleItem(String mCheckText, Boolean mEnabled, Boolean mChecked) {

        this.mCheckText = mCheckText;
        this.mEnabled = mEnabled;
        this.mChecked = mChecked;
    }

    public ExampleItem(String mCheckText) {
        this.mCheckText = mCheckText;
    }

    public String getCheckText() {
        return mCheckText;
    }

    public void setCheckText(String mCheckText) {
        this.mCheckText = mCheckText;
    }

    public Boolean getEnabled1() {
        return mEnabled;
    }

    public void setEnabled1(Boolean mEnabled) {
        this.mEnabled = mEnabled;
    }

    public Boolean getChecked1() {
        return mChecked;
    }

    public void setChecked1(Boolean mChecked) {
        this.mChecked = mChecked;
    }

}

在此处输入图像描述

In other words, I am trying to make everything below blue disabled until I uncheck Red, Green, or Blue!换句话说,我正在尝试禁用蓝色以下的所有内容,直到取消选中红色、绿色或蓝色!

You would need to create a setter function for your 'mExampleList' in your Adpater class, to update the dataset that the adapter is using.您需要在 Adpater class 中为您的“mExampleList”创建一个设置器 function,以更新适配器正在使用的数据集。 It obviously does not change anything, if you make changes to 'mExampleList' in your activity, without updating the list used by the Adapter.如果您在活动中对“mExampleList”进行更改,而不更新适配器使用的列表,它显然不会改变任何内容。

So at the end of your click listener you would have something like that:所以在你的点击监听器结束时,你会有这样的东西:

mAdapter.setExampleList(mExampleList)
mAdapter.notifyDataSetChanged()

Try the following:尝试以下操作:

In adapter, add below codes:在适配器中,添加以下代码:

private int selectedCount = 0;

public int getSelectedCount() {
    return selectedCount;
}

public void setSelectedCount(int selectedCount) {
    this.selectedCount = selectedCount;
    notifyDataSetChanged();
}

and change onBindViewHolder() to:并将onBindViewHolder()更改为:

@Override
public void onBindViewHolder(@NonNull ExampleViewHolder holder, int position) {

    ExampleItem currentItem = mExampleList.get(position);

    holder.mCheckBox.setText(currentItem.getCheckText());
    holder.mCheckBox.setChecked(currentItem.getChecked1());
    if ((selectedCount == 3)) holder.mCheckBox.setEnabled(currentItem.getChecked1());
    else holder.mCheckBox.setEnabled(true);
}

Then in Activity/Fragment, change mAdapter.setOnItemClickListener(new ExampleAdapter.OnItemClickListener()... to:然后在 Activity/Fragment 中,将mAdapter.setOnItemClickListener(new ExampleAdapter.OnItemClickListener()...更改为:

    mAdapter.setOnItemClickListener(new ExampleAdapter.OnItemClickListener() {
        @Override
        public void onItemClick(int position) {
            boolean checkedState;
            int selectedCount = mAdapter.getSelectedCount();

            if ((selectedCount != 3) || (mExampleList.get(position).getChecked1())) {
                if (mExampleList.get(position).getChecked1() == false) {
                    checkedState = true;
                    selectedCount++;
                } else {
                    checkedState = false;
                    selectedCount--;
                }
                changeItem(position, checkedState);
                mAdapter.setSelectedCount(selectedCount);
            }
        }
    });

Pls note that no need to have mEnabled field in the ExampleItem class.请注意, ExampleItem class 中不需要有mEnabled字段。 Hope that helps!希望有帮助!

Explanantion: About the onClick:- This is because CheckBox totally covered the layout, so itemView cannot recieve the click event.说明:关于onClick:- 这是因为CheckBox完全覆盖了布局,所以itemView无法接收到点击事件。 About RecyclerView:- The idea is simple, after modified the data set [not list, here I refer to the mExampleList and also the selectedCount], then call notifyDataSetChanged() which will redraw all recycler item views.关于RecyclerView:- 思路很简单,修改数据[不是list,这里我指的是mExampleList和selectedCount],然后调用notifyDataSetChanged()会重绘所有recycler item view。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM