我在onClickListener
上为CheckBox
设置RecyclerView
,其中包含一个CardView列表。在ItemHolder
扩展ViewHolder
的{{1}}中设置了侦听器。初次点击CardView
会检查CheckBox
,并将CardView的背景颜色从默认的白色切换为红色。这工作正常。
我在OnClickListener
本身也设置了CardView
。 OnClickListener
已在onCreateViewHolder()
中设置。点击CardView
即可为CardView
启动新的详情活动。这工作正常。
最后,我尝试在CardView上设置onLongClickListener
。在{onCreateViewHolder()中设置了OnLongClickListener
。 CardView上的longpress意味着将背景颜色切换为红色并启动AlertDialog,以便用户可以确认将从列表中删除CardView。这可以正常工作,但是当此代码添加到适配器时,CardView的CheckBox的OnClickListerner
不再有效。就好像OnLongClickListner
与CheckBox监听器冲突一样。注意我做"返回true"在itemHolder的onLongClick()
代码中。我在这里缺少什么?
Adapter.java
public MyRecylerAdapter(Context context, ArrayList<ListItem> listItems, ArrayList<ListItem> selectedList) {
this.mContext = context;
this.mListItems = listItems;
this.selectedItemsList = selectedList;
}
private int selectedPos = -1;
...
private class ItemHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private CardView cardView;
private CheckBox chkSelected;
private ItemHolder(final View itemView) {
super(itemView);
cardView = (CardView) itemView.findViewById(R.id.singlecard_view1);
chkSelected = (CheckBox) itemView.findViewById(R.id.chkSelected);
chkSelected.setOnClickListener(this);
}
public void onClick(View v) {
int adapterPos = getAdapterPosition();
if (adapterPos == android.support.v7.widget.RecyclerView.NO_POSITION) return;
if (recyclerItemClickListener !=null) {
recyclerItemClickListener.onCheckBoxClick(v, adapterPos);
}
Integer iPos = adapterPos;
if (((CheckBox)v).isChecked()) {
checkedListItems.add(iPos);
}
else {
checkedListItems.remove(iPos);
}
}
void bind(int position) {
if (checkedListItems.contains(position)) {
chkSelected.setChecked(true);
}
else {
chkSelected.setChecked(false);
}
}
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_contact_item, parent, false);
final ItemHolder itemHolder = new ItemHolder(view);
itemHolder.itemView.setOnClickListener(new View.OnClickListener() {
// Handles the row being clicked.
@Override
public void onClick(View view) {
ListItem adapterItem = MyRecylerAdapter.this.getItem(itemHolder.getAdapterPosition());
if (recyclerItemClickListener != null) {
recyclerItemClickListener.onItemClick(itemHolder.itemView, adapterItem);
}
}
});
itemHolder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View view) {
ListItem adapterItem2 = MyRecylerAdapter.this.getItem(itemHolder.getAdapterPosition());
if (recyclerItemClickListener != null) {
recyclerItemClickListener.onItemLongClick(itemHolder.itemView, adapterItem2);
}
int adapterPos2 = itemHolder.getAdapterPosition();
if (adapterPos2 != android.support.v7.widget.RecyclerView.NO_POSITION) {
int lastSelectedPosition = selectedPos;
selectedPos = adapterPos2;
notifyItemChanged(lastSelectedPosition);
notifyItemChanged(selectedPos);
}
return true;
}
});
return itemHolder;
}
public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) {
final ListItem listItem = mListItems.get(position);
final ItemHolder itemHolder = (ItemHolder) holder;
itemHolder.bind(position);
if (checkedListItems.contains(position)) {
itemHolder.cardView.setActivated(true);
}
else {
itemHolder.cardView.setActivated(false);
}
// **The addition of the below code causes the "itemHolder.cardView.
// setActivated(true);" in onBindViewHolder method to no longer fire, as
// a click on the CheckBox no longer changes the CardView background
// color.**
if (itemHolder.getAdapterPosition() == selectedPos) {
itemHolder.cardView.setActivated(true);
} else {
itemHolder.cardView.setActivated(false);
}
list_contact_item.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
xmlns:card_view="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/singlecard_view1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:foreground="?android:attr/selectableItemBackground"
>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/statelist_cardview_background" >
<CheckBox
android:id="@+id/chkSelected"
android:layout_width="wrap_content"
android:layout_height="30dp"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true"
android:layout_alignParentLeft="true"
android:layout_marginLeft="4dp"
android:layout_marginStart="4dp"
android:layout_marginTop="4dp"
android:gravity="center" />
<TextView
android:id="@+id/cardType1"
android:layout_width="wrap_content"
android:layout_height="30dp"
android:layout_toRightOf="@+id/chkSelected"
android:layout_toEndOf="@+id/chkSelected"
android:layout_alignParentTop="true"
android:paddingStart="3dp"
android:paddingLeft="3dp"
android:paddingEnd="6dp"
android:paddingRight="6dp"
android:layout_marginTop="4dp"
android:gravity="center"
android:textColor="#ffffff"
android:textStyle="bold|italic"
style="@style/Base.TextAppearance.AppCompat.Subhead" />
<TextView
android:id="@+id/cardBlankText1"
android:layout_width="wrap_content"
android:layout_height="30dp"
android:layout_alignParentTop="true"
android:layout_toRightOf="@+id/cardType1"
android:layout_toEndOf="@+id/cardType1"
android:layout_toLeftOf="@+id/cardBlankTextNumstotal"
android:layout_toStartOf="@+id/cardBlankTextNumstotal"
android:layout_marginTop="4dp"
android:gravity="center_vertical|end"
android:text="#"
android:textColor="@color/colorFlLabelFinal"
android:textStyle="bold"
android:maxLines="1"
style="@style/Base.TextAppearance.AppCompat.Subhead" />
<TextView
android:id="@+id/cardBlankTextNumstotal"
android:layout_width="wrap_content"
android:layout_height="30dp"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:gravity="center"
android:text="actual card #"
android:layout_marginTop="4dp"
android:layout_marginRight="4dp"
android:layout_marginEnd="4dp"
android:freezesText="true"
android:textColor="@android:color/black"
android:maxLines="1"
style="@style/Base.TextAppearance.AppCompat.Subhead" />
<TextView
android:id="@+id/cardBlankText2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_below="@+id/chkSelected"
android:layout_marginTop="4dp"
android:layout_marginLeft="6dp"
android:layout_marginStart="6dp"
android:text="todo"
android:textColor="@android:color/black"
android:textStyle="bold"
android:background="@drawable/todo_underline"
android:maxLines="1"
style="@style/Base.TextAppearance.AppCompat.Headline" />
...
</RelativeLayout>
</android.support.v7.widget.CardView>
statelist_cardview_background.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_activated="true"
android:drawable="@color/item_selected" />
<item android:state_activated="false"
android:drawable="@color/list_contact_item_default" />
</selector>
colors.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="list_contact_item_default">#FFFFFF</color>
<color name="item_selected">#FF0000</color>
</resources>
答案 0 :(得分:2)
为什么你没有使用 OnCheckedChangeListener 作为复选框?
CheckBox chkBox = ( CheckBox ) findViewById( R.id.checkbox );
chkBox.setOnCheckedChangeListener(new OnCheckedChangeListener()
{
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
{
if ( isChecked )
{
// perform logic
}
}
});
答案 1 :(得分:0)
试试这个
public class MyRecylerAdapter extends RecyclerView.Adapter<MyRecylerAdapter.ItemHolder> {
...
public MyRecylerAdapter(Context context, ArrayList<ListItem> listItems,
ArrayList<ListItem> selectedList) {
this.mContext = context;
this.mListItems = listItems;
this.selectedItemsList = selectedList;
}
private int selectedPos = -1;
public class ItemHolder extends RecyclerView.ViewHolder {
private CardView cardView;
private CheckBox chkSelected;
private ItemHolder(final View itemView) {
super(itemView);
cardView = (CardView) itemView.findViewById(R.id.singlecard_view1);
chkSelected = (CheckBox) itemView.findViewById(R.id.chkSelected);
}
void bind(int position) {
if (checkedListItems.contains(position)) {
chkSelected.setChecked(true);
} else {
chkSelected.setChecked(false);
}
}
}
@Override
public ItemHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_contact_item, parent, false);
final ItemHolder itemHolder = new ItemHolder(view);
return itemHolder;
}
public void onBindViewHolder(final ItemHolder itemHolder, final int position) {
final ListItem listItem = mListItems.get(position);
itemHolder.bind(position);
if (checkedListItems.contains(position)) {
itemHolder.cardView.setActivated(true);
} else {
itemHolder.cardView.setActivated(false);
}
if (itemHolder.getAdapterPosition() == selectedPos) {
itemHolder.cardView.setActivated(true);
} else {
itemHolder.cardView.setActivated(false);
}
itemHolder.itemView.setOnClickListener(new View.OnClickListener() {
// Handles the row being clicked.
@Override
public void onClick(View view) {
if (recyclerItemClickListener != null) {
recyclerItemClickListener.onItemClick(itemHolder.itemView, listItem);
}
}
});
itemHolder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View view) {
if (recyclerItemClickListener != null) {
recyclerItemClickListener.onItemLongClick(itemHolder.itemView, listItem);
}
int adapterPos2 = itemHolder.getAdapterPosition();
if (adapterPos2 != android.support.v7.widget.RecyclerView.NO_POSITION) {
int lastSelectedPosition = selectedPos;
selectedPos = adapterPos2;
notifyItemChanged(lastSelectedPosition);
notifyItemChanged(selectedPos);
}
return true;
}
});
itemHolder.chkSelected.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (position == android.support.v7.widget.RecyclerView.NO_POSITION) return;
if (recyclerItemClickListener != null) {
recyclerItemClickListener.onCheckBoxClick(v, position);
}
Integer iPos = position;
if (((CheckBox) v).isChecked()) {
checkedListItems.add(iPos);
} else {
checkedListItems.remove(iPos);
}
}
});
}
@Override
public int getItemCount() {
return mListItems.size();
}
}
答案 2 :(得分:0)
如果我正确理解了您的问题,请尝试使用此代码并告诉我它是否无法正常工作
适配器Java代码
public class Adapter extends RecyclerView.Adapter<Adapter.ItemHolder> {
private ArrayList<DemoData> mDemoData;
public Adapter() {
mDemoData = new ArrayList<>();
for (int i = 0; i <= 100; i++) {
mDemoData.add(new DemoData("Item " + i, false));
}
}
@Override
public ItemHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new ItemHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.recyler_card, parent, false));
}
@Override
public void onBindViewHolder(ItemHolder holder, int position) {
//Check if the item is check and toggle the checkbox
if (mDemoData.get(position).checked) {
holder.mCheckBox.setChecked(true);
} else {
holder.mCheckBox.setChecked(false);
}
//Set text to the textview
holder.mTextView.setText(mDemoData.get(position).item);
}
@Override
public int getItemCount() {
return mDemoData.size();
}
public class ItemHolder extends RecyclerView.ViewHolder {
private TextView mTextView;
private CheckBox mCheckBox;
public ItemHolder(View itemView) {
super(itemView);
mTextView = (TextView) itemView.findViewById(R.id.textView);
mCheckBox = (CheckBox) itemView.findViewById(R.id.checkbox);
//set OnClickListener
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(mCheckBox.getContext(), "Clicked", Toast.LENGTH_SHORT).show();
}
});
//set OnLongClickListener
itemView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
//if handled return true if not return false;
Toast.makeText(mCheckBox.getContext(), "Long Clicked", Toast.LENGTH_SHORT).show();
return false;
}
});
mCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
mDemoData.get(getAdapterPosition()).checked = isChecked;
}
});
}
}
}
ItemView XML代码
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="75dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="75dp"
android:orientation="horizontal">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<CheckBox
android:id="@+id/checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
</android.support.v7.widget.CardView>
活动Java代码
public class RecyclerDemoActivity extends AppCompatActivity {
private RecyclerView mRecyclerView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_recycler_demo);
mRecyclerView = (RecyclerView) findViewById(R.id.recyclerView);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
mRecyclerView.setAdapter(new Adapter());
}
}
只需使用此演示并相应地更改代码。
修改强> 这是使用的模型类。
public class DemoData{
public String item;
public boolean checked;
public DemoData(String item,boolean isChecked){
this.item=item;
this.checked=isChecked;
}
}
<强> | REY | 强>
答案 3 :(得分:0)
看来你正试图在这里解决错误的问题。你应该不设置点击&amp;长期点击卡片视图上的听众本身。
如果您想选中/取消选中复选框,也可以点击view_container ,您可以在view_container onClick <强>听众。
修改强>: 我已经更新了你的布局文件,现在注意你在FrameLayout上作为RelativeLayout(view_container)&amp;的父级。复选框。
在RelativeLayout之后添加Checkbox时,它将在view_container之上显示。希望它对你有用。
现在您可以设置点击监听器,如上所述。
更新了布局文件
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
xmlns:card_view="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/singlecard_view1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:foreground="?android:attr/selectableItemBackground"
>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:id="@+id/view_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/statelist_cardview_background" >
<TextView
android:id="@+id/cardType1"
android:layout_width="wrap_content"
android:layout_height="30dp"
android:layout_marginLeft="30dp"
android:layout_marginStart="30dp"
android:layout_alignParentTop="true"
android:paddingStart="3dp"
android:paddingLeft="3dp"
android:paddingEnd="6dp"
android:paddingRight="6dp"
android:layout_marginTop="4dp"
android:gravity="center"
android:textColor="#ffffff"
android:textStyle="bold|italic"
style="@style/Base.TextAppearance.AppCompat.Subhead" />
<TextView
android:id="@+id/cardBlankText1"
android:layout_width="wrap_content"
android:layout_height="30dp"
android:layout_alignParentTop="true"
android:layout_toRightOf="@+id/cardType1"
android:layout_toEndOf="@+id/cardType1"
android:layout_toLeftOf="@+id/cardBlankTextNumstotal"
android:layout_toStartOf="@+id/cardBlankTextNumstotal"
android:layout_marginTop="4dp"
android:gravity="center_vertical|end"
android:text="#"
android:textColor="@color/colorFlLabelFinal"
android:textStyle="bold"
android:maxLines="1"
style="@style/Base.TextAppearance.AppCompat.Subhead" />
<TextView
android:id="@+id/cardBlankTextNumstotal"
android:layout_width="wrap_content"
android:layout_height="30dp"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:gravity="center"
android:text="actual card #"
android:layout_marginTop="4dp"
android:layout_marginRight="4dp"
android:layout_marginEnd="4dp"
android:freezesText="true"
android:textColor="@android:color/black"
android:maxLines="1"
style="@style/Base.TextAppearance.AppCompat.Subhead" />
<TextView
android:id="@+id/cardBlankText2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_marginTop="34dp"
android:layout_marginLeft="6dp"
android:layout_marginStart="6dp"
android:text="todo"
android:textColor="@android:color/black"
android:textStyle="bold"
android:background="@drawable/todo_underline"
android:maxLines="1"
style="@style/Base.TextAppearance.AppCompat.Headline" />
...
</RelativeLayout>
<CheckBox
android:id="@+id/chkSelected"
android:layout_width="wrap_content"
android:layout_height="30dp"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true"
android:layout_alignParentLeft="true"
android:layout_marginLeft="4dp"
android:layout_marginStart="4dp"
android:layout_marginTop="4dp"
android:gravity="center" />
</FrameLayout>
</android.support.v7.widget.CardView>
答案 4 :(得分:0)
你应该给你数据(mListItems)添加一个isChecked Fileds!你可以这样做
holder.checkebox.setchecked(false);
if(mListItems.get(position).ischekced){
holder.checkebox.setchecked(true);
}
holder.checkebox..setOnCheckedChangeListener(new OnCheckedChangeListener(){
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
{
mListItems.get(position).isChecked=isChecked;
}
});