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);
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • EnglishVersion ->_->:https://github.com/jiang111/awesome-...
    聂顺阅读 1,257评论 0 4
  • 1: 获取控件宽高 控件View有getHeight()和getwidth()方法可以获取宽高,但是如果直接在on...
    自由人是工程师阅读 1,861评论 0 0
  • Fragment要点 1、Fragment作为Activity界面的一部分组成出现 2、可以在一个Activity...
    玉圣阅读 1,259评论 0 16
  • 1,一个南方的孩子独自到西北上大学是个怎么样的体验? 我是一个重庆农村长大的孩子。在我的家乡,景物都是对你友好的,...
    丹魁阅读 177评论 0 0
  • 想必刷微博的朋友这两天都被王源抽烟事件频频刷屏吧!试问一下短短4小时二十几个热搜在感叹流量巨大的同时又觉得异常可悲...
    简雪意阅读 102评论 0 0