Ixx*_*Ixx 21
除非其他人有更好的答案,否则我目前的方法是分开对待每个项目.
PorterDuffColorFilter greyFilter = new PorterDuffColorFilter(Color.GRAY, PorterDuff.Mode.MULTIPLY);
myLayout.getBackground().setColorFilter(greyFilter);
myImageView.setColorFilter(greyFilter);
myTextView.setTextColor(0xff777777);
Run Code Online (Sandbox Code Playgroud)
对于更多或嵌套的子代,可能使用instanceof的循环是合适的,但我不需要它.
编辑:此滤镜实际上不是灰色,这里有一个更好的滤镜:Drawable =>灰度 可以以相同的方式使用.
Sam*_* Lu 13
通过定义自定义视图组,可以很容易地执行此操作,如下所示:
public class MyViewContainer extends XXXLayout {
//XXLayout could be LinearLayout, RelativeLayout or others
private Paint m_paint;
//define constructors here and call _Init() at the end of constructor function
private void
_Init()
{
ColorMatrix cm = new ColorMatrix();
cm.setSaturation(0);
m_paint = new Paint();
m_paint.setColorFilter(new ColorMatrixColorFilter(cm));
}
@Override protected void
dispatchDraw(Canvas canvas)
{
canvas.saveLayer(null, m_paint, Canvas.ALL_SAVE_FLAG);
super.dispatchDraw(canvas);
canvas.restore();
}
}
Run Code Online (Sandbox Code Playgroud)
MyViewContainer的所有子视图都将以灰色显示.:-)
Lea*_* ES 11
Sam Lu的回答是一个良好的开端,但我遇到了性能问题并决定切换到硬件层.使用硬件层,您可以这样做:
private final Paint grayscalePaint = new Paint();
ColorMatrix cm = new ColorMatrix();
cm.setSaturation(0);
grayscalePaint.setColorFilter(new ColorMatrixColorFilter(cm));
public void setGrayedOut(boolean grayedOut) {
if (grayedOut) {
setLayerType(View.LAYER_TYPE_HARDWARE, grayscalePaint);
} else {
setLayerType(View.LAYER_TYPE_NONE, null);
}
}
Run Code Online (Sandbox Code Playgroud)
小心不要自己做图层,dispatchDraw()因为这会使应用程序崩溃.
它完全取决于您用来"灰显"项目的方法.如果您通过调用setEnabled(false)父ViewGroup进程来执行此操作,则默认情况下状态标志(如已禁用)不会逐渐显示到子视图.但是,有两种简单的方法可以自定义:
一种选择是将属性添加 android:duplicateParentState="true"到XML中的每个子视图.这将告诉孩子们从父母那里得到他们的州旗.这将镜像所有标志,包括按下,检查等...不仅仅启用.
另一种选择是创建你的自定义子类ViewGroup并重写setEnabled()以调用所有子视图,即
@Override
public void setEnabled(boolean enabled) {
super.setEnabled(enabled);
for(int i=0; i < getChildCount(); i++) {
getChildAt(i).setEnabled(enabled);
}
}
Run Code Online (Sandbox Code Playgroud)