Android布局技巧之include、merge与ViewStub标签的巧用

前言

在开发中UI布局是我们都会遇到的问题,随着UI越来越多,布局的重复性、复杂度也会随之增长。

相信大家经常听到include、merge、ViewStub这样的标签,官方也提到这三种布局可用于布局的优化。今天就介绍下这三种布局的使用,记录下来,便于后续app中的使用。

include布局重用

app开发过程中,会遇到不同页面里有相同的布局,这时我们可以将这些通用的布局提取出来到一个单独的layout文件里,再使用<include>标签引入到相应的页面布局文件里,主要通过include的layout属性引用。

举个栗子

include的布局:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:id="@+id/container"
 android:layout_width="match_parent"
 android:layout_height="wrap_content">

 <TextView
 android:id="@+id/tv1"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:text="这里是来自include布局" />

</RelativeLayout>

activity的布局:

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

 <TextView
 android:id="@+id/tv2"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:text="以下的内容来自include标签" />

 <include
 android:id="@+id/container"
 layout="@layout/include_layout"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_below="@+id/tv"
 android:layout_marginTop="10dp" />
</RelativeLayout>

这个标签在日常工作使用还是很常见的。这里有几点需要注意下: 

1、如果给include标签 和 include所加载的布局 都添加id的话,那么id要保持一致,如例子中都是container,否则是在代码中获取不到RelativeLayout容器的。 当然我们可以避免这样的问题,只需要给其中一项添加id属性就可以。

2、include布局里元素的id 要和  include所在页面布局里的其他元素id 不同,如例子中的两个textview,如果把id设置相同了,程序运行起来并不会报错,但是textview的赋值只会赋值给其中的一个。

3、如果需要给include标签设置位置属性的话,如例子中的layout_below、layout_marginTop,这时候 必须 同时设置include标签的宽高属性layout_width、layout_height,否则编译器是会报错的。一般情况不需要设置include的其他属性,直接加载布局文件 <include layout="@layout/...."/>

4、布局中可以包含两个相同的include标签,如下代码所示 两个include都加载layout="@layout/include_layout"

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

 <TextView
 android:id="@+id/tv"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:text="以下的内容来自include标签" />

 <include
 android:id="@+id/container"
 layout="@layout/include_layout"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_below="@+id/tv"
 android:layout_marginTop="10dp" />

 <include
 android:id="@+id/container2"
 layout="@layout/include_layout"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_marginTop="80dp" />
</RelativeLayout>

可以设置不同include的id属性,引用的时候如下可以正常显示:

View view = findViewById(R.id.container2);
TextView textView = view.findViewById(R.id.tv);
textView.setText("这里是来自 第二个 include布局");

merge减少视图层级

merge标签可用于减少视图层级来优化布局,可以配合include使用,如果include标签的父布局 和 include布局的根容器是相同类型的,那么根容器的可以使用merge代替。

页面布局

<?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:id="@+id/tv"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:text="以下的内容不是来自merge标签" />

 <include
 layout="@layout/merge_layout"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_marginTop="20dp" />
</LinearLayout>

先看没有使用merge的:

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

 <TextView
 android:id="@+id/tv"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:text="这里是不是来自merge布局" />
</LinearLayout>

看下view层的结构:

再看使用了merge的:

<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android">

 <TextView
 android:id="@+id/tv"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:text="这里是来自merge布局" />
</merge>

view层结构:

可以看到对比,减少了一层的LinearLayout的嵌套,需要注意的是使用merge的布局,在include的标签设置距离属性没有生效,可以将一些间距属性设置到include布局里元素上,具体看项目需求使用。

ViewStub按需加载

按需加载 顾名思义需要的时候再去加载,不需要的时候可以不用加载,节约内存使用。通常情况我们会使用setVisibility方法来控制视图的显示和隐藏,但是这种情况视图已经加载了。

比如app中页面里某个布局只需要在特定的情况下才显示,其余情况下可以不用加载显示,这时候可以使用ViewStub。

layout属性是需要加载布局

<?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">

 <ViewStub
 android:id="@+id/viewstub"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_marginTop="20dp"
 android:layout="@layout/viewstub_layout" />
</LinearLayout>

需要注意的是 ViewStub的inflate()方法只能被调用一次,一旦调用后,ViewStub将从视图中移除,被对应的layout布局取代,同时会保留ViewStub上设置的属性效果。

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

这篇关于include、merge、ViewStub的使用就介绍到这里了,具体使用情况还得视项目而定。

最后附上github地址https://github.com/taixiang/include (本地下载)

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对我们的支持。

(0)

