首页 文章

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

提问于
浏览
55

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

  • 5

    据我所知,这个bug仅在Android 5.0中,而不是5.1 . 诀窍似乎是使用Drawable#setHotspot作为谷歌开发提示到这里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

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

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

  • 3

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

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

    这将在背景上绘制涟漪效果 .

  • 3

    我发现如果列表项的 apply the background to the root element 它似乎只能正常工作 .

    另外,请考虑使用新的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>
    
  • 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>
    
  • 125

    我调整了@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>
    

    因此,这允许您设置背景颜色并仍然具有涟漪效果 .
    for me target and minSdk are 21.

相关问题