Android(安卓)界面过度绘制优化tips
Android App性能优化中,界面过度绘制的优化是一项很重要的优化点,前一段时间对项目整体进行了界面过度绘制优化,把优化过程的一些tips记录一下。
(过度绘制的概念及检查方法,有很多人写过了,不再复述,不知道的自行摆渡)
1、Activity本身是有一层背景色的,但是实际开发中,往往又需要设置不同的背景,所以往往会在布局文件的根布局中添加background属性,这样就导致了Activity的背景其实就有了两层颜色绘制,这样很容易导致界面的过度绘制。
为了解决这个问题,对项目的Activity基类BaseActivtiy设置了统一的主题,在具体界面中再设置需要的background颜色。这样项目的所有界面,整体减少了一层颜色绘制。
这种方式有一个缺点,在绘制具体界面的时候,如果有区域完全透明,没有设置至少一层颜色,就会导致UI异常出现(机型不同,表现形式不同,花屏、黑色甚至出现过OOM),需要在具体开发中具体解决。对于项目UI全部使用统一背景色的项目,可以直接设置windowBackground为指定色值,在具体布局文件中不设置background的方式,也可以实现相同的效果,但是这种方式灵活性较差。
2、使用频率较高,也是容易出现过度绘制的控件ListView、RecyclerView、GridView等AdapterView
AdapterView容易出现过度绘制的问题,主要是因为在开发过程中,容易出现对View设置background之后,又对item设置background导致。解决方案也比较简单,就是设置一层背景颜色,主要有两种方式:对Adapter设置background 或者 对Item设置background。
如果对AdapterView设置的background,那item的背景就可以使用类似的样式保证了颜色和点击效果。
<?xml version="1.0" encoding="utf-8"?>对应的,如果不设置Adapter的背景颜色,则可以对Item设置相应的background:
<?xml version="1.0" encoding="utf-8"?>第一种方式适合于Item没有分类 或者 不同有分类但是UI显示一致 的情况,比较简单通用;如果不同Item类型的UI不同,可以使用第二种方式,但这种方式有一个需要特殊处理的情况:item数量少不足以撑满整个View,会有空白区域出现,需要在开发过程中特殊处理。
3、在UI绘制过程中,分割线的不恰当绘制也容易出现界面过度绘制。
如果是ListView,可以使用divider解决。
如果是RecyclerView,可以使用addItemDecoration()方法,传入自定义的ItemDivider实现,还可以自定义出各种效果。
public class RecyleViewItemDivider extends RecyclerView.ItemDecoration { Paint paint = new Paint(); private int mItemColor; public QDRecyleViewItemDivider(int itemColor) { mItemColor = itemColor == -1 ? Color.parseColor("#dcdcdc") : itemColor; } @Override public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) { super.onDraw(c, parent, state); } @Override public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) { super.onDrawOver(c, parent, state); paint.setColor(mItemColor); for (int i = 0, size = parent.getChildCount(); i < size; i++) { View child = parent.getChildAt(i); c.drawLine(child.getLeft(), child.getBottom(), child.getRight(), child.getBottom(), paint); } } @Override public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { super.getItemOffsets(outRect, view, parent, state); }}
如果是LinearLayout,可以考虑divider和showDividers属性,也可以实现子控件之间的分隔符。 其他情况下,使用shape绘制分隔符时,也需要处理绘制方式,避免过度绘制。
4、shape在绘制过程中,可以进行描边绘制,但如果只是需要对指定边进行描边,处理不当就容易出现过度绘制。
-
-
-
以上这种方式,虽然也实现了整体#f6f6f6,底部描1像素边的效果,但是整体绘制了两层颜色,就容易导致界面过度绘制。可行方法如下,实现了上下描边效果:
<?xml version="1.0" encoding="utf-8"?>
5、shape在使用corners过程中,使用radius指定四个圆角时,要使用第一种方式,第二种方式虽然可以实现同样的效果,但是会多绘制一层,容易导致过度绘制。
如果是LinearLayout,可以考虑divider和showDividers属性,也可以实现子控件之间的分隔符。
更多相关文章
- Android中TextView中的文字颜色设置setTextColor的用法
- 图文浅析之Android显示原理
- android 学习七 一些xml layout组件的说明(自己总结不断更新)
- Android(安卓)OpenGL ES2.0从放弃到入门(五)——绘制3D模型(obj+mtl
- 我的android阅读软件“微读”-做最简单的手机阅读软件
- android 软键盘Enter键图标的设置 android:imeOptions
- Android自定义GridView之仿支付宝首页可拖动、可删除的九宫格
- android 设置Alpha值实现图片渐变效果
- 如何快速步入Android(安卓)开发之旅