2.实现逻辑java
首先咱们看下布局的android
咱们第一种方法就是用布局替换的思惟去实现canvas
首先咱们能看到id/content的ContentFrameLayout咱们的目的就是替换他bash
咱们去自定义一个 FrameLayout代码以下:ide
class GrayFrameLayout( context: Context, attrs: AttributeSet?
) : FrameLayout(context, attrs) {
private val paint: Paint
/**
* 绘制控件自己
* @param canvas
*/
override fun draw(canvas: Canvas) {
canvas.saveLayer(null, paint, Canvas.ALL_SAVE_FLAG)
super.draw(canvas)
canvas.restore()
}
/**
* 绘制子控件
* @param canvas
*/
override fun dispatchDraw(canvas: Canvas) {
canvas.saveLayer(null, paint, Canvas.ALL_SAVE_FLAG)
super.dispatchDraw(canvas)
canvas.restore()
}
init {
paint = Paint()
val colorMatrixColorFilter =ColorMatrixColorFilter(MatrixArrays.gray_matrix)
paint.colorFilter = colorMatrixColorFilter
}
}复制代码
MatrixArrays.gray_matrix是用矩阵实现的灰白效果
/**
* 灰白
*/
val gray_matrix = floatArrayOf(
0.33f, 0.59f, 0.11f, 0f, 0f,
0.33f, 0.59f, 0.11f, 0f, 0f,
0.33f, 0.59f, 0.11f, 0f, 0f,
0f, 0f, 0f, 1f, 0f)这样咱们就能够实现布局包括布局内的控件都有灰白的效果,下一步就是咱们的替换步骤了
复制代码
一、若是你的BaseActivity继承的是Activity那下面的就你的替换流程
咱们利用布局加载器在BaseActivity的onCreate方法中:
LayoutInflaterCompat.setFactory2(layoutInflater,GrayFactory())①GrayFactory代码以下:
class GrayFactory : Factory2 {
//Android5.0以前继承activity的灰白化处理
override fun onCreateView(
parent: View?,
name: String,
context: Context,
attrs: AttributeSet ): View? {
if (TextUtils.equals("FrameLayout", name)) {
val attributeCount = attrs.attributeCount
for (i in 0 until attributeCount) {
val attributeName = attrs.getAttributeName(i)
val attributeValue = attrs.getAttributeValue(i)
if (TextUtils.equals("id", attributeName)) {
val id = attributeValue.substring(1).toInt()
val resourceName = context.resources.getResourceName(id)
if (TextUtils.equals("android:id/content", resourceName)) {
return GrayFrameLayout(context, attrs) //建立灰白化framelayout
}
}
}
}
return onCreateView(name, context, attrs)
}
override fun onCreateView(
name: String,
context: Context,
attrs: AttributeSet ): View? {
var view: View? = null
try {
val aClass = context.classLoader.loadClass(name)
val constructor: Constructor<out View> =
aClass.getConstructor(
Context::class.java, AttributeSet::class.java
) as Constructor<out View>
view = constructor.newInstance(context, attrs)
}
catch (e: ClassNotFoundException) {
e.printStackTrace()
}
catch (e: NoSuchMethodException) {
e.printStackTrace() }
catch (e: IllegalAccessException) {
e.printStackTrace() }
catch (e: InstantiationException) {
e.printStackTrace() }
catch (e: InvocationTargetException) {
e.printStackTrace() }
return view
}
}
复制代码
二、若是你的BaseActivity继承的是AppCompatActivity那下面的就你的替换流程:就是把上面的简化了
在BaseActivity的onCreateView方法中:
if (TextUtils.equals("FrameLayout", name)) {
val attributeCount = attrs.attributeCount
for (i in 0 until attributeCount) {
val attributeName = attrs.getAttributeName(i)
val attributeValue = attrs.getAttributeValue(i)
if (TextUtils.equals("id", attributeName)) {
val id = attributeValue.substring(1).toInt()
val resourceName = context.resources.getResourceName(id)
if (TextUtils.equals("android:id/content", resourceName)) {
return GrayFrameLayout(context, attrs) //建立灰白化framelayout
}
}
}
}
return super.onCreateView(name, context, attrs)//必定是调super的,这里容易出现死循环
复制代码
咱们第二种方法就是用布局替换的思惟去实现布局
首先咱们看到上面的最根的根布局是DecorView咱们的目的就是替换他ui
①咱们在BaseActivity的onCreat方法中添加spa
var decorView = window.decorViewvar
var paint = Paint()
val colorMatrixColorFilter = ColorMatrixColorFilter(MatrixArrays.gray_matrix)
paint.colorFilter = colorMatrixColorFilter
decorView.setLayerType(View.LAYER_TYPE_HARDWARE,paint)//记得在清单文件中打开硬件加速
还有一种实现//不用矩阵计算用系统自带的
Paint paint = new Paint();
ColorMatrix cm = new ColorMatrix();
cm.setSaturation(0);//0就是灰白效果
paint.setColorFilter(new ColorMatrixColorFilter(cm));
activity.getWindow().getDecorView().setLayerType(View.LAYER_TYPE_HARDWARE, paint);复制代码
在使用的过程当中可能会发现dialog效果没有实现灰白化:3d
处理方法:第一种方法的第二个实现和第二种一块儿使用就能够了rest
结尾总结:
本文主要用到的是布局替换,项目中每一个界面都有相同的系统根布局DecorView、ContentFrameLayout因此从这里入手这个能够看下源码更清楚