App黑白化探索

原文地址:https://mp.weixin.qq.com/s/EioJ8ogsCxQEFm44mKFiOQ
https://mp.weixin.qq.com/s/8fTWLYaPhi0to47EUmFd7A

整体实现思路:替换根Fragment 设置绘制饱和度

if (mFactory2 != null) {
    view = mFactory2.onCreateView(parent, name, context, attrs);
} else if (mFactory != null) {
    view = mFactory.onCreateView(name, context, attrs);
} else {
    view = null;
}

if (view == null && mPrivateFactory != null) {
    view = mPrivateFactory.onCreateView(parent, name, context, attrs);
}

if (view == null) {
    final Object lastContext = mConstructorArgs[0];
    mConstructorArgs[0] = context;
    try {
        if (-1 == name.indexOf('.')) {
            view = onCreateView(parent, name, attrs);
        } else {
            view = createView(name, null, attrs);
        }
    } finally {
        mConstructorArgs[0] = lastContext;
    }
} 

我们的最终生成的view 优先级依次是mFactory2,mFactory,mPrivateFactory来生成View,自己重写onCreateView生成自定义的根fragment
代码

override fun onCreateView(name: String?, context: Context?, attrs: AttributeSet?): View? {
      if("FrameLayout".equals(name)){
      var count = attrs!!.getAttributeCount();
      for ( i in 0..count-1) {
          var attributeName = attrs.getAttributeName(i);
          var attributeValue = attrs.getAttributeValue(i);
          if (attributeName.equals("id")) {
              var id = Integer.parseInt(attributeValue.substring(1));
              var idVal = getResources().getResourceName(id);
              if ("android:id/content".equals(idVal)) {
                  var grayFrameLayout =  GrayFrameLayout(context, attrs);
                  return grayFrameLayout;
              }
          }
      }
  }
      return super.onCreateView(name, context, attrs)
  }
public class GrayFrameLayout extends FrameLayout {
    private Paint mPaint = new Paint();

    public GrayFrameLayout(Context context, AttributeSet attrs) {
        super(context, attrs);

        ColorMatrix cm = new ColorMatrix();
        cm.setSaturation(0);
        mPaint.setColorFilter(new ColorMatrixColorFilter(cm));
    }

    @Override
    protected void dispatchDraw(Canvas canvas) {
        canvas.saveLayer(null, mPaint, Canvas.ALL_SAVE_FLAG);
        super.dispatchDraw(canvas);
        canvas.restore();
    }


    @Override
    public void draw(Canvas canvas) {
        canvas.saveLayer(null, mPaint, Canvas.ALL_SAVE_FLAG);
        super.draw(canvas);
        canvas.restore();
    }

}
  1. 如果 Activity的 Window 设置了 background,咋办呢?
if ("android:id/content".equals(idVal)) {
    GrayFrameLayout grayFrameLayout = new GrayFrameLayout(context, attrs);
    grayFrameLayout.setBackgroundDrawable(getWindow().getDecorView().getBackground());
    return grayFrameLayout;
}

如果你是theme 中设置的 windowBackground,那么需要从 theme 里面提取 drawable,参考代码如下:

TypedValue a = new TypedValue();
getTheme().resolveAttribute(android.R.attr.windowBackground, a, true);
if (a.type >= TypedValue.TYPE_FIRST_COLOR_INT && a.type <= TypedValue.TYPE_LAST_COLOR_INT) {
    // windowBackground is a color
    int color = a.data;
} else {
    // windowBackground is not a color, probably a drawable
    Drawable c = getResources().getDrawable(a.resourceId);
}

第二种方法 我们可以直接给任何一个 View 去设置灰度化。

Paint paint = new Paint();
ColorMatrix cm = new ColorMatrix();
cm.setSaturation(0);
mPaint.setColorFilter(new ColorMatrixColorFilter(cm));
getWindow().getDecorView().setLayerType(View.LAYER_TYPE_HARDWARE, paint);

你可能感兴趣的:(App黑白化探索)