当前位置: 首页 > news >正文

Android 布局巧用之include、merge、ViewStub

原文链接:https://mp.weixin.qq.com/s/bTA2gztUzqvqER2rz56RRQ

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

include布局重用

app开发过程中,会遇到不同页面里有相同的布局,这时我们可以将这些通用的布局提取出来到一个单独的layout文件里,再使用<include>标签引入到相应的页面布局文件里,主要通过includelayout属性引用。
举个栗子
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_belowlayout_marginTop,这时候 必须 同时设置include标签的宽高属性layout_widthlayout_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层的结构:

image

再看使用了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层结构:

image

可以看到对比,减少了一层的 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>

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

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

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

最后附上github地址https://github.com/taixiang/include

欢迎关注我的博客:https://blog.manjiexiang.cn/
更多精彩欢迎关注微信号:春风十里不如认识你

image.png

相关文章:

  • HTML(form标签)、CSS选择器一
  • 初始 Mybatis(一) —— 基本配置及用法
  • OpenStack Newton部署官方指南
  • 小前端眼里的大前端:GMTC 2018 参会小结
  • Rails哲学三原则
  • TCPDF 如何实现首行缩进
  • https请求过程
  • 一个JS多个数组取交集算法
  • JS对象的克隆
  • 作为面试官如何从深度和广度上考察面试者
  • 沃森想通过社交网络筛出最想要优惠券的人
  • 刨根问底 | Elasticsearch 5.X集群多节点角色配置深入详解【转】
  • 在word中输入任意角度旋转图片
  • python怎么写可读性好的面向过程的长篇代码?
  • 第一节:.Net版基于WebSocket的聊天室样例
  • -------------------- 第二讲-------- 第一节------在此给出链表的基本操作
  • [笔记] php常见简单功能及函数
  • android图片蒙层
  • ES6之路之模块详解
  • Git同步原始仓库到Fork仓库中
  • Javascript Math对象和Date对象常用方法详解
  • Javascript设计模式学习之Observer(观察者)模式
  • STAR法则
  • Twitter赢在开放,三年创造奇迹
  • Vue 2.3、2.4 知识点小结
  • vue-router 实现分析
  • 从地狱到天堂,Node 回调向 async/await 转变
  • 关于Android中设置闹钟的相对比较完善的解决方案
  • 缓存与缓冲
  • 基于阿里云移动推送的移动应用推送模式最佳实践
  • 浏览器缓存机制分析
  • 什么软件可以剪辑音乐?
  • 算法-插入排序
  • 我从编程教室毕业
  • const的用法,特别是用在函数前面与后面的区别
  • #我与Java虚拟机的故事#连载10: 如何在阿里、腾讯、百度、及字节跳动等公司面试中脱颖而出...
  • #我与Java虚拟机的故事#连载13:有这本书就够了
  • #我与Java虚拟机的故事#连载19:等我技术变强了,我会去看你的 ​
  • (4)STL算法之比较
  • (TOJ2804)Even? Odd?
  • (附源码)springboot车辆管理系统 毕业设计 031034
  • (区间dp) (经典例题) 石子合并
  • (转)iOS字体
  • ./mysql.server: 没有那个文件或目录_Linux下安装MySQL出现“ls: /var/lib/mysql/*.pid: 没有那个文件或目录”...
  • .NET分布式缓存Memcached从入门到实战
  • .net开源工作流引擎ccflow表单数据返回值Pop分组模式和表格模式对比
  • .net连接oracle数据库
  • .Net组件程序设计之线程、并发管理(一)
  • ?
  • @vue/cli脚手架
  • [ vulhub漏洞复现篇 ] Celery <4.0 Redis未授权访问+Pickle反序列化利用
  • [Asp.net MVC]Asp.net MVC5系列——Razor语法
  • [AutoSar]BSW_Com07 CAN报文接收流程的函数调用
  • [BZOJ4010]菜肴制作
  • [FUNC]判断窗口在哪一个屏幕上