布局中其他视图遮挡了材料设计波纹效果

19
我在一个ImageButton上添加了涟漪效果,但是由于一个作为RelativeLayout背景的ImageView遮盖住了它,所以涟漪效果被隐藏了。
这是布局文件:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                xmlns:tools="http://schemas.android.com/tools"
                android:layout_width="match_parent"
                android:layout_height="172dp"
                android:orientation="vertical"
                android:theme="@style/ThemeOverlay.AppCompat.Dark">

    <ImageView
        android:id="@+id/drawerBackgroundImageView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scaleType="centerCrop"
        android:src="@drawable/drawer_background"/>

    [...]

    <ImageButton
        android:id="@+id/drawerLogoutButton"
        android:layout_width="32dp"
        android:layout_height="32dp"
        android:layout_alignBottom="@id/drawerEmailTextView"
        android:layout_alignParentEnd="true"
        android:layout_alignParentRight="true"
        android:layout_marginEnd="@dimen/activity_horizontal_margin"
        android:layout_marginRight="@dimen/activity_horizontal_margin"
        style="@style/FlatButtonStyle"
        android:scaleType="centerInside"
        android:src="@drawable/ic_logout_white_24dp"/>

</RelativeLayout>

(这里有一堆其他的视图,但它们与此无关)

我正在将一个 ImageView 用作 RelativeLayout 的背景,因为我需要为图像设置特定的 scaleType,所以我不能使用基本的 android:background 属性。

涟漪效果被隐藏了,因为它没有蒙版图层(我希望它能延伸到按钮的边界之外),因此使用 ImageButton 的父视图来显示。如果我移除 ImageView,则效果完全可见。

有没有办法使涟漪效果在有问题的 ImageView 上方显示?


你能够检查一下我在下面的答案是否正确吗?https://dev59.com/q1wZ5IYBdhLWcg3wBcSz#37757154 谢谢 - Santiago Vanegas
嗨,Santiago,抱歉我没有检查你的答案,因为我从那时起一直在处理另一个项目,有点忘记了这个问题。我会尝试一下并尽快回复你。 - Jukurrpa
6个回答

69

我曾经遇到过完全相同的问题,通过这个线程解决了它:https://code.google.com/p/android/issues/detail?id=155880

问题预览:

解决前:

Before

解决后:

After

说明:

"无边框按钮会将内容绘制在最靠近的背景上。你的按钮可能在自己和ImageView之间没有背景,所以它会在ImageView下方绘制。"

解决方案:

"在包含按钮的某个布局(ImageView下方)上使用透明背景(android:background="@android:color/transparent"),这将规定涟漪效果的最大边界."

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
                ...>

    <!-- Your background ImageView -->
    <ImageView
        android:id="@+id/drawerBackgroundImageView"
        android:src="@drawable/drawer_background"
        ... />

        <!-- ... -->

    <!-- HERE, you need a container for the button with the transparent
         background. Let's say you'll use a FrameLayout -->
    <FrameLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@android:color/transparent">

        <!-- Maybe more items --> 

        <!-- Button with borderless ripple effect -->
        <ImageButton
            android:id="@+id/drawerLogoutButton"
            android:background="?selectableItemBackgroundBorderless"
            ... />

    </FrameLayout>

</FrameLayout>

希望能有所帮助。


这个可以完成任务,谢谢!顺便说一下,我会用FrameLayout替换根RelativeLayout,因为我们只是按原样显示子视图。 - Jukurrpa
@Jukurrpa,没错,我们应该避免使用RelativeLayout,因为它更加低效。使用FrameLayout会更好。 - Santiago Vanegas
这在我的情况下导致了一个被剪裁的涟漪效果(容器右上角的溢出按钮)。如果其他人遇到同样的问题,使用填充而不是边距可以解决被剪裁的涟漪效果。 - masterwok
有很多关于同一个问题的问答,但是这个问题终于被解决了。 - musooff
将边框布局(FrameLayout)的大小设置为比图像视图(ImageView)大(大约两倍),以避免裁剪无边界的涟漪效果。 - Sattar Hummatli
除了父元素的背景之外,我还需要在我的ImageButton上设置一些填充。 - Robyer