相关推荐

  • Android中使用include标签和merge标签重复使用布局

    尽管Android提供了各种组件来实现小而可复用的交互元素,你也可能因为布局需要复用一个大组件.为了高效复用完整布局,你可以使用<include/>和<merge/>标签嵌入另一个布局到当前布局.所以当你通过写一个自定义视图创建独立UI组件,你可以放到一个布局文件里,这样更容易复用. 复用布局因为其允许你创建可复用的复杂布局而显得非常强大.如,一个 是/否 按钮面板,或带描述文本的自定义进度条.这同样意味着,应用里多个布局里共同的元素可以被提取出来,独立管理,然后插入到每个布局里.

  • 解析android中include标签的使用

    在一个项目中我们可能会需要用到相同的布局设计,如果都写在一个xml文件中,代码显得很冗余,并且可读性也很差,所以我们可以把相同布局的代码单独写成一个模块,然后用到的时候可以通过<include /> 标签来重用layout代码.app_title.xml: 复制代码 代码如下: <?xml version="1.0" encoding="utf-8"?><RelativeLayout android:id="@+id/titl

  • android使用include调用内部组件的方法

    本文实例讲述了android使用include调用内部组件的方法.分享给大家供大家参考.具体如下: 例子一: sublayout.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical&

  • Android编程之include文件的使用方法

    本文实例分析了Android编程之include文件的使用方法.分享给大家供大家参考,具体如下: 记得很久以前,听一位大神说,程序员都很懒,不懒惰的程序员不是好程序员,当时不明白什么意思.后来慢慢的懂得了它的意思,好的程序员不要做重复的工作. 我们在android的布局文件中,常会遇到一些相同的布局,每个页面都写,一是比较麻烦,二是一旦有修改还得改多个文件.这个时候我们就可以用到include了. 非常简单的使用,下面看代码 include的文件scollandlisttitle.xml <?x

  • Android组件ViewStub基本使用方法详解

    ViewStub可以在运行时动态的添加布局.帮助文档给定的定义是: "A ViewStub is an invisible, zero-sized View that can be used to lazily inflate layout resources at runtime. When a ViewStub is made visible, or when inflate() is invoked, the layout resource is inflated. The ViewStu

  • Android抽象布局——include、merge 、ViewStub详解

    在布局优化中,Androi的官方提到了这三种布局<include />.<merge />.<ViewStub />,并介绍了这三种布局各有的优势,下面也是简单说一下他们的优势,以及怎么使用,记下来权当做笔记. 1.布局重用<include /> <include />标签能够重用布局文件,简单的使用如下: <LinearLayout xmlns:android="http://schemas.android.com/apk/re

  • 深入分析Android ViewStub的应用详解

    在开发应用程序的时候,经常会遇到这样的情况,会在运行时动态根据条件来决定显示哪个View或某个布局.那么最通常的想法就是把可能用到的View都写在上面,先把它们的可见性都设为View.GONE,然后在代码中动态的更改它的可见性.这样的做法的优点是逻辑简单而且控制起来比较灵活.但是它的缺点就是,耗费资源.虽然把View的初始可见View.GONE但是在Inflate布局的时候View仍然会被Inflate,也就是说仍然会创建对象,会被实例化,会被设置属性.也就是说,会耗费内存等资源. 推荐的做法是

  • Android开发技巧之ViewStub控件惰性装载

    在4.5.6节介绍过一个<include>标签,该标签可以在布局文件中引用另外一个布局文件,并可以覆盖被引用布局文件根节点所有与布局相关的属性,也就是以android:layout开头的属性.通过<include>标签可以将一个非常庞大的布局文件分解成若干个较小的布局文件,而且这些小的布局文件也可以被多次引用,从而达到一个重用的目的. <include>标签固然很好用,但有一个问题,就是布局文件中的控件并不一定在程序启动时全都用到,有一些控件只在特定的情况下才会被使用到

  • Android开发之merge结合include优化布局

    merge结合include优化android布局,效果不知道,个人感觉使用上也有很大的局限,不过还是了解一下,记录下来. 布局文件都要有根节点,但android中的布局嵌套过多会造成性能问题,于是在使用include嵌套的时候我们可以使用merge作为根节点,这样可以减少布局嵌套,提高显示速率. <?xml version="1.0" encoding="utf-8"?> <merge xmlns:android="http://sch

  • Android布局技巧之include、merge与ViewStub标签的巧用

    前言 在开发中UI布局是我们都会遇到的问题,随着UI越来越多,布局的重复性.复杂度也会随之增长. 相信大家经常听到include.merge.ViewStub这样的标签,官方也提到这三种布局可用于布局的优化.今天就介绍下这三种布局的使用,记录下来,便于后续app中的使用. include布局重用 app开发过程中,会遇到不同页面里有相同的布局,这时我们可以将这些通用的布局提取出来到一个单独的layout文件里,再使用<include>标签引入到相应的页面布局文件里,主要通过include的la

  • Android布局技巧之使用ViewStub

    多亏了<include />标签,在Android里,很容易就能做到共享和重用UI组件.在Android开发中,很容易就能创建出复杂的UI结构,结果呢,用了很多的View,且其中的一些很少使用.针对这种情况,谢天谢地,Android还为我们提供了一个特别的构件--ViewStub,它可以使你充分享受<include />的好处而不会造成无用View的浪费. ViewStub是一个看不见的,轻量级的View.它没有尺寸,也不会绘制以及以某种形式参与到布局中来.这意味着ViewStub

  • Android布局技巧之创建可重用的UI组件

    Android平台提供了大量的UI构件,你可以将这些小的视觉块(构件)搭建在一起,呈现给用户复杂且有用的画面.然而,应用程序有时需要一些高级的视觉组件.为了满足这一需求,并且能高效的实现,你可以把多个标准的构件结合起来成为一个单独的.可重用的组件. 例如,你可以创建一个可重用的组件包含一个进度条和一个取消按钮,一个Panel包含两个按钮(确定和取消动作),一个Panel包含图标.标题和描述等等.简单的,你可以通过书写一个自定义的View来创建一个UI组件,但更简单的方式是仅使用XML来实现. 在

  • Android布局技巧之合并布局

    我们已经有文章向你描述如何使用<include />标签来重用和共享你的布局代码.这篇文章将向你阐述<merge />标签的使用以及如何与<include />标签互补使用. <merge />标签用于减少View树的层次来优化Android的布局.通过看一个例子,你就能很容易的理解这个标签能解决的问题.下面的XML布局显示一个图片,并且有一个标题位于其上方.这个结构相当的简单:FrameLayout里放置了一个ImageView,其上放置了一个TextVi

  • Android布局技巧之创建高效布局

    Android UI工具包提供了一些布局管理器,它们使用起来相当容易,而且,大多数的时候,你只需要使用它们最基本的特征来实现UI. 执着于基本特征的使用对于创建UI来说,往往不是最高效的.一个常见的例子就是滥用LinearLayout,它将会导致View树中的View数量激增.View--更糟的是,布局管理器--添加到应用程序里都会带来一定的消耗:初始化,布局和绘制变得更加缓慢.嵌套布局的花销尤其"昂贵",例如,如果你嵌套了一些LinearLayout,并使用了weight参数,这会导

  • Android布局优化之ViewStub控件

    ViewStub是Android布局优化中一个很不错的标签/控件,直接继承自View.虽然Android开发人员基本上都听说过,但是真正用的可能不多. ViewStub可以理解成一个非常轻量级的View,与其他的控件一样,有着自己的属性及特定的方法.当ViewStub使用在布局文件中时,当程序inflate布局文件时,ViewStub本身也会被解析,且占据内存控件,但是与其他控件相比,主要区别体现在以下几点: 1.当布局文件inflate时,ViewStub控件虽然也占据内存,但是相相比于其他控

  • android布局优化的一些实用建议

    前言 Android的绘制优化其实可以分为两个部分,即布局(UI)优化和卡顿优化,而布局优化的核心问题就是要解决因布局渲染性能不佳而导致应用卡顿的问题,所以它可以认为是卡顿优化的一个子集. 本文主要包括以下内容 为什么要进行布局优化及android绘制,布局加载原理 获取布局文件加载耗时的方法 介绍一些布局优化的手段与方法 一些常规优化手段 为什么要进行布局优化? 为什么要进行布局优化?答案是显而易见的,如果布局嵌套过深,或者其他原因导致布局渲染性能不佳,可能会导致应用卡顿 那么布局到底是如何导

  • Android布局性能优化之按需加载View

    有时应用程序中会有一些很少用到的复杂布局.在需要它们的时候再加载可以降低内存的消耗,同时也可以加快界面的渲染速度. 定义ViewStub ViewStub是一个轻量级的View,它没有高宽,也不会绘制任何东西.所以它的加载与卸载的成本很低.每个ViewStub都可以使用android:layout属性指定要加载的布局. 下面这个ViewStub用于一个半透明的ProgressBar的加载.它只有在新工作开始时才会显示. <ViewStub android:id="@+id/stub_imp

随机推荐