Android RecyclerView Item 中的背景选择器
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25392722/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Background Selector in RecyclerView Item
提问by ademar111190
I'm using the RecyclerView
like below:
我正在使用RecyclerView
如下所示:
<android.support.v7.widget.RecyclerView
android:id="@+id/list"
android:layout_width="320dp"
android:layout_height="match_parent"/>
and my list item:
和我的清单项目:
<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>
see in detail this part android:background="@drawable/selector_medium_high"
it's a normal selector:
详细看这部分android:background="@drawable/selector_medium_high"
它是一个普通的选择器:
<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>
but when I run this code, i have no changes in background color when I touch the row....
但是当我运行此代码时,当我触摸该行时,背景颜色没有变化....
回答by Ahmed Ghonim
Set clickable
, focusable
, focusableInTouchMode
to true
in all elements of RecyclerView
"list".
设置clickable
,focusable
,focusableInTouchMode
以true
在所有元素RecyclerView
“名单”。
回答by 100rbh
Add :
添加 :
android:background="?android:attr/selectableItemBackground"
in item.xml
在 item.xml
回答by NixSam
If nothing of this works for you, like it didn't for me, use this code:
如果这些都不适合你,就像它不适合我一样,请使用以下代码:
android:foreground="?android:attr/selectableItemBackground"
The trick is in android:foreground
attribute...
诀窍在于android:foreground
属性...
回答by Lawrr
Adding android:background="?android:attr/selectableItemBackground"
to my_list_item.xml
's root layoutseems to work for me (assuming you want the default selection colour).
添加android:background="?android:attr/selectableItemBackground"
tomy_list_item.xml
的根布局似乎对我有用(假设您想要默认选择颜色)。
Also make sure the root layout's android:layout_width
is match_parent
rather than wrap_content
to ensure that the whole row is selectable.
还要确保根布局android:layout_width
是,match_parent
而不是wrap_content
确保整行都可以选择。
回答by Greg Ennis
Unfortunately using focusable views to simulate item selection is not a good solutionbecause:
不幸的是,使用可聚焦视图来模拟项目选择并不是一个好的解决方案,因为:
- Focus is lost when
notifyDataSetChanged
is called - Focus is problematic when child views are focusable
notifyDataSetChanged
调用时失去焦点- 当子视图可聚焦时,焦点是有问题的
I wrote a base adapter class to automatically handle item selection with a RecyclerView. Just derive your adapter from it and use drawable state lists with state_selected, like you would do with a list view.
我编写了一个基本的适配器类来使用 RecyclerView 自动处理项目选择。只需从中派生您的适配器并使用 state_selected 的可绘制状态列表,就像使用列表视图一样。
I have a Blog Post Hereabout it, but here is the code:
我有一篇关于它的博客文章,但这里是代码:
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);
}
});
}
}
}
回答by jingyuan iu
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;
}
});
回答by Rajiv Manivannan
Add this below attribute in your Item "my_list_item.xml"android:descendantFocusability="blocksDescendants"
This works for me !
在您的项目“my_list_item.xml”中添加以下属性android:descendantFocusability="blocksDescendants"
这对我有用!
回答by Bruno Pinto
You need to set android:clickable="true"
in the element xml, and if you have more selectors in some view inside your view, you need to set android:duplicateParentState="true"
there too.
Thats works on pre honeycomb apis.
您需要android:clickable="true"
在元素 xml 中进行设置,如果您的视图内的某个视图中有更多选择器,则也需要在android:duplicateParentState="true"
那里进行设置 。这适用于前蜂窝 apis。
回答by Davideas
As many others answered the only way is to combine selectors and new Classes to keep track of the selection, but better to delegate this calculation to the Adapter. The library FlexibleAdapterkeeps track of the selections for you, configuration change is also compatible.
正如许多其他人回答的那样,唯一的方法是结合选择器和新类来跟踪选择,但最好将此计算委托给适配器。库FlexibleAdapter会为您跟踪选择,配置更改也是兼容的。
Backgrounds color with ripple can now be done without XML part, but in the code to manage dynamic data.
带有波纹的背景颜色现在可以在没有 XML 部分的情况下完成,而是在代码中管理动态数据。
Finally, you can use lot of features with the same library, selection is a tiny basic feature you can have.
最后,您可以在同一个库中使用许多功能,选择是您可以拥有的一个很小的基本功能。
Please have a look at the description, Wiki pages and full working example: https://github.com/davideas/FlexibleAdapter
请查看说明、Wiki 页面和完整的工作示例:https: //github.com/davideas/FlexibleAdapter
回答by Juboraj Sarker
on your design or xml file just place the following lines.
在您的设计或 xml 文件中,只需放置以下几行。
android:clickable="true"
android:focusable="true"
android:background="?android:attr/activatedBackgroundIndicator"