10

我知道这是一篇旧文章,但今天我还是遇到了很多问题,所以我想分享一下我最终找出的方法,也许其他人也会从中受益。此前需要强调的一点是,请始终阅读文档

1)经过

我想在选项卡项目上使用无限涟漪效果,并使其扩散到整个AppBarLayout区域。我将@android:color/transparent 应用于TabLayout作为第一个包装父级,并给AppBarLayout设置了背景颜色,然而涟漪仍然被剪切在TabLayout高度的边界处。

2)故事的寓意(阅读文档)

因此,我去了Android知识堆: 文档,并发现了这个:

?android:attr / selectableItemBackgroundBorderless 用于扩展超出视图的涟漪。 它将在视图的非空背景的最近父节点上绘制并限定。

3)行动方针

使用布局检查器,我意识到@android:color/transparent 虽然是透明的(傻瓜!),但它实际上将View的bg 属性的值分配为0,但零不是空,因此涟漪被限制在最近的父级。

4)结论

有了这个,我去设置了TabLayout的android:background 属性为@ null 而不是透明,现在我有一个花哨的小涟漪扩散到AppBarLayout区域。

5)结语:**ANDROID和 SO FTW!

感谢在这篇文章中用言辞阐明了这个问题的每个人。 干杯!


9
我遇到了相同的问题。目前我找到的唯一解决方案并不完美,因为涟漪被视图遮盖了(它不是无边框)。
解决方案(变通方法): 将您的ImageButton包围在其他视图中,并在布局中将涟漪设置为前景而不是背景,像这样:
<ImageView ... /> 

<FrameLayout
    ...
    android:clickable="true"
    android:focusable="true"
    android:foreground="?attr/selectableItemBackgroundBorderless" >

    <ImageButton />
</FrameLayout>

如果有人能解释为什么图片后面会出现涟漪,我会非常高兴。此外,如果您查看Google Photos应用程序,在图像详细信息中,它们在图像视图上放置了透明图标和涟漪效果。我想复制这个功能,但我无法使涟漪处于前景。有人知道如何在所有内容上方放置透明的图像按钮,但仍然具有涟漪效果吗?请注意保留HTML标签。

编辑最终解决方案 您可以在此处找到完全相同的问题 link。 其中提供了很好的解释。解决方案相同,但还解决了添加矩形蒙版的问题。

android:clipChildren="false"
android:clipToPadding="false"

将以下代码添加到您的布局中。现在,您的涟漪应该是无边框的(对我有效)。 布局XML可能类似于:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
...
android:clipChildren="false"
android:clipToPadding="false">

    <ImageView ... /> 

    <FrameLayout
        ...

        android:clickable="true"
        android:foreground="?attr/selectableItemBackgroundBorderless">
       <ImageView ... />
    </FrameLayout>

</FrameLayout>

谢谢!它解决了我的问题。只需将这两行添加到父级,就可以工作了! - Toufic Batache

1
在将ImageButton包装在FrameLayout中后,我发现触摸区域变成了矩形。通过在FrameLayout上应用带有椭圆形状的背景,我成功地实现了圆形触摸区域。

1
我遇到了同样的问题。使用上述描述的解决方案解决了问题。通过将前景设置为?attr/actionBarItemBackground,背景设置为@null,成功避免了包装FrameLayout。
 <ImageButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center|end"
            android:background="@null"
            android:contentDescription="@string/app_name"
            android:foreground="?attr/actionBarItemBackground"
            android:padding="@dimen/small_margin"
            android:src="@drawable/ic_clear_text_icon" />

0

在所有父布局中使用 android:clipChildern="false" android:clipToPadding="false"

这是我的解决方案。

` <LinearLayout 
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:clipChildren="false"
    android:clipToPadding="false" >

    <LinearLayout
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:clipChildren="false"
      android:clipToPadding="false">

      <ImageButton
        android:layout_width="48dp"
        android:layout_height="48dp"
        android:foreground="?attr/selectableItemBackgroundBorderless"
        android:src="@drawable/ic_magnifier" />

         ....
        `

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