将 RippleEffect Color 更改回其 Styled 原始值
Change RippleEffect Color back to it's Styled original value
我有一个 Android 项目,我正在使用
更改我的一个视图中出现的波纹效果的颜色
虽然它可以工作,但我确实需要根据我的风格将此颜色重置回默认值。
下面我将展示我的样式文件,我希望有一种方法可以将 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);
}
}
而不是尝试撤销对原始背景所做的更改 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
,您会注意到应用程序中使用此特定可绘制资源的任何地方的效果。
在 Drawable
上调用 mutate()
告诉运行时这个 Drawable
应该有自己的状态。如果您之后应用任何更改,其他 Drawable 将保持不变。
另见 mutate()
上的 documentation
我有一个 Android 项目,我正在使用
虽然它可以工作,但我确实需要根据我的风格将此颜色重置回默认值。 下面我将展示我的样式文件,我希望有一种方法可以将 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);
}
}
而不是尝试撤销对原始背景所做的更改 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
,您会注意到应用程序中使用此特定可绘制资源的任何地方的效果。
在 Drawable
上调用 mutate()
告诉运行时这个 Drawable
应该有自己的状态。如果您之后应用任何更改,其他 Drawable 将保持不变。
另见 mutate()