55

ListViewandroid 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,它会像预期的那样工作(波纹从触摸位置开始)。

4

6 回答 6

127

我设法在保持连锁反应的同时获得单独颜色的列表项。使用您拥有的任何适配器设置列表项的背景,并将列表视图设置为在顶部显示选择器:

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

这将在背景上方绘制波纹效果。

于 2014-11-20T00:50:31.587 回答
6

据我所知,此错误仅存在于 Android 5.0 中,而不是 5.1 中。诀窍似乎是使用 Drawable#setHotspot 作为 Google 开发人员提示到这里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);
                }
            });
于 2015-06-11T01:55:40.097 回答
3

示例布局,其中包含作为父布局背景的涟漪效果。

<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>

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

于 2014-12-26T07:28:49.770 回答
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>
于 2014-11-17T00:20:40.490 回答
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。

于 2015-01-20T11:18:22.923 回答
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>
于 2015-03-11T09:15:58.600 回答