美文网首页
视图优化作业

视图优化作业

作者: duanmo | 来源:发表于2016-04-17 10:45 被阅读31次

    项目地址github

    首先打开overdraw view,然后进入我们的MainActivity,如下:


    Snip20160417_1.png

    红色是过度绘制严重的区域,我们打开布局文件看看


    Snip20160417_2.png

    很容易就看到了一块区域的背景重复绘制了,我们把里层的删掉


    Snip20160417_3.png

    变绿了。。好了很多,我们再来优化一下视图层级,采用RelativeLayout布局试试,优化之前先打开GPU Profiler检测一下当前的视图渲染时间,如图


    Snip20160417_4.png

    修改后的XML文件:


    Snip20160417_5.png

    满怀信心的运行:


    Snip20160417_6.png

    卧槽,你TM还突破天际了?看来老师说的根布局尽量不用用RelativeLayout是真的T T

    那么就不改根布局了,把ImageView那块用RelativeLayout吧


    Snip20160417_7.png

    看着舒服了很多。。虽然并没有什么卵用,GPU Profiler依然要上天

    MainActivity就到此为止吧,桑心。接下来看看OverDrawViewActivity


    Snip20160417_8.png

    非常恐怖!马上点开XML看一下,结果XML里什么都没有!只有一个自定义View,我们打开这个OverDrawView看一下,重点在onDraw方法


    Snip20160417_9.png

    可以看出,这里的Rect一层一层叠加,导致了过度绘制,我们先分析一下


    Snip20160417_10.png

    这张图应该能说明问题了吧,好了接下来就是修改(简单的数学计算):

            // 该区域最终只漏出了height/4的高度,所以修改一下高度,后面几个同理
            mPaint.setColor(Color.GRAY);
    //        canvas.drawRect(0, 0, width, height, mPaint);
            canvas.drawRect(0, 0, width, height / 4, mPaint);
    
            mPaint.setColor(Color.CYAN);
    //        canvas.drawRect(0, height/4, width, height, mPaint);
            canvas.drawRect(0, height/4, width, height / 3, mPaint);
    
            mPaint.setColor(Color.DKGRAY);
    //        canvas.drawRect(0, height/3, width, height, mPaint);
            canvas.drawRect(0, height/3, width, height / 2 , mPaint);
    
            mPaint.setColor(Color.LTGRAY);
            canvas.drawRect(0, height/2, width, height, mPaint);
    

    最终效果:


    Snip20160417_11.png

    接下来再看看BusyOnDrawActivity,点击按钮进入这个Activity时非常卡,用了差不多2s才进去,


    Snip20160417_14.png

    快速上下滑动是这样的:


    Snip20160417_16.png

    Activity代码里什么都没有,然后我们看看XML布局


    Snip20160417_12.png

    布局很简单,就是一个ScrollView里面套着一堆园,数了一下总共10行,每行3个,每个圆宽高都是100dp。这个圆就是一个自定义View 叫BusyOnDrawView,我们进去看看:

        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
    
            for (int i = 0; i < 1000; i++) {
                System.out.println("canvas = [" + canvas + "]" + i);
            }
    
            Paint paint = new Paint();
            paint.setColor(Color.RED);
            paint.setStyle(Paint.Style.STROKE);
            paint.setStrokeWidth(4);
            int radius = Math.min(getWidth(), getHeight()) / 2;
            canvas.drawCircle(getWidth()/2, getHeight()/2, radius, paint);
        }
    

    这里打印一堆log不知道是干嘛的,注掉,然后运行,发现瞬间不卡了。然后再把Paint提出来。然后再把计算radius提取成成员变量,获取尺寸都移动到onSizeChanged方法中。最终代码如下

    public class BusyOnDrawView extends View {
    
        private Paint mPaint;
        private int mRadius;
        private int mWidth;
        private int mHeight;
    
        public BusyOnDrawView(Context context) {
            super(context);
            init();
        }
    
        public BusyOnDrawView(Context context, AttributeSet attrs) {
            super(context, attrs);
            init();
        }
    
        public BusyOnDrawView(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            init();
        }
    
        @TargetApi(Build.VERSION_CODES.LOLLIPOP)
        public BusyOnDrawView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
            super(context, attrs, defStyleAttr, defStyleRes);
            init();
        }
    
        private void init() {
            mPaint = new Paint();
            mPaint.setColor(Color.RED);
            mPaint.setStyle(Paint.Style.STROKE);
            mPaint.setStrokeWidth(4);
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
    
    //        for (int i = 0; i < 1000; i++) {
    //            System.out.println("canvas = [" + canvas + "]" + i);
    //        }
    
            canvas.drawCircle(mWidth/2, mHeight/2, mRadius, mPaint);
        }
    
        @Override
        protected void onSizeChanged(int w, int h, int oldw, int oldh) {
            super.onSizeChanged(w, h, oldw, oldh);
            mWidth = getWidth();
            mHeight = getHeight();
            mRadius = Math.min(mWidth, mHeight) / 2;
        }
    }
    

    这里我觉得用RecyclerView是否更好?我们修改一下布局和代码。突然发现RecyclerView还得导依赖,这里就偷懒用一下ListView吧,一个意思。

    public class BusyOnDrawViewActivity extends AppCompatActivity {
    
        private ListView mListView;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_busy_on_draw_view);
    
            mListView = (ListView) findViewById(R.id.lv);
            mListView.setAdapter(new MyAdapter());
        }
    
        class MyAdapter extends BaseAdapter {
            @Override
            public int getCount() {
                return 10;
            }
    
            @Override
            public Object getItem(int position) {
                return null;
            }
    
            @Override
            public long getItemId(int position) {
                return position;
            }
    
            @Override
            public View getView(int position, View convertView, ViewGroup parent) {
                if (convertView == null) {
                    convertView = LayoutInflater.from(parent.getContext())
                            .inflate(R.layout.item, parent, false);
                }
                return convertView;
            }
        }
    
    }
    
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
                xmlns:tools="http://schemas.android.com/tools"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:paddingBottom="@dimen/activity_vertical_margin"
                android:paddingLeft="@dimen/activity_horizontal_margin"
                android:paddingRight="@dimen/activity_horizontal_margin"
                android:paddingTop="@dimen/activity_vertical_margin">
        <ListView
            android:id="@+id/lv"
            android:divider="@null"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>
    </LinearLayout>
    
    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
    
        <com.github.lzyzsd.androiduiproblems.BusyOnDrawView
            android:layout_width="100dp"
            android:layout_height="100dp"/>
    
        <com.github.lzyzsd.androiduiproblems.BusyOnDrawView
            android:layout_width="100dp"
            android:layout_height="100dp"/>
    
        <com.github.lzyzsd.androiduiproblems.BusyOnDrawView
            android:layout_width="100dp"
            android:layout_height="100dp"/>
    </LinearLayout>
    

    全文完

    相关文章

      网友评论

          本文标题:视图优化作业

          本文链接:https://www.haomeiwen.com/subject/hqeolttx.html