视图绘制回顾
测量:确定大小
布局:确定位置
绘制:绘制视图
性能瓶颈
每个阶段耗时
自顶而下的遍历
触发多次
布局层级及复杂度
准则
减少View树层级
宽而浅,避免窄而深
不嵌套使用RelativeLayout
不在嵌套LinearLayout中使用weight
merge标签:减少一个层级,只能用于根View
ConstraintLayout
实现几乎完全扁平化布局
构建复杂布局性能更高
具有RelativeLayout和LinearLayout特性
过度绘制
一个像素最好只被绘制一次
调试GPU过度绘制
蓝色可接受
避免过度绘制方法
去掉多余背景色,减少复杂shape使用
避免层级叠加
自定义View使用clipRect屏蔽被遮盖View绘制
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// Don't draw anything until all the Asynctasks are done and all the DroidCards are ready.
if (mDroids.length > 0 && mDroidCards.size() == mDroids.length) {
// Loop over all the droids, except the last one.
int i;
for (i = 0; i < mDroidCards.size() - 1; i++) {
mCardLeft = i * mCardSpacing;
canvas.save();
// 指定绘制区域
canvas.clipRect(mCardLeft,0,mCardLeft+mCardSpacing,mDroidCards.get(i).getHeight());
// Draw the card. Only the parts of the card that lie within the bounds defined by
// the clipRect() get drawn.
drawDroidCard(canvas, mDroidCards.get(i), mCardLeft, 0);
canvas.restore();
}
// Draw the final card. This one doesn't get clipped.
drawDroidCard(canvas, mDroidCards.get(mDroidCards.size() - 1),
mCardLeft + mCardSpacing, 0);
}
// Invalidate the whole view. Doing this calls onDraw() if the view is visible.
invalidate();
}
其他技巧
Viewstub:高效占位符、延迟初始化
onDraw中避免:创建大对象、耗时操作
TextView优化