具有彩色背景和波纹效果的列表视图选择器

Posted

技术标签:

【中文标题】具有彩色背景和波纹效果的列表视图选择器【英文标题】:Listview selector with colored background and ripple effect 【发布时间】:2014-10-16 02:23:57 【问题描述】:

android L 开发者预览版中的标准ListView 选择器使用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 之外使用相同的背景,例如对于LinearLayout,它按预期工作(波纹从触摸位置开始)。

【问题讨论】:

您是否在列表项上指定背景并将列表选择器设置为空? 您可以简单地将您的列表项背景设置为一种颜色并将列表选择器保留为默认值吗? ListView 对触摸事件有特殊处理,这可能会阻止您获得您想要的效果(尽管请随时在code.google.com/p/android-developer-preview/wiki/… 提交关于此的错误)。 将列表项背景设置为纯色将不起作用,这将覆盖列表选择器。如问题中所述,将波纹选择器设置为项目背景不会收到来自 ListView 的触摸热点。我决定遵循不设置任何列表项背景并将波纹设置为 listSelector 的模式。唯一的问题是我不能有一些具有不同背景的列表项并保持波纹,例如突出未读消息。 您解决了这个问题吗?我现在也面临同样的情况...... 【参考方案1】:

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

<ListView
    android:layout_
    android:layout_
    android:drawSelectorOnTop="true" />

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

【讨论】:

如果不将 drawSelectorOnTop 设置为 true,则波纹在 ListView 中的行为不正确。对我来说,它只是用波纹颜色填充按钮,而不是显示实际效果。这解决了它 - 谢谢! 这个答案只是帮助我修复了其中一个 6 小时的错误。非常感谢。 这实际上是解决这个烦人问题的最佳和最简单的答案。 有了这个我得到了涟漪,但在涟漪消失后,可绘制项目中指定的颜色完全覆盖了整个单元格,没有显示其中的内容。有谁知道如何解决这个问题? 它什么也没做。【参考方案2】:

据我所知,这个错误只存在于 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_
    android:layout_>

      <LinearLayout
            android:id="@+id/row_content"
            android:layout_
            android:layout_
            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_
    android:layout_
    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_
        android:layout_
        android:text="Large Text"
        android:id="@+id/tvTitle"/>

    <TextView
        android:layout_
        android:layout_
        android:text="Small Text"
        android:id="@+id/tvSubtitle" />

</RelativeLayout>

【讨论】:

这是我一直在寻找的答案,我认为这是问题的根源。 我有一个recyclerview,我有一个行布局,根线性布局有imageview,textview。我已将 android:background="@drawable/ripple_recycler_view_row" android:clickable="true" android:drawSelectorOnTop="true" 添加到我的根线性布局中,但波纹显示在 clecked 行元素的背景中。【参考方案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】:

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

<RelativeLayout 
                android:id="@+id/id4"
                android:layout_
                android:layout_
                android:background="@drawable/ripple_effect"
                android:clickable="true">

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

                <LinearLayout
                    android:id="@+id/id2" 
                    android:layout_
                    android:layout_
                    android:orientation="vertical"
                    android:layout_alignParentRight="true"
                    android:layout_centerVertical="true">

                    <TextView 
                        android:id="@+id/id1"
                        android:layout_
                        android:layout_
                        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_
    android:layout_
    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_
        android:layout_>

        <!-- Your content -->

    </RelativeLayout>
</LinearLayout>

【讨论】:

以上是关于具有彩色背景和波纹效果的列表视图选择器的主要内容,如果未能解决你的问题,请参考以下文章

android中具有背景颜色和imageview的自定义选择器

Spinner 下拉项目彩色背景上的波纹效果 (appcompat-v7 V21)

如何使用HTML 5和CSS 3显示彩色下拉选择器?

带有选取器(分段控件)子视图和选择手势的列表项

如何在同一视图中使用具有不同数据源的多个选取器视图?

css3选择器怎样选择元素?