Android LayerDrawable包含两个状态的ImageView ListDrawable未在一个图层上绘制已按下状态
我正在尝试使用LayerDrawable作为源来扩展ImageView。每一层由一个StateListDrawable组成,其中一个是ShapeDrawable,另一个是从资源加载的Drawable 在用户按下时,ShapeDrawable从青色逐渐变为白色,可绘制图标从其原始颜色(白色)变为可绘制,并应用颜色过滤器,使其变为相同的青色 图标始终保持不变的原始颜色,但可变形的渐变为白色。我已经从图标中删除了白色状态,并显示了青色,因此我假设这是StateListDrawable的某个地方出现的问题。我还删除了进入和退出淡出持续时间,但没有成功 代码如下Android LayerDrawable包含两个状态的ImageView ListDrawable未在一个图层上绘制已按下状态,android,imageview,android-drawable,Android,Imageview,Android Drawable,我正在尝试使用LayerDrawable作为源来扩展ImageView。每一层由一个StateListDrawable组成,其中一个是ShapeDrawable,另一个是从资源加载的Drawable 在用户按下时,ShapeDrawable从青色逐渐变为白色,可绘制图标从其原始颜色(白色)变为可绘制,并应用颜色过滤器,使其变为相同的青色 图标始终保持不变的原始颜色,但可变形的渐变为白色。我已经从图标中删除了白色状态,并显示了青色,因此我假设这是StateListDrawable的某个地方出现的问
public class DrawerItemIcon extends ImageView {
private static final String ITEM_ENABLED_COLOR = "#1ABC9C";
private int mIconResource;
private StateListDrawable mCircleDrawable;
private StateListDrawable mIconDrawable;
public DrawerItemIcon(Context context, int iconResource) {
super(context);
mIconResource = iconResource;
init();
}
private void init() {
setDuplicateParentStateEnabled(true);
setImageDrawable(getLayers());
}
private LayerDrawable getLayers() {
Drawable[] layers = new Drawable[2];
layers[1] = getCircleDrawable();
layers[0] = getIconDrawable();
return new LayerDrawable(layers);
}
private Drawable getCircleDrawable() {
mCircleDrawable = new StateListDrawable();
mCircleDrawable.addState(new int[]{android.R.attr.state_pressed},getPressedShapeCircleDrawable());
mCircleDrawable.addState(new int[]{android.R.attr.state_enabled}, getEnabledShapeCircleDrawable());
mCircleDrawable.setEnterFadeDuration(500);
mCircleDrawable.setExitFadeDuration(500);
return mCircleDrawable;
}
private ShapeDrawable getPressedShapeCircleDrawable() {
ShapeDrawable bgDrawable = new ShapeDrawable();
bgDrawable.setShape(new OvalShape());
bgDrawable.getPaint().setStyle(Paint.Style.STROKE);
bgDrawable.getPaint().setStrokeWidth(4);
bgDrawable.getPaint().setColor(Color.WHITE);
return bgDrawable;
}
private ShapeDrawable getEnabledShapeCircleDrawable() {
ShapeDrawable bgDrawable = new ShapeDrawable();
bgDrawable.setShape(new OvalShape());
bgDrawable.getPaint().setStyle(Paint.Style.STROKE);
bgDrawable.getPaint().setStrokeWidth(4);
bgDrawable.getPaint().setColor(Color.parseColor(ITEM_ENABLED_COLOR));
return bgDrawable;
}
public Drawable getIconDrawable() {
mIconDrawable = new StateListDrawable();
mIconDrawable.addState(new int[]{android.R.attr.state_pressed}, getPressedIconDrawable());
mIconDrawable.addState(new int[]{android.R.attr.state_enabled}, getEnabledIconDrawable());
mIconDrawable.setEnterFadeDuration(500);
mIconDrawable.setExitFadeDuration(500);
return mIconDrawable;
}
private Drawable getPressedIconDrawable() {
return getResources().getDrawable(mIconResource);
}
private Drawable getEnabledIconDrawable() {
Drawable selectedDrawable = getResources().getDrawable(mIconResource);
selectedDrawable.setColorFilter(
new PorterDuffColorFilter(Color.parseColor(ITEM_ENABLED_COLOR), PorterDuff.Mode.MULTIPLY));
return selectedDrawable;
}
}
这是因为该可拉伸材料的连续状态。解决这个问题的方法就是在
getEnabledIconDrawable()
方法中添加一个.mutate()
调用
... getResources().getDrawable(mIconResource).mutate();
有关恒定状态的更多信息,请参见:
其他地方已回答,但将放在此处供将来参考。您确实应该从可绘制的XML中执行此操作。这将使代码更易于阅读,这可能会使错误更加明显。@alanv我明天将尝试使用XML。尽管此视图仅构成复合视图的一部分。是否有任何原因,从性能角度或其他方面来看,XML比Java更好?@alanv这利用了
ColorFilter
,这在XML中是不可能实现的。瞧,亚历克斯没有想到这一点。我的最低要求是API 14,我认为Tint不在支持库中。@luke william duncan是的,Tint/tintMode从API 1开始就存在了。但是,API 21中添加了不同状态所需的setImageTintList(ColorStateList)
,您说得对。谢谢您的回复,我明天会检查代码,看看它是否有效。在检查之前,我将此标记为正确答案(我正在处理其他部分,无法应用隐藏)但它仍然不起作用。看看这篇文章,添加以下内容更有意义:selectedDrawable.mutate().setColorFilter(新的PorterDuffColorFilter(Color.parseColor(ITEM_ENABLED_Color),PorterDuff.Mode.MULTIPLY));因为恒定状态肯定是白色的,不是吗?是的,对不起,这就是我的意思。应该多给点背景。在您发布的代码段中,该方法是代码段的getEnabledCondrawable()
方法,该代码段使用被调用为正确的可绘制对象的Drawable#mutate()