【问题标题】:Change RippleEffect Color back to it's Styled original value将 RippleEffect 颜色更改回其 Styled 原始值
【发布时间】:2019-01-29 19:07:20
【问题描述】:

我有一个 Android 项目,我正在使用 following approach 更改在我的一个视图中发生的波纹效果的颜色

虽然它可以工作,但我确实需要根据我的风格将此颜色重置为默认值。 下面我将展示我的 Style 文件,我希望有一种方法可以将 RippleDrawable 设置回它的默认颜色。

<style name="AppTheme" parent="Theme.MaterialComponents.Light.DarkActionBar">
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
    <item name="editTextColor">@android:color/white</item>
    <item name="font">@font/roboto_regular</item>

    <item name="colorControlNormal">@android:color/white</item>
    <item name="android:scrollbarThumbVertical">@drawable/nice_scrollbar</item>

    <item name="android:textColor">@color/darkGrey</item>
    <item name="android:editTextColor">@android:color/black</item>

    <item name="android:textColorHighlight">@color/colorPrimary</item>
    <item name="android:colorBackground">@color/darkerWhite</item>
    <item name="android:windowBackground">@color/darkerWhite</item>

    <item name="windowNoTitle">true</item>
    <item name="android:windowNoTitle">true</item>
</style>

可以看出,我正在使用 MaterialComponents。

您将在下面找到我用来更改颜色以及在给定 x/y 处对视图施加波纹效果的当前方法:

private void forceRippleAnimation(View view, int x, int y) {
    Drawable background = view.getBackground();
    if (Build.VERSION.SDK_INT >= 21 && background instanceof RippleDrawable) {
        RippleDrawable rippleDrawable = (RippleDrawable) background;
        rippleDrawable.setHotspot(x, y);
        rippleDrawable.setColor(new ColorStateList(
            new int[][]{
                new int[]{}
            },
            new int[]{
                getContext().getResources().getColor(R.color.rippleColor)
            }
        ));
        rippleDrawable.setState(new int[]{android.R.attr.state_pressed, android.R.attr.state_enabled});

        Handler handler = new Handler();
        handler.postDelayed(new Runnable(){
            @Override public void run(){
                rippleDrawable.setState(view.getDrawableState());
            }
        }, 650);
    }
}

【问题讨论】:

  • 请展示您如何更改颜色 - 链接问题至少有两个有用的答案,我不知道哪一个在您眼中看起来最有希望。
  • 你好@0X0nosugar,我刚刚编辑了我的问题,描述了我如何强制产生连锁反应。一种可能的方法是从 RippleDrawable 中找到初始 ColorStateList,但是没有 getColorStateList,也没有找到默认值的方法......

标签: java android material-components-android rippledrawable


【解决方案1】:

而不是试图扭转对原始背景RippleDrawable所做的更改, 您可以保留它并将更改应用到副本:

Activity 有两个Drawable 字段:

private RippleDrawable customRippleDrawable;
private RippleDrawable backgroundFromXml;

创建给定背景的副本并将其设置为新背景:

Drawable background = view.getBackground();
if (Build.VERSION.SDK_INT >= 21 && background instanceof RippleDrawable) {
    backgroundFromXml = (RippleDrawable) background;
    customRippleDrawable = (RippleDrawable) background.getConstantState().newDrawable().mutate();
    customRippleDrawable.setHotspot(x, y);
    customRippleDrawable.setColor(new ColorStateList(
            new int[][]{
                new int[]{}
            },
            new int[]{
                MainActivity.this.getResources().getColor(R.color.rippleColor)
            }
    ));
    customRippleDrawable.setState(new int[]{android.R.attr.state_pressed, android.R.attr.state_enabled});
    view.setBackground(customRippleDrawable);
}

由于 backgroundFromXml 是一个字段,您可以稍后访问它以将背景重置为其原始值:

view.setBackground(backgroundFromXml);

mutate() 是做什么的?

从一个可绘制资源生成的所有Drawables 共享一个公共状态。这有助于节省资源(例如内存),从而提高 Android 应用程序的性能。

通常,如果您将例如ColorFilter 应用于从某个可绘制资源生成的Drawable,您会注意到应用程序中使用该特定可绘制资源的任何地方的效果。

Drawable 上调用mutate() 告诉运行时这个Drawable 应该有自己的状态。如果您之后应用任何更改,其他 Drawable 将保持不变。

另请参阅mutate() 上的documentation

【讨论】:

  • 我找到了另一种无法解决涟漪问题的解决方案。但我可能会选择你的答案作为我所问的正确答案。您能否进一步解释 .mutate() 的工作原理?似乎 getResources().getColor(R.color.rippleColor) 可能是获得这种颜色的一种方式,但我无法使其工作。我总是在尝试这个时遇到崩溃。
  • 对不起,还有一个问题,您考虑在代码中的哪个位置复制背景?我看到您从视图中获取它,对其进行变异并对其应用新的颜色状态。之后,您再次为视图设置相同的背景。为什么这会重置颜色?你在哪里复制这个背景(我所看到的只是引用被拾取和更改,然后被重置为视图)?
  • @MarceloPetrucelli - 在我的示例中有两个 Drawables。一个是基于另一个创建的。我使用其中一个 (customRippleDrawable) 显示更改后的波纹,另一个 (backgroundFromXml) 显示正常的波纹。
猜你喜欢
  • 2015-07-21
  • 2013-06-25
  • 1970-01-01
  • 2013-04-12
  • 2021-05-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-13
相关资源
最近更新 更多