简体   繁体   English

如何实现Android Recyclerview项目单击和复选框项目单击?

[英]How to implement Android Recyclerview item click AND checkbox item click?

I had the following holder that worked, ie I was able to check/uncheck the checkbox. 我有以下工作的所有者,即我能够选中/取消选中该复选框。 (The checkbox is part of the RecyclerView card): (此复选框是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);
       }
  });
}

I wanted to implement click of the item on RecyclerView. 我想在RecyclerView上单击该项目。 So, I took from this solution - please check: https://stackoverflow.com/a/26196831/4013399 因此,我从此解决方案中获取了-请检查: https : //stackoverflow.com/a/26196831/4013399

However, now, the click of the entire card item works, but the checkbox can not be checked/unchecked. 但是,现在可以单击整个卡片项目,但是无法选中/取消选中该复选框。 How to solve this? 如何解决呢?

Please help. 请帮忙。 Thanks. 谢谢。

Update 更新

I made changes - however, "HERE-1,2 and 3" lines are never entered. 我进行了更改-但是, 从未输入“ 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");
    }
});

} }

First You add the below property in your checkbox 首先,在复选框中添加以下属性

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

Below is my itemclick 以下是我的物品

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

Add below method in your adapter : 在适配器中添加以下方法:

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

Simply call performClick() for your checkbox on click of your adapter inflated view in adapter class. 只需单击适配器类中的适配器膨胀视图,即可为您的复选框调用performClick()

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

I wrote a library to handle android recycler view item click event. 我写了一个库来处理android回收器视图项单击事件。 You can find whole tutorial in https://github.com/ChathuraHettiarachchi/RecycleClick 您可以在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
            }
        });

or to handle item long press you can use 或长按即可处理项目,您可以使用

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

to handle checkbox click you need to setCheckChangeListner on your adapter 处理复选框单击,您需要在适配器上设置setCheckChangeListner

I solved this problem by removing the whole class referenced in the question link ( https://stackoverflow.com/a/26196831/4013399 ). 我通过删除问题链接( https://stackoverflow.com/a/26196831/4013399 )中引用的整个类来解决了这个问题。 Instead I implemented an onClick listener only for the checkbox. 相反,我只为复选框实现了onClick侦听器。 And for the whole card view item click?, you may ask. 对于整个卡片视图项目,请单击“?”。 For that, I simply implemented another onClick listener for a layout that contained my textbox. 为此,我只是为包含我的文本框的布局实现了另一个onClick侦听器。 Also, to save the state of the checkboxes a simple setting and getting of key,value pairs like (checkbox position, "1") (where 1 indicates checked) and simultaneously updating this in the SharedPreferences worked. 另外,要保存复选框的状态,只需设置和获取键值对(例如(复选框位置,“ 1”)(其中1表示已选中)),然后在SharedPreferences中同时更新它即可。

TL; TL; DR DR

To implement RecyclerView item click and a clickable view in RecyclerView item, You need to define listener for each of them. 要实现RecyclerView项单击和RecyclerView项中的可单击视图,您需要为它们中的每一个定义侦听器。

First, you need to define the layout: 首先,您需要定义布局:

<?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>

From the above xml code, you can find that the RelativeLayout using: 从上面的xml代码中,您可以使用以下代码找到RelativeLayout:

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

This is to make the item having an animation when clicked. 这是为了使该项目在单击时具有动画。

Second, you need to define click listener interface within your Adapter, something like this: 其次,您需要在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();
  }

Then, in your Activity or Fragment where RecyclerView code reside, you need to set the listener: 然后,在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.
  }
});

Addition: 加成:
To hold the the state of item in your ReyclerView, you need to use SparseBooleanArray 要在ReyclerView中保持项目的状态,您需要使用SparseBooleanArray

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

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