如何在LinearLayout中以编程方式设置水波纹效果?

46

我想将背景android.R.attr.selectableItemBackground设置为LinearLayout。在使用XML时没有问题(它可以正常工作)。

<LinearLayout
    android:id="@+id/llMiner"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="?android:attr/selectableItemBackground"
    android:clickable="true" >

...但我必须在Java代码中完成这个操作,所以我尝试了以下代码

llMiner.setClickable(true);
llMiner.setBackgroundResource(android.R.attr.selectableItemBackground);

...但它不起作用,事实上在这第二行上我得到了一个NotFoundException

所以在我尝试了这个变量之后认为资源是一个颜色。

llMiner.setClickable(true);
llMiner.setBackgroundColor(android.R.attr.selectableItemBackground);

这个代码不会抛出异常,但是...无法正常工作(按下时没有背景色的变化,尽管它应该会转换到按下状态)...有什么建议吗?


你是在你的活动的onClick方法中改变颜色吗..??? - Usama Sarwar
那么我认为你必须重写onClick方法来完成你的功能。 - Usama Sarwar
我正在尝试做同样的事情,但迄今为止没有成功。如果您找到了解决方案,请告诉我,或者如果有人知道这是否可以实现,请给予反馈。谢谢! - Sandra
对于任何寻找支持库对应项的人,它是android.support.design.R.attr.selectableItemBackground - Sufian
我的先前评论似乎现在不起作用了(或者可能从来没有起作用)。现在有效的是R.attr.selectableItemBackground - Sufian
@Splact 如果您不介意,请选择我的答案 :) - Wooseong Kim
2个回答

113
您可以使用这种方式。
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
    // If we're running on Honeycomb or newer, then we can use the Theme's
    // selectableItemBackground to ensure that the View has a pressed state
    TypedValue outValue = new TypedValue();
    this.getTheme().resolveAttribute(android.R.attr.selectableItemBackground, outValue, true);
    textView.setBackgroundResource(outValue.resourceId);
}

1
对我不起作用,白色,它们无法保持来自主题的colorAccent在早期的棒棒糖设备上。 - Anthone
1
如果您想保留主题颜色,请使用R.attr.selectableItemBackground而不是android.R.attr.selectableItemBackground。 - Quentin G.
1
使用R.attr.selectableItemBackground将使用AppCompat的属性(如果您包含了它),并在默认情况下为早期版本的Lollipop而不是涟漪效果提供淡入/淡出效果。请注意,R是您的packagename.R - Sufian
点赞给予有效的答案,真的帮了很多,谢谢。 - ucMedia

1

使用这个有用的扩展

fun Context.makeCircleRippleDrawable(
    @ColorInt rippleColor: Int = ContextCompat.getColor(this, R.color.black_alpha_25),
    @ColorInt backgroundColor: Int = ContextCompat.getColor(this, android.R.color.transparent),
    @ColorInt disabledColor: Int = backgroundColor,
    elevation: Float = 0F
): Drawable {
    return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {

        val content: GradientDrawable?
        val mask: GradientDrawable?

        if (backgroundColor == Color.TRANSPARENT) {
            content = null
            mask = GradientDrawable()
            mask.setColor(rippleColor)
            mask.shape = GradientDrawable.OVAL
        } else {
            content = GradientDrawable().also {
                it.shape = GradientDrawable.OVAL
                it.color = ColorStateList(
                    arrayOf(
                        intArrayOf(android.R.attr.state_activated),
                        intArrayOf(android.R.attr.state_enabled),
                        intArrayOf(-android.R.attr.state_enabled)
                    ),
                    intArrayOf(
                        backgroundColor,
                        backgroundColor,
                        disabledColor
                    )
                )
            }
            mask = null
        }

        RippleDrawable(
            ColorStateList(
                arrayOf(
                    intArrayOf(android.R.attr.state_pressed),
                    intArrayOf(android.R.attr.state_focused),
                    intArrayOf(android.R.attr.state_activated)
                ),
                intArrayOf(
                    rippleColor,
                    rippleColor,
                    rippleColor
                )
            ),
            content,
            mask
        )
    } else {

        val shapePressed = GradientDrawable()
        shapePressed.shape = GradientDrawable.OVAL
        shapePressed.setColor(rippleColor)

        val shapeDefault = GradientDrawable().also {
            it.shape = GradientDrawable.OVAL
            it.color = ColorStateList(
                arrayOf(
                    intArrayOf(android.R.attr.state_activated),
                    intArrayOf(android.R.attr.state_enabled),
                    intArrayOf(-android.R.attr.state_enabled)
                ),
                intArrayOf(
                    backgroundColor,
                    backgroundColor,
                    disabledColor
                )
            )
        }

        val stateListDrawable = StateListDrawable()
        stateListDrawable.addState(
            intArrayOf(
                android.R.attr.state_pressed,
                android.R.attr.state_enabled
            ), shapePressed
        )
        stateListDrawable.addState(intArrayOf(), shapeDefault)
        stateListDrawable
    }
}

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