ImageView覆盖了按钮的涟漪效果

6
我有一个ImageView作为RelativeLayout的背景,并在其上方放置了一个刷新按钮。按钮的涟漪效果被下面的ImageView覆盖了。我尝试过使用FrameLayout等方法,但没有什么帮助。
<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>

请发布您的涟漪XML代码和触发涟漪效果的代码。 - Prem
@prem 我没有使用ripple.xml,而是使用Android内置的涟漪效果,通过android:background="?android:attr/selectableItemBackgroundBorderless"来实现。它在我添加下面的ImageView之前都能正常工作。 - user572285
1个回答

0

使用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"将具有涟漪的图像设置为透明,以便覆盖实心图像。

这段代码的问题在于:

  1. 您必须硬编码填充。如果没有填充或填充太小,则涟漪效果将绑定到矩形而不是圆形。使用公式48(高度/宽度)/7来计算填充。如果除以7不起作用,请减少除数,例如6。
  2. 因为它有填充,所以无法触摸填充以触发涟漪效果。如果这是一个小按钮,因为不明显,所以可以接受,但如果是一个大按钮,就很重要了。

好消息是有一种替代方法可以使用drawable/ripple.xml中的ripple标签模拟selectableItemBackgroundBorderless

<?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部分。不再有硬编码填充和透明图像。唯一的小问题是点击角落仍会触发涟漪效果。我找到了这个thread,但我还没有尝试过。
上述两种方法即使图像不透明也有效。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接