原文地址: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();
}
}
- 如果 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);