【问题标题】:How to implement Android Recyclerview item click AND checkbox item click?如何实现 Android Recyclerview 项目点击和复选框项目点击?
【发布时间】:2017-02-02 19:57:12
【问题描述】:

我有以下有效的持有人,即我能够选中/取消选中复选框。 (复选框是 RecyclerView 卡片的一部分):

@Override
public void onBindViewHolder(final ViewHolder holder, int position) {
  holder.bindData(numbers.get(position));
  //in some cases, it will prevent unwanted situations
  holder.checkbox.setOnCheckedChangeListener(null);

  //if true, your checkbox will be selected, else unselected
  holder.checkbox.setChecked(numbers.get(position).isSelected());

  holder.checkbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
       @Override
       public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
         numbers.get(holder.getAdapterPosition()).setSelected(isChecked);
       }
  });
}

我想在 RecyclerView 上实现对项目的点击。所以,我从这个解决方案中提取了 - 请检查:https://stackoverflow.com/a/26196831/4013399

但是,现在,点击整个卡片项目有效,但无法选中/取消选中复选框。如何解决?

请帮忙。谢谢。

更新

我进行了更改 - 但是,从未输入“HERE-1,2 和 3”行。

@Override
public void onBindViewHolder(final ViewHolder holder, int position) {
Log.e("I AM ", "HERE-0");
holder.bindData(numbers.get(position));

final RelativeLayout rlyItem = holder.rlyItem;
final CheckBox checkbox = holder.checkbox;

rlyItem.setOnClickListener(new View.OnClickListener() {
    @Override public void onClick(View view) {
        mListener.onItemClicked(holder.getLayoutPosition());
        Log.e("I AM ", "HERE-1");
    }
});

checkbox.setOnClickListener(new View.OnClickListener() {
    @Override public void onClick(View view) {
        if (((CheckBox) view).isChecked()) {
            checkbox.setChecked(false);
            Log.e("I AM ", "HERE-2");
        } else {
            checkbox.setChecked(true);
            Log.e("I AM ", "HERE-3");
        }
        // Inform to Activity or the Fragment where the RecyclerView reside.
        mListener.onItemCheckBoxChecked(((CheckBox) view).isChecked(), holder.getLayoutPosition());
    }
});
//in some cases, it will prevent unwanted situations
holder.checkbox.setOnCheckedChangeListener(null);

//if true, your checkbox will be selected, else unselected
holder.checkbox.setChecked(numbers.get(position).isSelected());

checkbox.setOnCheckedChangeListener(new   CompoundButton.OnCheckedChangeListener() {
    @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
        numbers.get(holder.getAdapterPosition()).setSelected(isChecked);
        Log.e("I AM ", "HERE-4");
        //Log.e(Integer.toString(holder.getAdapterPosition()), " IS CHECKED");
    }
});

}

【问题讨论】:

  • 勾选时需要刷新该项。您可以在适配器中使用notifyItemChanged(int position)

标签: java android android-recyclerview android-cardview android-checkbox


【解决方案1】:

单击适配器类中的适配器膨胀视图,只需为您的复选框调用performClick()

 holder.itemView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            holder.checkbox.performClick();
        }
    });

【讨论】:

  • 是的,我试过了,但没有做任何改变。复选框仍然不可点击。
  • 我删除了整个“卡片项目”点击,并像您一样制作了一个 textview onClick 和 checkbox onClick 实现。但是,您现在能解释一下当用户返回活动时如何保存复选框的状态吗?这会很有帮助。谢谢。
【解决方案2】:

首先,您在复选框中添加以下属性

  android:clickable="false"
        android:focusable="false"
        android:longClickable="false"

下面是我的itemclick

 recyclerView.addOnItemTouchListener(new RecyclerItemClickListener(getActivity(), new RecyclerItemClickListener.OnItemClickListener() {
                    @Override
                    public void onItemClick(View view, int position) {
                        Utils.hideSoftKeyboard(getActivity());
                       cityAdapter.itemSelected(position);
                    }
                }));

在您的适配器中添加以下方法:

 public void itemSelected(final int position) {
        if (townModelArrayList != null && !townModelArrayList.isEmpty()) {
            townModelArrayList.get(position).setSelected(!townModelArrayList.get(position).isSelected());
            notifyDataSetChanged();
        }
    }

