Android 性能优化笔记 一 布局优化

作者: 月夜无声 | 来源:发表于2017-11-22 16:41 被阅读125次
    一、使用<include>标签重用布局

    eg:一个公用的布局common.xml

     <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:background="#ccc"
     android:layout_height="50dp">
      <TextView
    android:layout_centerInParent="true"
     android:textSize="16sp"
      android:text="标题"
     android:layout_width="wrap_content"
    android:layout_height="wrap_content" />
            </RelativeLayout>
    

    在需要重用此布局的地方

    <?xml version="1.0" encoding="utf-8"?>
     <RelativeLayout
     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"
    tools:context="com.mh.demoperformance.MainActivity">
     <include layout="@layout/common"/>
          </RelativeLayout>
    
    

    效果图


    2376856-60e54112922a0ce6.png

    使用include 引入一个布局文件,include标签除了可以指定id之外,
    只能使用android:layout_开头的属性,而且只要
    指定了android:layout_这种属性就必须要写
    上android:layout_height和android:layout_width,否者
    其他的android:layout_属性都无效,一旦在include 中
    指定了android:layout_height和android:layout_width之
    后,被include 进来的布局的根元素的android:layout_height和
    android:layout_width将无效,宽高将和include里面的保持一致,
    修改布局后:

    <?xml version="1.0" encoding="utf-8"?>
            <RelativeLayout
                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"
                tools:context="com.mh.demoperformance.MainActivity">
                <include
                    android:layout_height="match_parent"
                    android:layout_width="match_parent"
                    layout="@layout/common"/>
    
            </RelativeLayout>
    

    效果图

    2376856-0e67b6bed6ca2249.png
    同理如果include 里面写了id标签,被include 的布局的根元素
    也指定了id标签,那么将以inclide的id标签为准
    二、使用<merge>标签合并布局

    一般在使用<include>标签的时候会引入多余的嵌套布局,
    比如在上面的例子中,布局和被嵌套的布局的最外层都
    使用了RelativeLayout,所以被嵌套的布局的RelativeLayout是
    多余的,所以<merge>标签一般和<include>标签一起使用
    来减少布局层级修改common.xml布局

    <?xml version="1.0" encoding="utf-8"?>
    <merge xmlns:android="http://schemas.android.com/apk/res/android">
    <TextView
    android:layout_centerInParent="true"
     android:textSize="16sp"
    android:text="标题"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />
    </merge>
    

    这样就去除了多余的RelativeLayout 布局嵌套
    merge的一些特性:

    1. merge必须放在布局文件的根节点上。
    2. merge并不是一个View,只是声明了一些视图,等待被添加。
      所以对merge标签设置的所有属性都是无效的。如果通
      过LayoutInflate.inflate方法渲染, 第二个参数必须指定
      一个父容器,且第三个参数必须为true。
      贴一篇作者 江南一点雨 LayoutInflate.inflate的文章
      (http://blog.csdn.net/u012702547/article/details/52628453)
    3. 如果Activity的布局根节点是FrameLayout,可以替换
      为merge标签,这样执行setContentView之后,会减少
      一层FrameLayout节点。
    三、使用<ViewStub>按需加载布局

    在实际开发中很多布局我们并不是一开始就需要加载的
    ,通常我们可以使用显示和隐藏来实现。但是这样
    隐藏的布局在一开始的时候就已经参与绘制了,
    会影响绘制的效率。而VIewStub本事继承了View,
    它的宽和高都是0,自身并不参与绘制。当我们需要
    显示的时候才去加载进来,能提高程序的初始化性能。

    一个需要按需加载的布局文件viewstub.xml

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">
    <Button
    android:textSize="16sp"
     android:text="点击重新加载"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />
     </RelativeLayout>
    

    main.xml文件

    <?xml version="1.0" encoding="utf-8"?>
     <RelativeLayout
     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:background="#ccc"
    tools:context="com.mh.demoperformance.MainActivity">
    <ViewStub
     android:layout_centerInParent="true"
     android:id="@+id/viewstub"
     android:layout="@layout/common"
    android:layout_width="wrap_content"
     android:layout_height="wrap_content" />
            </RelativeLayout>
    

    在需要显示的时候

    ViewStub viewStub = (ViewStub) findViewById(R.id.viewstub);
     viewStub.inflate();
    

    或者

     mViewStub = (ViewStub) findViewById(R.id.viewstub);
            mViewStub.setVisibility(View.VISIBLE);
    

    当调用infalte或者ViewStub.setVisibility(View.VISIBLE);时,
    先从父视图上把当前ViewStub删除,再把加载的android:layotu视图添加上

    四、LinearLayout增加divider分割线

    如果我们要给LinearLayout 添加如下图的分割线,通常我们可以
    在每一项中间添加一个View,设置view的宽高,和背景,
    但是这样不仅浪费资源而且还繁琐,
    在android3.0及后面的版本给LinearLayout添加分割线我们可以这样做:
    1)在drawable文件下新建shape_divider.xml

    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android">
        <solid android:color="#e70303" />
        <size android:height="1dp" />
    </shape>
    

    2)在LinearLayout中添加

    android:showDividers="middle"
    android:divider="@drawable/shape_divider"
    

    效果图


    2376856-5a81e6867eb1e694.png

    这样便能实现上图中效果。android:divider="@drawable"中的drawable也可以是图片文件,
    修改android:divider="@drawable/shape_divider"为android:divider="@drawable/pic" ,
    pic是一张图片。效果如下图


    2376856-36aa733f0b14ebe9.png
    showDividers 一共有下面几个参数值可选 middle|end|beginning|none
    middle -- 在每一项中间添加分割线

    end -- 在整体的最后一项添加分割线
    beginning -- 在整体的最上方添加分割线
    none -- 无

    五、Space占位

    Space控件在布局中只占位置,而不去绘制渲染。
    组件中的间隙用Space控件填充比用其它控件
    填充可以提高绘制效率。

    <android.support.v4.widget.Space
            android:layout_width="match_parent"
            android:layout_height="20dp"/>
    

    占位20dp高

    相关文章

      网友评论

        本文标题:Android 性能优化笔记 一 布局优化

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