Android非按钮视图上的涟漪效果和高度(Elevation)

9

我正在尝试给一个LinearLayout添加触摸反馈,使其与API 21级别下的常规按钮反馈类似,就像这个示例中的那样,但迄今为止未能成功。

我已经定义了一个标准的涟漪drawable,如下所示:

<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="?android:colorControlHighlight">

<item android:id="@android:id/mask">
    <shape android:shape="rectangle">
        <solid android:color="?android:colorAccent" />
    </shape>
</item>

我使用了谷歌提供的StateListAnimator,参见这里

<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="true" android:state_pressed="true">
    <objectAnimator
        android:duration="@android:integer/config_shortAnimTime"
        android:propertyName="translationZ"
        android:valueTo="@dimen/touch_raise"
        android:valueType="floatType" />
</item>
<item>
    <objectAnimator
        android:duration="@android:integer/config_shortAnimTime"
        android:propertyName="translationZ"
        android:valueTo="0dp"
        android:valueType="floatType" />
</item>

在定义了动画和涟漪图案后,我将它们添加到LinearLayout中,如下所示:

<LinearLayout
    android:id="@+id/linearLayout"        
    android:clickable="true"
    android:focusable="true"
    android:orientation="horizontal"
    android:background="@drawable/ripple"
    android:stateListAnimator="@anim/touch_elevation">

这个想法是将该LinearLayout用作按钮,因为相对于按钮样式的绘制,我可以更简单地插入各种类型的文本并处理其中ImageView的定位。

单独添加涟漪效果或动画效果是可以的,只要视图的背景没有透明度,就像这个问题一样。

我不确定这是否与上述问题有关,但是既然标准按钮可以同时使用涟漪和高程动画反馈,我认为在其他视图上实现此效果也是可能的。

非常感谢您对此问题的任何见解。


如果您希望在用户点击您的LinearLayout时应用涟漪效果,您需要使用适当的StateListDrawable,而不是直接引用您的<ripple>。 - CommonsWare
你现有的背景说“立即显示涟漪”。这似乎是一个奇怪的选择。Button 的背景是 StateListDrawable,用于在正常、按下、禁用、聚焦等状态下使用不同的图像。你需要做同样的事情。 - CommonsWare
我想我明白你的意思,但奇怪的是,正如我在问题中提到的那样,如果我只将涟漪指定为背景,则它按预期工作。 - Rakatan
两者同时发生会产生什么影响? - GPack
此外,该遮罩只是用作alpha通道。您可以使用<color android:color="@color/white" />而不是形状可绘制物。 - alanv
显示剩余2条评论
2个回答

3
使用ForegroundLinearLayout。它允许将涟漪或任何其他可绘制对象放在视图的前景中。同样的方式,您可以创建ForegroundRelativeLayout等(只需使此类从RelativeLayout扩展即可)。
以下是使用stateListAnimator和涟漪可绘制对象的示例:
<your.package.ForegroundLinearLayout
    android:layout_width="300dp"
    android:layout_height="300dp"
    android:layout_centerInParent="true"
    android:gravity="center"
    android:foreground="@drawable/bg_ripple"
    android:background="#fff"
    android:clickable="true"
    android:stateListAnimator="@animator/animator_elevation">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello world!"/>

</your.package.ForegroundLinearLayout>

结果:

输入图像描述

编辑:ForegroundLinearLayout 存在于支持设计库中。因此,您可以直接使用 android.support.design.internal.ForegroundLinearLayout


1
在涟漪的项目元素中没有 android:id="@android:id/mask" 属性时,这两个效果一起工作(也许这个属性会增加一些透明度)。

两种效果确实可以在不使用遮罩的情况下同时起作用。显然是透明度问题。很抱歉,我无法使用您的解决方案,因为我希望对任何项目都能应用这两种效果。例如,在CardView上使用此解决方案(其中涟漪必须是前景),将导致视图的整个内容变为不可见状态。 - Rakatan
我从未想过 android:id/mask 可能是导致我的 <ripple> drawable 没有显示高度的原因!!! - reavcn

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