我有一个ImageView用作Relativelayout的背景,上面有一个刷新按钮。按钮的波纹效果被其下方的Im​​ageView覆盖。我已经尝试过FrameLayouts等,但似乎无济于事。

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/nav_drawer"
    android:layout_width="315dp"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    android:background="@color/sidebar_bg_color"
    android:orientation="vertical">

    <ImageView
        android:id="@+id/imageView4"
        android:layout_width="fill_parent"
        android:layout_height="165dp"
        android:layout_alignParentTop="true"
        android:src="@drawable/device_bg" />

    <LinearLayout
        android:layout_width="48dp"
        android:layout_height="48dp"
        android:layout_alignParentEnd="true"
        android:layout_alignParentTop="true"
        android:background="?android:attr/selectableItemBackgroundBorderless"
        android:clickable="true"
        android:focusable="true"
        android:gravity="center"
        android:orientation="vertical">

        <ImageView
            android:id="@+id/imageView3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/sidebar_refresh" />
    </LinearLayout>

</RelativeLayout>

最佳答案

使用selectableItemBackgroundBorderless,您可以这样:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/nav_drawer"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    android:background="@android:color/holo_green_light"
    android:orientation="vertical">

    <ImageView
        android:id="@+id/imageView4"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_alignParentTop="true"
        android:scaleType="fitXY"
        android:src="@drawable/device_bg" />

    <ImageView
        android:layout_width="48dp"
        android:layout_height="48dp"
        android:layout_alignParentEnd="true"
        android:layout_alignParentTop="true"
        android:src="@drawable/sidebar_refresh" />

    <LinearLayout
        android:layout_width="48dp"
        android:layout_height="48dp"
        android:layout_alignParentEnd="true"
        android:layout_alignParentTop="true">
        <FrameLayout
            android:layout_weight="1"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:padding="7dp"
            android:background="@android:color/transparent">
            <ImageView
                android:id="@+id/imageView3"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:clickable="true"
                android:src="@drawable/sidebar_refresh"
                android:alpha="0"
                android:background="?attr/selectableItemBackgroundBorderless"/>
        </FrameLayout>
    </LinearLayout>

</RelativeLayout>

关键是波纹效果必须具有自己的布局( LinearLayout + FrameLayout ),然后使用alpha="0"将具有波纹的图像设置为透明,以覆盖实心图像。

此代码的问题是:
  • 您必须对填充进行硬编码。如果没有填充或填充太小,则波纹效果将绑定(bind)到矩形而不是圆形。使用公式48(高度/宽度)/7可以计算出填充量。如果除以7不起作用,请减小除数,例如6.
  • 因为它具有填充,所以您不能触摸填充来触发波纹效果。如果这不是一个明显的小按钮,这是可以接受的,但是如果它是一个大按钮,则很重要。

  • 好消息是,还有另一种方法可以在selectableItemBackgroundBorderless中使用ripple标签模拟drawable/ripple.xml:
    <?xml version="1.0" encoding="utf-8"?>
    <ripple xmlns:android="http://schemas.android.com/apk/res/android"
        android:color="?android:colorPrimary">
        <item android:id="@android:id/mask">
    
            <shape android:shape="oval">
                <solid android:color="?android:colorPrimary"/>
            </shape>
    
        </item>
    </ripple>
    

    从我观察到的结果来看,它具有与selectableItemBackgroundBorderless相同的波纹效果(除了它没有溢出波纹),因此您没有理由坚持使用默认的selectableItemBackgroundBorderless
    使用此ripple.xml,执行以下操作:
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:id="@+id/nav_drawer"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:background="@android:color/holo_green_light"
        android:orientation="vertical">
    
        <ImageView
            android:id="@+id/imageView4"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_alignParentTop="true"
            android:scaleType="fitXY"
            android:src="@drawable/device_bg" />
    
        <ImageView
            android:layout_width="48dp"
            android:layout_height="48dp"
            android:layout_alignParentEnd="true"
            android:layout_alignParentTop="true"
            android:src="@drawable/sidebar_refresh" />
    
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentEnd="true"
            android:layout_alignParentTop="true">
            <FrameLayout
                android:layout_weight="1"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:background="@android:color/transparent">
                <ImageView
                    android:id="@+id/imageView3"
                    android:layout_width="48dp"
                    android:layout_height="48dp"
                    android:clickable="true"
                    android:src="@drawable/ripple" />
            </FrameLayout>
        </LinearLayout>
    
    </RelativeLayout>
    

    唯一的变化是LinearLayout部分。没有更多的硬编码填充,也没有Alpha图像。唯一的小问题是点击角点仍会触发涟漪效应。我找到了这个thread,但是我还没有尝试过。

    即使图像不透明,上述两种方式也可以工作。

    关于android - ImageView正在覆盖叠加按钮的波纹效果,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/27809742/

    10-09 12:50