【讨论】:

    【解决方案3】:

    我写了一个库来处理 android recycler view item click 事件。你可以在https://github.com/ChathuraHettiarachchi/RecycleClick找到整个教程

    RecycleClick.addTo(YOUR_RECYCLEVIEW).setOnItemClickListener(new RecycleClick.OnItemClickListener() {
                @Override
                public void onItemClicked(RecyclerView recyclerView, int position, View v) {
                    // YOUR CODE
                }
            });
    

    或者你可以使用长按来处理项目

    RecycleClick.addTo(YOUR_RECYCLEVIEW).setOnItemLongClickListener(new RecycleClick.OnItemLongClickListener() {
                @Override
                public boolean onItemLongClicked(RecyclerView recyclerView, int position, View v) {
                    // YOUR CODE
                    return true;
                }
            });
    

    要处理复选框单击,您需要在适配器上设置检查更改列表

    【讨论】:

    • 谢谢!这帮助了我:)
    【解决方案4】:

    我通过删除问题链接 (https://stackoverflow.com/a/26196831/4013399) 中引用的整个类解决了这个问题。相反,我只为复选框实现了一个 onClick 侦听器。而对于整个卡片视图项目单击?,您可能会问。为此,我只是为包含我的文本框的布局实现了另一个 onClick 侦听器。 此外,为了保存复选框的状态,一个简单的设置和获取键、值对,如(复选框位置,“1”)(其中 1 表示选中)并同时在 SharedPreferences 中更新它起作用。

    【讨论】:

      【解决方案5】:

      TL;博士

      要实现 RecyclerView 项目的点击和 RecyclerView 项目中的可点击视图,您需要为它们中的每一个定义监听器。

      首先,你需要定义布局:

      <?xml version="1.0" encoding="utf-8"?>
      <android.support.v7.widget.CardView
          xmlns:android="http://schemas.android.com/apk/res/android"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          >
        <RelativeLayout
            android:id="@+id/item__rly"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="?android:selectableItemBackground"
            android:clickable="true"
            >
      
          <CheckBox
          android:id="@+id/item_cbx"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:text="Sample CheckBox" />
      
        </RelativeLayout>
      
      </android.support.v7.widget.CardView>
      

      从上面的xml代码可以发现RelativeLayout使用:

      android:background="?android:selectableItemBackground"
      android:clickable="true"
      

      这是为了使项目在单击时具有动画效果。

      其次,您需要在 Adapter 中定义点击监听接口,如下所示:

      public class YourAdapter extends
          RecyclerView.Adapter<YourAdapter.ViewHolder> {
      
        private List<YourData> mDatas;
      
        // Define listener member variable
        private static OnRecyclerViewItemClickListener mListener;
      
        // Define the listener interface
        public interface OnRecyclerViewItemClickListener {
          void onItemClicked(int position);
          void onItemCheckBoxChecked(boolean isChecked, int position);
        }
      
        // Define the method that allows the parent activity or fragment to define the listener.
        public void setOnRecyclerViewItemClickListener(OnRecyclerViewItemClickListener listener) {
          this.mListener = listener;
        }
      
        public static class ViewHolder extends RecyclerView.ViewHolder {
          RelativeLayout rlyItem;
          CheckBox cbxSample;
      
          // We also create a constructor that accepts the entire item row
          // and does the view lookups to find each subview
          public ViewHolder(View itemView) {
            // Stores the itemView in a public final member variable that can be used
            // to access the context from any ViewHolder instance.
            super(itemView);
            rlyItem = (RelativeLayout) itemView.findViewById(R.id.item__rly);
            cbxSample = (CheckBox) itemView.findViewById(R.id.item_cbx);
          }
        }
      
        // Usually involves inflating a layout from XML and returning the holder
        @Override public ViewHolder onCreateViewHolder(ViewGroup parent,
            int viewType) {
          Context context = parent.getContext();
          LayoutInflater inflater = LayoutInflater.from(context);
      
          // Inflate the custom layout
          View viewHolder = inflater.inflate(R.layout.item_layout, parent, false);
      
          // Return a new holder instance
          return new ViewHolder(viewHolder);
        }
      
        // Involves populating data into the item through holder
        @Override public void onBindViewHolder(final ViewHolder viewHolder, int position) {
          // Get the data model based on position
          final YourData data = mDatas.get(position);
      
          final RelativeLayout rlyItem = viewHolder.rlyItem;
          CheckBox cbxSample = viewHolder.cbxSample;
      
          rlyItem.setOnClickListener(new View.OnClickListener() {
            @Override public void onClick(View view) {
              mListener.onItemClicked(viewHolder.getLayoutPosition());
            }
          });
      
          cbxSample.setOnClickListener(new View.OnClickListener() {
            @Override public void onClick(View view) {
              if (((CheckBox) v).isChecked()) {
                cbxSample.setChecked(false);
              } else {
                cbxSample.setChecked(true);
              }
              // Inform to Activity or the Fragment where the RecyclerView reside.
              mListener.onItemCheckBoxChecked(((CheckBox) v).isChecked(), viewHolder.getLayoutPosition());
            }
          });
      
        }
      
        @Override public int getItemCount() {
          return mDatas.size();
        }
      

      然后,在你的 RecyclerView 代码所在的 Activity 或 Fragment 中,你需要设置监听器:

      yourAdapter.setOnRecyclerViewItemClickListener(new YourAdapter.OnRecyclerViewItemClickListener() {
        @Override 
        public void onItemClicked(int position) {
          // Do something when item clicked.   
        }
      
        @Override
        public void onItemCheckBoxChecked(boolean isChecked, int position) {
          // Do something when check box check state change.
        }
      });
      

      补充:
      要在 ReyclerView 中保存项目的状态,您需要使用 SparseBooleanArray

      【讨论】:

      • 我已经通过使用您的 itemclick 代码修复了上述问题...但是,如果我在您的代码中这样做,我的适配器无法识别 OnRecyclerViewItemClickListener 方法 - [adapter.setOnRecyclerViewItemClickListener(new adapter.OnRecyclerViewItemClickListener() {...] - 如何解决这个问题?
      • 无法解析 [new adapter.OnRecyclerViewItemClickListener] 上的符号 OnRecyclerViewItemClickListener
      • 另外,由于RelativeLayout,我的复选框在卡片上不可见。请帮助我理解。
      • 你检查我的答案了吗?
      • @Zac:您需要将new adapter.OnRecyclerViewItemClickListener() 更改为new AdapterClassName.OnRecyclerViewItemClickListener()。请注意,您需要使用适配器类名,而不是变量。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-09-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-16
      • 1970-01-01
      相关资源
      最近更新 更多