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因此從這裏入手這個能夠看下源碼更清楚