原理:
自定义view时,对paint设置setColorFilter,将饱和度设置为0,canvas通过saveLayer把paint替换即可,全局设置时,可以采用以下方式。
创建GrayFrameLayout
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();
}
}
在baseActivity中替换掉默认的fragmentLayout
@Override
public View onCreateView(String name, Context context, AttributeSet attrs) {
if("FrameLayout".equals(name)){
int count = attrs.getAttributeCount();
for (int i = 0; i < count; i++) {
String attributeName = attrs.getAttributeName(i);
String attributeValue = attrs.getAttributeValue(i);
if (attributeName.equals("id")) {
int id = Integer.parseInt(attributeValue.substring(1));
String idVal = getResources().getResourceName(id);
if ("android:id/content".equals(idVal)) {
GrayFrameLayout grayFrameLayout = new GrayFrameLayout(context, attrs);
return grayFrameLayout;
}
}
}
}
return super.onCreateView(name, context, attrs);
}
具体思路如下:
Paint paint = new Paint();
ColorMatrix cm = new ColorMatrix();
cm.setSaturation(0);
mPaint.setColorFilter(new ColorMatrixColorFilter(cm));
getWindow().getDecorView().setLayerType(View.LAYER_TYPE_HARDWARE, paint);
在baseActivity的super.onCreate前执行即可
具体思路如下:
Window window = activity.getWindow();
if (window == null) {
return;
}
View view = window.getDecorView();
Paint paint = new Paint();
// 我们把蓝色减弱为原来的0.7
ColorMatrix cm = new ColorMatrix(new float[]{
-1, 0, 0, 0, 255,
0, -1, 0, 0, 255,
0, 0, -1, 0, 255,
0, 0, 0, 1, 0
});
paint.setColorFilter(new ColorMatrixColorFilter(cm));
view.setLayerType(View.LAYER_TYPE_HARDWARE, paint);
但是有一个很明显的问题,因为我们是对Activity的DecorView做了颜色转换,ImageView是它的Child,所以图片也被反色了,可以单独给ImageView设置一个反向的矩阵让图片恢复原来的颜色:
// 遍历查找ImageView,对其设置逆矩阵
int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
final View childView = parent.getChildAt(i);
if (childView instanceof ViewGroup) {
takeOffColor((ViewGroup) childView);
} else if (childView instanceof ImageView) {
Paint paint = new Paint();
ColorMatrix cm = new ColorMatrix(new float[]{
-1, 0, 0, 0, 255,
0, -1, 0, 0, 255,
0, 0, -1, 0, 255,
0, 0, 0, 1, 0
});
paint.setColorFilter(new ColorMatrixColorFilter(cm));
childView.setLayerType(View.LAYER_TYPE_HARDWARE, paint);
}
}
感谢:以上来源与鸿洋公众号系列文章,进行一个小笔记汇总