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属性,也可以实现子控件之间的分隔符。

更多相关文章

  1. Android中TextView中的文字颜色设置setTextColor的用法
  2. 图文浅析之Android显示原理
  3. android 学习七 一些xml layout组件的说明(自己总结不断更新)
  4. Android(安卓)OpenGL ES2.0从放弃到入门(五)——绘制3D模型(obj+mtl
  5. 我的android阅读软件“微读”-做最简单的手机阅读软件
  6. android 软键盘Enter键图标的设置 android:imeOptions
  7. Android自定义GridView之仿支付宝首页可拖动、可删除的九宫格
  8. android 设置Alpha值实现图片渐变效果
  9. 如何快速步入Android(安卓)开发之旅

随机推荐

  1. Android:TextView与图片上下对齐使用drawa
  2. Android技能树 — Drawable小结
  3. Android中EditText的inputType属性
  4. Android(安卓)C语言开发系列教程目录
  5. Android(安卓)SDK Android(安卓)NDK 官方
  6. Android高手进阶教程
  7. android学习笔记(二)——textAppearance的
  8. android 版本
  9. Android(安卓): reletive layout
  10. 五大ui布局