碰到这么一个问题,我有一个activity,布局如下:
<RelativeLayout xmlns:Android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@drawable/page_bg" >
<com.ebensz.widget.SVGEditor android:id="@+id/svg_editor"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>
其中page_bg是一张jpg图片,在调试svg_editor的绘制速度的时候,发现有三处主要的绘制,分别是ColorDrawable、BitmapDrawable和svg_editor,后面两个自然是RelativeLayout和我自定义的控件,ColorDrawable就很奇怪了,我没有一处使用,只能是窗口饰件(decoView)了,这点很快就得到了确认。但我的RelativeLayout使用JPG图片做背景,而JPG图片是不可能有透明色的,再画RelativeLayout的父视图不是画蛇添足么?
我首先把怀疑的目光集中到了RelativeLayout上,是不是因为我没有指明它不透明,系统把它当透明的了呢,于是查看了VIEW类的isOpaque和computeOpaqueFlags函数,它是根据背景是否透明设定视图的透明属性的,问题很快被澄清了,RelativeLayout确实是不透明的。那问题出在哪呢?
于是我又把View的invalidate和绘制流程梳理了一遍。invalidate的流程很简单,先是设置无效标记,然后调用parent view的invalidateChild,它的主要代码如下:
// Check whether the child that requests the invalidate is fully opaque
final boolean isOpaque = child.isOpaque() && !drawAnimation &&
child.getAnimation() != null;
// Mark the child as dirty, using the appropriate flag
// Make sure we do not set both flags at the same time
final int opaqueFlag = isOpaque ? DIRTY_OPAQUE : DIRTY;
do {
View view = null;
if (parent instanceof View) {
view = (View) parent;
}
if (drawAnimation) {
if (view != null) {
view.mPrivateFlags |= DRAW_ANIMATION;
} else if (parent instanceof ViewRoot) {
((ViewRoot) parent).mIsAnimating = true;
}
}
// If the parent is dirty opaque or not dirty, mark it dirty with the opaque
// flag coming from the child that initiated the invalidate
if (view != null && (view.mPrivateFlags & DIRTY_MASK) != DIRTY) {
view.mPrivateFlags = (view.mPrivateFlags & ~DIRTY_MASK) | opaqueFlag;
}
parent = parent.invalidateChildInParent(location, dirty);
} while (parent != null);