将RippleEffect颜色更改回其样式原始值

时间:2019-01-29 19:07:20

标签: java android components material rippledrawable

我有一个Android项目,其中我正在使用following approach

更改在我的一个视图中发生的波纹效果的颜色

尽管可以正常工作,但我确实需要根据我的风格将此颜色重置为默认值。 在下面,我将显示我的样式文件,我希望有一种方法可以将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);
    }
}

1 个答案:

答案 0 :(得分:1)

与其尝试撤消对原始背景<div class="container"> <div class="col-4 picture">col-4</div> <div class="header">modified. If col-4 is being overriden, I don't see the purpose of .col-4 class</div> </div> <div class="container reset-header"> <div class="col-4 picture">col-4</div> <div class="col-4">should be col-4. Remove the .header class and use a new class for whatever styles you need here and add the new class to the .header above</div> </div> 所做的更改, 您可以保留它并将更改应用到副本:

RippleDrawable有两个Activity字段:

Drawable

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

private RippleDrawable customRippleDrawable;
private RippleDrawable backgroundFromXml;

由于 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);
}

view.setBackground(backgroundFromXml); 的作用是什么?

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

通常,如果将Drawable应用于从某个可绘制资源生成的ColorFilter,则您会注意到应用程序中使用此特定可绘制资源的所有位置的效果。

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

另请参见Drawable上的documentation