how to highlight the selected Item of Recycler View?

前端 未结 8 1262
执念已碎
执念已碎 2020-11-28 03:02

I have a Recycler View with the Images loaded from the Internal Storage. I want to Highlight the selected item when clicked. I tried a lot of thing but it was not working. A

相关标签:
8条回答
  • 2020-11-28 03:31

    You should create a selector drawable with android:state_focused="true" attribute as below

    <?xml version="1.0" encoding="utf-8"?>
    <ripple xmlns:android="http://schemas.android.com/apk/res/android"
        android:color="?attr/colorControlHighlight">
        <item>
            <selector xmlns:android="http://schemas.android.com/apk/res/android">
                <item
                    android:drawable="@color/colorAccent"
                    android:state_focused="true" />
            </selector>
        </item>
    </ripple>
    

    then set this drawable as background of your RecyclerView row layout as

    android:background="@drawable/selector"
    
    0 讨论(0)
  • 2020-11-28 03:33

    I have tried several ways for hours and here is the two solutions I came out with. Both solutions assume I have my RecyclerView declared as follows:

    activity.xml

    <android.support.v7.widget.RecyclerView
        android:id="@+id/list"
        android:layout_height="match_parent"
        android:layout_width="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />
    

    Nothing special here, just a regular RecyclerView declaration. Now let's see the other files, starting with the most easy and viable solution.

    First solution (XML only)

    layout/item.xml

    The two important attributes here in the item's root ViewGroup are background and clickable.

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:background="@drawable/selector_item"
        android:clickable="true"
        android:gravity="center"
        android:layout_height="wrap_content"
        android:layout_width="match_parent"
        android:orientation="horizontal"
        android:padding="16dp">
    
        ...
    
    </LinearLayout>
    

    drawable/selector_item.xml

    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
    
        <item
            android:drawable="@drawable/background_item_pressed"
            android:state_pressed="true"
            />
    
        <item
            android:drawable="@drawable/background_item"
            />
    
    </selector>
    

    Second solution (XML + Java)

    item.xml

    No background nor clickable attribute here.

    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:gravity="center"
        android:layout_height="wrap_content"
        android:layout_width="match_parent"
        android:orientation="horizontal"
        android:padding="16dp">
    
        ...
    
    </LinearLayout>
    

    Adapter.java

    public class Adapter extends RecyclerView.Adapter<Adapter.ViewHolder> {
        public class ViewHolder extends RecyclerView.ViewHolder {
            public ViewHolder(View itemView) {
                super(itemView);
    
                itemView.setOnTouchListener(itemTouchListener);
            }
        }
    
        ...
        private View.OnTouchListener itemTouchListener = new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        v.setBackgroundResource(R.drawable.background_item_event_pressed);
                        break;
                    case MotionEvent.ACTION_CANCEL:
                        // CANCEL triggers when you press the view for too long
                        // It prevents UP to trigger which makes the 'pressed' background permanent which isn't what we want
                    case MotionEvent.ACTION_OUTSIDE:
                        // OUTSIDE triggers when the user's finger moves out of the view
                    case MotionEvent.ACTION_UP:
                        v.setBackgroundResource(R.drawable.background_item_event);
                        break;
                    default:
                        break;
                }
    
                return true;
            }
        };
    
        ...
    }
    

    I highly recommend using the first solution as it's easier to maintain and more powerful as it also allows you to add ripple effects (in the drawable/background_item... XML files), which I believe isn't possible with solution 2.

    0 讨论(0)
  • 2020-11-28 03:36

    If you manage to use an observable pattern flavor such as Otto or AndroidRx, you can follow how to highlight the background as explained above, and for each viewHolder's itemView you can subscribe to the observable and unsubscribe when it detaches from your recyclerview like I did here:

    https://github.com/juanmendez/jm_android_dev/blob/master/01.fragments/06.fragments_with_rx/app/src/main/java/info/juanmendez/android/recyclerview/ui/listing/recyclerview/CountryHolder.java#L49

    By the way for a quick demo my itemView is using linearLayout, so it was easy to set background color as yellow.

    0 讨论(0)
  • 2020-11-28 03:37

    you can use this code out of Adapter

    LinearLayoutManager RvLayoutManager = (LinearLayoutManager)rootlayout.getLayoutManager();
    View itemSelected = RvLayoutManager.findViewByPosition(position);
    itemSelected.setBackgroundColor(Color.Red);
    
    0 讨论(0)
  • 2020-11-28 03:38

    You can add this to your row_item.xml

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

    For example:

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:clickable="true"
       android:background="?attr/selectableItemBackground"
    
    <!-- row content -->
    

    If android version is Lolipop or greater, selector comes with ripple. And a highlight for other version. Hope it helps

    0 讨论(0)
  • 2020-11-28 03:40

    there is no selector in RecyclerView like ListView and GridView but you try below thing it worked for me

    create a selector drawable as below

    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android"> 
    <item android:state_pressed="true">
       <shape>
             <solid android:color="@color/blue" />
       </shape>
    </item>
    
    <item android:state_pressed="false">
        <shape>
           <solid android:color="@android:color/transparent" />
        </shape>
    </item>
    </selector>
    

    then set this drawable as background of your RecyclerView row layout as

    android:background="@drawable/selector"
    
    0 讨论(0)
提交回复
热议问题