布局优化inclue merge ViewStub

布局优化主要分为三部分,代码优化、绘制层级优化与动态加载View,分别对应着include、merge、ViewStib

1 include

include 标签主要用来实现代码复用,当布局文件太复杂或者存在某些布局文件可以复用的时候就可以使用include
例如编写一个个人信息页面如下


1.jpg

对应的着布局文件activity_main。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    >
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textSize="25sp"
        android:background="@color/colorAccent"
        android:text="姓名"/>
    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textSize="25sp"
        android:layout_marginTop="10dp"
        android:background="@color/colorAccent"
        android:text="电话"/>
    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textSize="25sp"
        android:layout_marginTop="10dp"
        android:background="@color/colorAccent"
        android:text="邮箱"/>
    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
</LinearLayout>

当我们发现其他页面也会用到类似的布局时候就可以将这部分布局单独定义在另一个xml布局文件中,然后在需要引入这类布局的地方调用include标签。
首先将这部分布局提取到 info_xml 文件中

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textSize="25sp"
        android:background="@color/colorAccent"
        android:text="姓名"/>

    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textSize="25sp"
        android:layout_marginTop="10dp"
        android:background="@color/colorAccent"
        android:text="电话"/>

    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textSize="25sp"
        android:layout_marginTop="10dp"
        android:background="@color/colorAccent"
        android:text="邮箱"/>

    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</LinearLayout>

之后再activity_main.xml文件中引入这套布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    >

    <include
        layout="@layout/info" />

</LinearLayout>

运行后得到同样的界面


1.jpg

2 merge

使用include引入布局存在一个弊端,就是会引入一层布局嵌套,由于我们在定义info.xml布局文件时候,将所有的控件放到了LinearLayout中,之后在activity_main布局文件的LinearLayout中将info布局作为一个子View引入,因此info.xml文件中的LinearLayout是一个多余的View层,为了避免引入这层嵌套就可以使用merge来代替LinearLayout,修改info.xml布局文件

<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android">
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textSize="25sp"
        android:background="@color/colorAccent"
        android:text="姓名"/>

    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textSize="25sp"
        android:layout_marginTop="10dp"
        android:background="@color/colorAccent"
        android:text="电话"/>
    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textSize="25sp"
        android:layout_marginTop="10dp"
        android:background="@color/colorAccent"
        android:text="邮箱"/>
    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
</merge>

在运行程序,会得到通样的界面,但是merge中的这些View就被作为activity.xml文件中的LinearLayout内部的子View引入,避免了一层布局嵌套。

3 ViewStub

ViewStub是一个继承自View的控件,当使用布局加载器加载一套xml布局的时候就会创建对应View标签的实例对象(如TextView,Button),ViewStub是一个没有大小,没有绘制功能,资源消耗很少的View,它可以与一套布局文件形成对应关系,当程序最初运行时候首先加载ViewStub,当用到ViewStub对应布局时再去加载这套布局,这就增加了很多的灵活性,并且可以延迟加载一些不必要的控件。
这里使用ViewStub来对应info.xml的这套布局。
activity_main.xml中代码如下

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    >
    <Button
        android:id="@+id/load_view_stub"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="显示ViewStub布局"
        android:textSize="25sp"/>
    <ViewStub
        android:id="@+id/view_stub"
        android:layout="@layout/info"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</LinearLayout>

ViewStub的layout标签就是对应的布局,注意这里的info.xml不能使用merge标签。因此加载的布局会引入一层布局嵌套。
这里添加一个按钮来控制ViewStub显示info布局。为Button添加点击事件,获取到ViewStub对象,然后调用inflate()将info的布局显示出来。


public class MainActivity extends AppCompatActivity  {


    Button button;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        button=findViewById(R.id.load_view_stub);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ViewStub stub=findViewById(R.id.view_stub);
                stub.inflate();
            }
        });
    }
}

程序运行后如图,这里没有显示info布局


2.jpg

点击显示ViewStub按钮后显示info布局。


3.jpg
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,240评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,328评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,182评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,121评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,135评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,093评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,013评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,854评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,295评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,513评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,678评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,398评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,989评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,636评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,801评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,657评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,558评论 2 352

推荐阅读更多精彩内容

  • 先扯两句 上次写的部分主要还是一些封装的抽象方法,这部分只是单纯的为我这种懒汉提供了便利罢了,而本次写的内容呢,则...
    半寿翁阅读 2,870评论 0 12
  • 在开发中UI布局是我们都会遇到的问题,随着UI越来越多,布局的重复性、复杂度也会随之增长。对此我们优化xml布局就...
    JimLong阅读 2,330评论 1 21
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 172,061评论 25 707
  • 当年若不是他救了她,她又怎会有现在! 三月,正是草长莺飞,百花齐放的时候。 在一个不知名的山谷里,满谷的白色野花中...
    风落无殇阅读 245评论 8 5
  • 今天想起来了。初中的时候,她问我借钱,有一次因为吃饭的时候闹别扭,关系僵了,后来我叫他弟弟告诉她还我的钱,还了。关...
    花香云阅读 293评论 0 0