解决Android 过度绘制.md

Android 过度绘制问题

过度绘制(Overdraw)

过度绘制会引起界面卡顿

如何检测过度绘制

Android手机上面的开发者选项提供了工具来检测过度绘制,可以按如下步骤来打开:

开发者选项->调试GPU过度绘制->显示过度绘制区域

多次绘制的显示效果

绘制优化方案

  • 去除不必要的背景

1.在theme中设置

  <style name="AppTheme" parent="主题">
  	  <item name="android:windowBackground">@null</item>
 </style>

2.在Activity的onCreate()方法中添加:

    getWindow().setBackgroundDrawable(null);
  • 使用Inspector 在AS中查看 Layout 层级

       这里使用Android推荐的Layout Inspector来查看layout的层次结构。
    
      在Android Studio中点击Tools > Android > Layout Inspector。然后在出现的 Choose Process 对话框中,选择想要检查的应用进程即可。
    

使用 merge 标签在使用时 将相同布局嵌套的时候【去重】

<merge
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">

<ImageView
    ...
    />

<TextView
    ...
    />
</merge>

多使用扁平化布局

可以使用更扁平化的布局,如RelativeLayout、GridLayout、ConstraintLayout等布局来提高性能。布局默认的最大深度为10。

比如:在TextView上设置带透明度alpha值的黑色文本可以实现灰色

的效果。但是,直接通过设置灰色的话能够获得更好的性能。

尽量少使用透明度

使用了透明度的View 会进行两次绘制,1 要先知道下一层的View是什么,2 在结合上一层的 View 进行混合处理

减少onDrwa 绘制层数 使用canvas clipRect()

一般      
   @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        for (int i = 0; i < imgs.length; i++) {
            canvas.drawBitmap(imgs[i], i * 100, 0, mPaint);
        }
    }

使用 clipRect()

     protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    for (int i = 0; i < imgs.length; i++) {
        canvas.save();
        if (i < imgs.length - 1) {
            //前面的n-1张图,只裁剪一部分
            canvas.clipRect(i * 100, 0, (i + 1) * 100, imgs[i].getHeight());
        } else if (i == imgs.length - 1) {
            //最后一张,完整的
            canvas.clipRect(i * 100, 0, i * 100 + imgs[i].getWidth(), imgs[i].getHeight());
        }
        canvas.drawBitmap(imgs[i], i * 100, 0, mPaint);
        canvas.restore();
    }

使用ViewStub 标签延迟加载(在需要时才显示该UI)

<ViewStub
android:id="@+id/stub_import"
android:inflatedId="@+id/panel_import"
android:layout="@layout/progress_overlay"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom" />

这里的panel_import就是具体要加载的布局ID。

通过以下代码即可在需要时加载布局:

findViewById(R.id.stub_import)).setVisibility(View.VISIBLE);
或者

View importPanel = ((ViewStub) findViewById(R.id.stub_import)).inflate();

onDraw()的使用

  • onDraw()中不要创建新的局部变量以及不要做耗时操作

  • onDraw()中不要创建新的局部变量,因为onDraw()方法可能会被频繁调用,大量的临时对象会导致内存抖动,会造成频繁的GC,从而使UI线程被频繁阻塞,导致画面卡顿。

使用ConstraintLayout

ConstraintLayout相比RelativeLayout,其性能更好,也更容易使用,结合Android Studio的布局编辑器可以实现拖拽控件来编写布局等等。

发布了26 篇原创文章 · 获赞 6 · 访问量 7808

猜你喜欢

转载自blog.csdn.net/weixin_37558974/article/details/82791581