RippleDrawable not showing correct state in RecyclerView

96 views Asked by At

I have a RippleDrawable with different states for selecting a list item in a RecyclerView

<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="@color/PrimaryBlue">
    <item android:id="@android:id/mask">
        <color android:color="@android:color/white" />
    </item>

    <item>
        <selector>
            <item android:state_activated="true">
                <color android:color="@color/HeaderBackgroundGrey"/>
            </item>
            <item android:state_focused="true">
                <color android:color="@color/HeaderBackgroundGrey"/>
            </item>
            <item android:state_active="true">
                <color android:color="@android:color/transparent"/>
            </item>
            <item android:state_selected="true">
                <color android:color="@android:color/transparent"/>
            </item>
            <item android:state_enabled="true">
                <color android:color="@android:color/transparent"/>
            </item>
            <item android:state_checked="true">
                <color android:color="@android:color/transparent"/>
            </item>
            <item android:state_pressed="true">
                <color android:color="@android:color/transparent"/>
            </item>
        </selector>
    </item>
</ripple>

Initially when the list loads the first item in the list is the @color/PrimaryBlue color but it should be my activated color so the blue color seems to override the activated color

When I select an item in the list I want to change the background to a dark grey color and I do that by setting the state of the view to activated in my onBindViewHolder

holder.menu_item.isActivated = selectedPosition == position

this changes that row to the background color I want BUT the first item in the list is my @color/PrimaryBlue color. I dont know what state this item is in as I thought it would be the focused state but I tried setting that in the selector but its still the blue.

As you can see here "Etherenet" is still the blue color and "Display" is what was selected with the correct background. Ethernet however should be the same color as "Wifi" now

enter image description here

The only way I can move the blue from the first item in the list is if I request focus to another view but then the blue just moves to the other list item I gave focus to.

I want the blue color to highlight when a row is hovered over for a row using a mouse or navigating via keyboard then when the item is selected it should show the Activated state color for that row and all other rows should be the default background color.

This is my layout for the row item

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/menu_item"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:background="@drawable/selected_background"
    android:focusable="true">

    <TextView
        android:id="@+id/title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="@dimen/text_margin"/>

</LinearLayout>

How do I remove/change that state of the first list item so that it is not blue or even what is the correct way of showing the selected list item in a recycler view while keeping the other states working normally with mouse and keyboard

Update:

If I change my Drawable to this

<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="@android:color/transparent">
    <item android:id="@android:id/mask">
        <color android:color="@android:color/white" />
    </item>

    <item>
        <selector>
            <item android:state_activated="true">
                <color android:color="@color/HeaderBackgroundGrey"/>
            </item>
            <item android:state_focused="true">
                <color android:color="@color/ListItemBlue"/>
            </item>
            <item android:state_hovered="true">
                <color android:color="@color/ListItemBlue"/>
            </item>
            <item android:state_drag_hovered="true">
                <color android:color="@color/ListItemBlue"/>
            </item>
        </selector>
    </item>
</ripple>

Adapter onBind

override fun onBindViewHolder(holder: ViewHolder, position: Int) {
            val item = values[position]
            holder.title.text = item

            if (lastPosition == position) {
                holder.menu_item.isActivated = true
                holder.menu_item.requestFocus()
            } else {
                holder.menu_item.isActivated = false
            }
        }

I get what I want but because I set the ripple to transparent I dont get the ripple animation when clicking

0

There are 0 answers