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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 09:24:21  来源:igfitidea点击:

Background Selector in RecyclerView Item

androidselectorandroid-recyclerview

提问by ademar111190

I'm using the RecyclerViewlike 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, focusableInTouchModeto truein all elements of RecyclerView"list".

设置clickablefocusablefocusableInTouchModetrue在所有元素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:foregroundattribute...

诀窍在于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_widthis match_parentrather than wrap_contentto 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 notifyDataSetChangedis 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"