如何将颜色过滤器应用于包含所有子项的视图

Ixx*_*Ixx 20 android view colors filter

如何均匀地灰化包含许多不同项目的视图 - ImageViews,TextViews,背景图像.我是否必须将每件事分别变灰?或者有没有办法将相同的滤色器应用于所有?

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 =>灰度 可以以相同的方式使用.

  • `myLayout.getBackground().setColorFilter(greyFilter);`我正在搜索它.好东西. (2认同)

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()因为这会使应用程序崩溃.


Dev*_*red 7

它完全取决于您用来"灰显"项目的方法.如果您通过调用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)