tal*_*kol 87 android drawable android-widget
我正在尝试创建一个通用框架函数,使得任何Drawable在按下/聚焦/选择/等时都会突出显示.
我的函数接受一个Drawable并返回一个StateListDrawable,其中默认状态是Drawable本身,而状态for android.R.attr.state_pressed是相同的drawable,只需使用过滤器setColorFilter.
我的问题是我无法克隆drawable并使用过滤器创建一个单独的实例.这是我想要实现的目标:
StateListDrawable makeHighlightable(Drawable drawable)
{
StateListDrawable res = new StateListDrawable();
Drawable clone = drawable.clone(); // how do I do this??
clone.setColorFilter(0xFFFF0000, PorterDuff.Mode.MULTIPLY);
res.addState(new int[] {android.R.attr.state_pressed}, clone);
res.addState(new int[] { }, drawable);
return res;
}
Run Code Online (Sandbox Code Playgroud)
如果我没有克隆,那么过滤器显然适用于这两种状态.我试过玩,mutate()但它没有帮助..
有任何想法吗?
更新:
接受的答案确实克隆了一个可绘制的.这对我没有帮助,因为我的一般功能在一个不同的问题上失败了.看起来当你向StateList添加一个drawable时,它会丢失所有的过滤器.
Fla*_*vio 154
请尝试以下方法:
Drawable clone = drawable.getConstantState().newDrawable();
Run Code Online (Sandbox Code Playgroud)
Pet*_*tai 99
如果将过滤器/ etc应用于创建的drawable, getConstantState().newDrawable()那么该drawable的所有实例也将被更改,因为drawable使用了constantState作为缓存!
因此,如果使用滤镜和a为圆圈着色newDrawable(),则会更改所有圆圈的颜色.
如果你想在不影响其他实例的情况下使这个可绘制的可更新,那么你必须改变现有的常量状态.
// To make a drawable use a separate constant state
drawable.mutate()
Run Code Online (Sandbox Code Playgroud)
有一个很好的解释,请看:
http://www.curious-creature.org/2009/05/02/drawable-mutations/
http://developer.android.com/reference/android/graphics/drawable/Drawable.html#mutate()
Yan*_* Bi 14
这对我有用.
Drawable clone = drawable.getConstantState().newDrawable().mutate();
Run Code Online (Sandbox Code Playgroud)
Mal*_*asz 10
这是我的解决方案,基于这个SO问题.
想法是ImageView当用户触摸它时获取滤色器,并且当用户停止触摸时滤色器被移除.内存中只有1个可绘制/位图,因此无需浪费它.它的工作原理应该如此.
class PressedEffectStateListDrawable extends StateListDrawable {
private int selectionColor;
public PressedEffectStateListDrawable(Drawable drawable, int selectionColor) {
super();
this.selectionColor = selectionColor;
addState(new int[] { android.R.attr.state_pressed }, drawable);
addState(new int[] {}, drawable);
}
@Override
protected boolean onStateChange(int[] states) {
boolean isStatePressedInArray = false;
for (int state : states) {
if (state == android.R.attr.state_pressed) {
isStatePressedInArray = true;
}
}
if (isStatePressedInArray) {
super.setColorFilter(selectionColor, PorterDuff.Mode.MULTIPLY);
} else {
super.clearColorFilter();
}
return super.onStateChange(states);
}
@Override
public boolean isStateful() {
return true;
}
}
Run Code Online (Sandbox Code Playgroud)
用法:
Drawable drawable = new FastBitmapDrawable(bm);
imageView.setImageDrawable(new PressedEffectStateListDrawable(drawable, 0xFF33b5e5));
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
25802 次 |
| 最近记录: |