Android 带彩色滤光片的Ninepatch可拉伸
我正在创建一些日历视图,我想做的是为clickabe的LineairLayout创建一个背景 因此,我创建了一个带有两个图像的StateListDrawable:Android 带彩色滤光片的Ninepatch可拉伸,android,nine-patch,android-drawable,porter-duff,statelistdrawable,Android,Nine Patch,Android Drawable,Porter Duff,Statelistdrawable,我正在创建一些日历视图,我想做的是为clickabe的LineairLayout创建一个背景 因此,我创建了一个带有两个图像的StateListDrawable: 以图像为背景 按下项目时的图像 到目前为止,这段代码可以使用: NinePatchDrawable background = (NinePatchDrawable) context.getResources().getDrawable(R.drawable.calendar_item); Drawable backgr
NinePatchDrawable background = (NinePatchDrawable) context.getResources().getDrawable(R.drawable.calendar_item);
Drawable backgroundFocus = context.getResources().getDrawable(R.drawable.calendar_focus);
int stateFocused = android.R.attr.state_focused;
int statePressed = android.R.attr.state_pressed;
StateListDrawable sld = new StateListDrawable();
sld.addState(new int[]{ stateFocused, statePressed}, backgroundFocus);
sld.addState(new int[]{-stateFocused, statePressed}, backgroundFocus);
sld.addState(new int[]{-stateFocused}, background);
return sld;
但是我想做些额外的事情。我希望用户能够传递一种他想要用来显示背景的颜色。因此,背景变量必须是可变的,但它必须基于可绘制的九个补丁
所以我想我可以这样做:
background.setColorFilter(Color.RED, PorterDuff.Mode.DST_IN);
其中Color.RED必须由用户选择的颜色替换
但这似乎不起作用。九面片制作完美,但没有应用颜色过滤器
我还尝试了其他PoterDuff.Mode:
- SRC
- SRC_顶部
- DST_IN
Dirk我不认为可以为StateListDrawable中的每个Drawable分配颜色过滤器。原因:当StateListDrawable更改状态时,将删除/替换ColorFilter。要查看此操作,请更改语句的顺序,以便:
background.setColorFilter(Color.RED, PorterDuff.Mode.DST_IN);
在创建StateListDrawable之后出现。您将看到应用了ColorFilter。但是,一旦状态改变(单击,然后释放),颜色过滤器就不再存在了
StateListDrawable允许您设置颜色过滤器:StateListDrawable#setColorFilter(颜色过滤器)
。这是如何使用提供的(或空)ColorFilter的:
StateListDrawable#onStateChange(int[]):
@Override
protected boolean onStateChange(int[] stateSet) {
....
if (selectDrawable(idx)) { // DrawableContainer#selectDrawable(int)
return true;
}
....
}
public boolean selectDrawable(int idx) {
....
if (idx >= 0 && idx < mDrawableContainerState.mNumChildren) {
Drawable d = mDrawableContainerState.mDrawables[idx];
mCurrDrawable = d;
mCurIndex = idx;
if (d != null) {
....
// So, at this stage, any ColorFilter you might have supplied
// to `d` will be replaced by the ColorFilter you
// supplied to the StateListDrawable, or `null`
// if you didn't supply any.
d.setColorFilter(mColorFilter);
....
}
} else {
....
}
}
可提取容器#选择可提取(int):
@Override
protected boolean onStateChange(int[] stateSet) {
....
if (selectDrawable(idx)) { // DrawableContainer#selectDrawable(int)
return true;
}
....
}
public boolean selectDrawable(int idx) {
....
if (idx >= 0 && idx < mDrawableContainerState.mNumChildren) {
Drawable d = mDrawableContainerState.mDrawables[idx];
mCurrDrawable = d;
mCurIndex = idx;
if (d != null) {
....
// So, at this stage, any ColorFilter you might have supplied
// to `d` will be replaced by the ColorFilter you
// supplied to the StateListDrawable, or `null`
// if you didn't supply any.
d.setColorFilter(mColorFilter);
....
}
} else {
....
}
}
另一种可能性:使用框架布局代替线性布局。LinearLayouts没有前景属性
// StateListDrawable
frameLayout.setBackground(sld);
// For tint
frameLayout.setForeground(sldOverlay);
它确实涉及透支,使其成为次优解决方案/解决方案。也许您可以看看扩展StateListDrawable和DrawableContainer。由于您没有为StateListDrawable使用ColorFilter,因此可以删除
d.setColorFilter(mColorFilter)代码>从覆盖的drawable容器中#选择drawable(int)
AFAIK状态列表删除附加到drawable的所有颜色过滤器。所以问题可能不是9patch部分,而是statelist。请您测试删除状态列表,将颜色过滤器应用于绘图并给出反馈好吗?嗯。。。我将不得不考虑这些。虽然我不是这个问题的最初提问者,但它确实巧妙地涵盖了我在办公时间聊天中看到的一个场景,我觉得这个场景很有趣。要想在运行时选择一种颜色应用于9个补丁,几乎需要一个ColorFilter
AFAIK,尽管我对Android的这一特定领域还不是很在行。StateListDrawable
是因为在许多情况下,这九个补丁将应用于应该是可点击元素的东西。谢谢你的意见@公共软件。。。这九个补丁将应用于应该是可点击元素的东西
——有点奇怪的是,StateListDrawable
是这样实现的<对于作为附加参数传递给StateListDrawable#addState()
的单个Drawable,code>ColorFilters
将提供更多的控制/选择。或者,在使用StateListDrawable
本身上设置的ColorFilter设置/覆盖单个Drawable的ColorFilter之前进行空检查也会起作用。嗯,可以有,应该有,扩展
。。。