最近在做关于DrawerLayout的需求,发现当非Drawer的Child多于一个时,把Drawer拉出来产生的遮罩颜色不一,如下图
image.png
查看了DrawerLayout的源码,感觉出现阴影颜色不一致问题的原因是源码设计有点缺陷?
DrawerLayout常见的用法是设置两个View,一个作为抽屉,一个作为主View,这种情况下抽屉出来时主View上的阴影没有问题。但是,当主View不止一个时,例如下图,两个View同级写在DrawerLayout中,这时候抽屉出来时阴影就会出现问题。
image.png查看DrawerLayout的drawChild方法,发现阴影的绘制是下面的逻辑,每次调用drawChild时,只要当前在绘制的是主View,就绘制一次全屏的阴影:
@Override
protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
final boolean drawingContent = isContentView(child);//contentView就是上面说的主view
...
if (mScrimOpacity > 0 && drawingContent) {
canvas.drawRect(clipLeft, 0, clipRight, getHeight(), mScrimPaint);//绘制全屏的阴影
}
...
}
DrawerLayout中判断一个Child是否主View的方法就是看它有没有设置gravity属性,没设置就是主view
boolean isContentView(View child) {
return ((LayoutParams) child.getLayoutParams()).gravity == Gravity.NO_GRAVITY;
}
按照源码的方式去绘制,当有两个主View时,绘制一帧的图层是这样的:
绘制主View1 —> 绘制蒙层 —> 绘制主View2 —> 绘制蒙层
当最先绘制的主View1没有被主View2挡住时,可以看到它的上面是有两层阴影叠加的效果,因此,会呈现出一深一浅的效果。
找到了原因,解决方法就有了,想办法保证只有一个主View!
或者让Google大佬改改,无论有几个主View,每一帧都只绘制一次蒙层。
网友评论