Измените цвет RippleEffect обратно на его первоначальное значение в стиле - PullRequest
0 голосов
/ 29 января 2019

У меня есть проект Android, в котором я меняю цвет эффекта Ripple, который происходит в одном из моих представлений, используя следующий подход

Хотя он работает, мне нужносбросить этот цвет обратно к его значению по умолчанию, в зависимости от моего стиля.Ниже я покажу свой файл стилей, и мне бы хотелось иметь способ вернуть 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 голосов
/ 30 января 2019

Вместо попытки отменить изменения, внесенные в исходный фон 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()?

Все Drawable сгенерированные из одного извлекаемого ресурса имеют общее состояние.Это помогает экономить ресурсы (например, память) и, таким образом, повышает производительность приложения для Android.

Обычно, если вы примените, например, ColorFilter к Drawable, сгенерированному из определенного ресурса, который вы будете рисовать, вы будетеобратите внимание на эффект повсюду в вашем приложении, где используется этот конкретный нарисованный ресурс.

Вызов mutate() на Drawable сообщает среде выполнения, что этот Drawable должен иметь свое собственное состояние.Если вы примените какие-либо изменения впоследствии, остальные Drawables останутся без изменений.

См. Также документацию на mutate()

...