RecyclerView项目中的背景select器
我正在使用如下所示的RecyclerView
:
<android.support.v7.widget.RecyclerView android:id="@+id/list" android:layout_width="320dp" android:layout_height="match_parent"/>
和我的清单项目:
<LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@drawable/selector_medium_high"> <com.basf.suvinil.crie.ui.common.widget.CircleView android:id="@+id/circle" android:layout_width="22dp" android:layout_height="22dp"/> <TextView android:id="@+id/label" android:layout_width="match_parent" android:layout_height="wrap_content" android:minHeight="57.5dp"/> </LinearLayout>
详细看这部分android:background="@drawable/selector_medium_high"
这是一个普通的select器:
<selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@color/background_high" android:state_activated="true"/> <item android:drawable="@color/background_high" android:state_pressed="true"/> <item android:drawable="@color/background_high" android:state_checked="true"/> <item android:drawable="@color/background_high" android:state_focused="true"/> <item android:drawable="@color/background_medium"/> </selector>
但是当我运行这个代码,我没有改变背景颜色当我触摸行….
在RecyclerView
“list”的所有元素中设置clickable
, focusable
, focusableInTouchMode
为true
。
地址:
android:background="?android:attr/selectableItemBackground"
在item.xml
将android:background="?android:attr/selectableItemBackground"
到my_list_item.xml
的根布局似乎适用于我(假设您需要默认的select颜色)。
还要确保根布局的android:layout_width
是match_parent
而不是wrap_content
以确保整行是可选的。
如果没有这个对你有效,就像它不适合我,使用这个代码:
android:foreground="?android:attr/selectableItemBackground"
技巧是在android:foreground
属性…
不幸的是使用可调焦视图来模拟项目select不是一个好的解决scheme,因为:
-
notifyDataSetChanged
被调用时焦点丢失 - 孩子的观点是可以聚焦的,重点是有问题的
我写了一个基类适配器类来自动处理与RecyclerView的项目select。 只需从中获取适配器,并使用state_selected绘制状态列表,就像使用列表视图一样。
我有一个博客文章关于它,但这里是代码:
public abstract class TrackSelectionAdapter<VH extends TrackSelectionAdapter.ViewHolder> extends RecyclerView.Adapter<VH> { // Start with first item selected private int focusedItem = 0; @Override public void onAttachedToRecyclerView(final RecyclerView recyclerView) { super.onAttachedToRecyclerView(recyclerView); // Handle key up and key down and attempt to move selection recyclerView.setOnKeyListener(new View.OnKeyListener() { @Override public boolean onKey(View v, int keyCode, KeyEvent event) { RecyclerView.LayoutManager lm = recyclerView.getLayoutManager(); // Return false if scrolled to the bounds and allow focus to move off the list if (event.getAction() == KeyEvent.ACTION_DOWN) { if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) { return tryMoveSelection(lm, 1); } else if (keyCode == KeyEvent.KEYCODE_DPAD_UP) { return tryMoveSelection(lm, -1); } } return false; } }); } private boolean tryMoveSelection(RecyclerView.LayoutManager lm, int direction) { int tryFocusItem = focusedItem + direction; // If still within valid bounds, move the selection, notify to redraw, and scroll if (tryFocusItem >= 0 && tryFocusItem < getItemCount()) { notifyItemChanged(focusedItem); focusedItem = tryFocusItem; notifyItemChanged(focusedItem); lm.scrollToPosition(focusedItem); return true; } return false; } @Override public void onBindViewHolder(VH viewHolder, int i) { // Set selected state; use a state list drawable to style the view viewHolder.itemView.setSelected(focusedItem == i); } public class ViewHolder extends RecyclerView.ViewHolder { public ViewHolder(View itemView) { super(itemView); // Handle item click and set the selection itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // Redraw the old selection and the new notifyItemChanged(focusedItem); focusedItem = mRecyclerView.getChildPosition(v); notifyItemChanged(focusedItem); } }); } } }
viewHolder.mRlPrince.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { if (event.getAction()==MotionEvent.ACTION_DOWN){ viewHolder.mRlPrince.setBackgroundColor(Color.parseColor("#f8f8f8")); }if (event.getAction()==MotionEvent.ACTION_UP){ viewHolder.mRlPrince.setBackgroundColor(Color.WHITE); } return false; } });
在您的项目“my_list_item.xml”中添加以下属性
android:descendantFocusability="blocksDescendants"
这对我android:descendantFocusability="blocksDescendants"
!
您需要在元素xml中设置android:clickable="true"
,并且如果在视图中的某个视图中有更多的select器,则还需要设置android:duplicateParentState="true"
。 这对蜂窝蜂窝蜂巢是有效的。
和其他许多人一样,唯一的办法就是结合select器和新的类来跟踪select,但是更好地将这个计算委托给适配器。 FlexibleAdapter库跟踪您的select,configuration更改也是兼容的。
带纹理的背景颜色现在可以在没有XML部分的情况下完成,而是在代码中pipe理dynamic数据。
最后,你可以在同一个库中使用很多function,select是一个很小的基本function。
请看看描述,Wiki页面和完整的工作示例: https : //github.com/davideas/FlexibleAdapter