Listview选择器与彩色背景和涟漪效果

时间:2014-08-22 09:14:52

标签: android listview material-design android-5.0-lollipop rippledrawable

Android L开发人员预览中的标准ListView选择器使用colorControlHighlight触摸时产生涟漪效果,并且在未聚焦状态下具有透明背景。

我想定义一个具有彩色背景的ListView项目,并且仍然使用相同的高亮颜色显示触摸时的涟漪效果。现在,如果我定义以下drawable:

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

它可以工作,但无论触摸位置如何,纹波都会从ListView项目的中间开始。如果我在ListView之外使用相同的背景,例如对于LinearLayout,它的工作方式与预期一致(涟漪从触摸位置开始)。

6 个答案:

答案 0 :(得分:126)

我设法获得单独的彩色列表项,同时保持涟漪效果。使用您拥有的任何适配器设置列表项的背景,并设置listview以在顶部显示选择器:

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

这会在背景之上绘制涟漪效果。

答案 1 :(得分:6)

据我所知,这个bug仅在Android 5.0中,而不是5.1。诀窍似乎是使用Drawable#setHotspot作为谷歌开发提示到这里https://twitter.com/crafty/status/561768446149410816(因为晦涩的推特提示是一种很好的文档形式!)

假设你有类似这样的行布局

<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);
                }
            });

答案 2 :(得分: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>

答案 3 :(得分:3)

示例布局,其中包含作为父布局背景的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>

在这里你可以使用不同的形状,如矩形而不是椭圆形......

答案 4 :(得分:3)

我改编了@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>

因此,这允许您设置背景颜色并仍然具有连锁效果 对我来说目标和minSdk是21。

答案 5 :(得分:2)

您可以使用嵌套布局来实现此目的。只需创建例如将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>