Селектор Listview с цветным фоном и эффектом пульсации

Стандартный селектор ListView в предварительном просмотре предварительного просмотра android L использует colorControlHighlight для эффекта пульсации при касании и имеет прозрачный фон в нефокусированном состоянии.

Я хотел бы определить элемент ListView, который имеет цветной фон и все еще показывает эффект пульсации при касании с тем же цветом выделения. Теперь, если я определяю следующее допустимое:

<ripple xmlns:android="http://schemas.android.com/apk/res/android"
        android:color="?android:colorControlHighlight">
    <item android:drawable="@color/my_background_color"/>
</ripple>

он работает, но пульсация начинается в середине элемента ListView, независимо от положения касания. Если я использую тот же фон вне ListView, например. при a LinearLayout он работает как ожидаемый (пульсация начинается в позиции касания).

Ответ 1

Мне удалось получить индивидуально окрашенные элементы списка, сохраняя эффект пульсации. Установите фон элементов списка с помощью любого адаптера, который у вас есть, и установите для списка, чтобы показывать селектор сверху:

<ListView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:drawSelectorOnTop="true" />

Это приведет к эффекту пульсации над фоном.

Ответ 2

Насколько я могу судить об этой ошибке только в Android 5.0, а не в 5.1. Трюк, похоже, заключается в том, чтобы использовать Drawable # setHotspot в качестве подсказок Google dev здесь https://twitter.com/crafty/status/561768446149410816 (поскольку неясные подсказки для Twitter - отличная форма документации!)

Предположим, что у вас есть макет строки, что-то вроде этого

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

      <LinearLayout
            android:id="@+id/row_content"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:background="?attr/selectableItemBackground">

          .... content here .....

     </LinearLayout>

</FrameLayout>

Следующие работали для меня

            row.setOnTouchListener(new View.OnTouchListener() {
                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    v.findViewById(R.id.row_content)
                        .getBackground()
                        .setHotspot(event.getX(), event.getY());

                    return(false);
                }
            });

Ответ 3

Я обнаружил, что он работает, только если вы примените фон к корневому элементу элемента списка.

Кроме того, рассмотрите возможность использования RecyclerView вместо ListView

Пример просмотра списка элементов:

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginTop="@dimen/list_padding"
    android:layout_marginLeft="@dimen/list_padding"
    android:layout_marginRight="@dimen/list_padding"
    android:padding="@dimen/list_padding"
    android:background="@drawable/ripple_bg">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Large Text"
        android:id="@+id/tvTitle"/>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Small Text"
        android:id="@+id/tvSubtitle" />

</RelativeLayout>

Ответ 4

я адаптировал @ArhatBaid, чтобы ответить на маленький бит, протестировал его, и он отлично работает:

<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="?android:colorControlHighlight">
    <item android:drawable="@color/light_grey_header_navigation_drawer"/>
</ripple>

Таким образом, это позволяет вам установить цвет фона и все еще иметь эффект пульсации.
для меня target и minSdk равны 21.

Ответ 5

Пример макета, который содержит эффект Ripple в качестве фона родительского макета.

<RelativeLayout 
                android:id="@+id/id4"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:background="@drawable/ripple_effect"
                android:clickable="true">

                <ImageView 
                    android:id="@+id/id3"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_alignParentLeft="true"
                    android:background="@drawable/image"
                    android:layout_centerVertical="true"/>

                <LinearLayout
                    android:id="@+id/id2" 
                    android:layout_width="fill_parent"
                    android:layout_height="wrap_content"
                    android:orientation="vertical"
                    android:layout_alignParentRight="true"
                    android:layout_centerVertical="true">

                    <TextView 
                        android:id="@+id/id1"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="@string/text"/>

                </LinearLayout>
            </RelativeLayout>

Ripple_effect.xml Здесь вы можете использовать любой цвет по вашему выбору. Убедитесь, что вы используете sdk-версию 21 и имеете папку drawable-v21 и style-v21 и поместите в нее весь файл, связанный с v21.

<ripple xmlns:android="http://schemas.android.com/apk/res/android" 
                  android:color="?android:colorControlHighlight">
    <item android:id="@android:id/mask">
        <shape android:shape="oval">
            <solid android:color="?android:colorAccent" />
        </shape>
    </item>

Здесь вы можете использовать другую форму, например прямоугольник, вместо овального...

Ответ 6

Вы можете добиться этого с помощью вложенного макета. Просто создайте, например. LinearLayout в качестве корневого макета вокруг существующего макета, установите эффект пульсации на корневой макет и цвет фона на вложенный.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/ripple_effect"
    android:orientation="vertical">

    <RelativeLayout xmlns:app="http://schemas.android.com/apk/res-auto"
        android:id="@+id/containterContent"
        android:background="@color/yourCOLOR"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <!-- Your content -->

    </RelativeLayout>
</LinearLayout>