Android布局优化-include、merge以及ViewStub使用

一、inlude 标签

inlude 标签用于 xml 复用,实现布局模块化,减少开发者工作量。

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

    <TextView
        android:id="@+id/tv_title"
        android:layout_width="match_parent"
        android:layout_height="45dp"
        android:text="标题"
        android:gravity="center"/>

</merge>

<!--layout_title.xml-->
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".ui.UIOptimizeActivity">

    <include android:id="@+id/include" layout="@layout/layout_title"/>

</androidx.constraintlayout.widget.ConstraintLayout>

 include 的标签是否有效?

1、id:

a)在同一个 xml 下 include 两次 layout_title.xml 并对 include 标签分别设置不同的 id ,运行应用之后使用 layout inspector 查看,发现 Activity 中存在两个 id 为 tv_title 的 TextView(应该是 layout inspector 的问题),TextView 的 id 并没有发生改变.

b)将 merge 标签改为未设置 id 的 LinearLayout 运行之后使用 layout inspector 查看 发现 include 的 id 被添加到 LinearLayout 之上。

c)将 merge 标签下的 TextView id 删除,运行之后使用 layout inspector 查看,发现 Activity 中存在两个 id 为空的 TextView

d)将 merge 标签改为有设置 id 的 LinearLayout 运行之后使用 layout inspector 查看 发现 include 的 id 被添加到 LinearLayout 之上。

结论:include 标签的 id 会被赋值到被 include 的 xml 的根 View 上,如果 xml 的根标签是 merge 那么 include 的 id 无效。

2、layout_width、layout_height、margin、padding 等:

a)将 merge 标签改为 LinearLayout,include 上设置的属性有效。

b)将 LinearLayout 标签改为 merge,include 上设置的属性无效。

结论:include 标签的 width、height、margin、padding 等属性会被赋值到被 include 的 xml 的根 View 上,如果 xml 的根标签是 merge 那么 include 的属性无效。

二、merge 标签

merge 标签可以用来减少 View 层级,由于一般需要复用的 xml 都比较复杂因此极少存在需要使用的场景,目前主要是配合 include 标签,或者在自定义 View 时候,比如继承了某个 ViewGroup 的场景下使用 merge 标签减少自定义控件的层级。

1、使用 merge 标签如何使用指定 ViewGroup 属性?

merge 标签不是View,所以被 merge 标签包裹的 view 无法使用  ViewGroup 的属性实现对应的布局效果,Google 提供了 parentTag 标签来解决这个问题。

tools:parentTag="android.widget.LinearLayout"

三、ViewStub 标签

1、ViewStub 的使用

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

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="我藏在ViewStub中!!!" />

</LinearLayout>

<!--layout_view_stub-->

编写布局 文件

<?xml version="1.0" encoding="utf-8"?>
<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"
    tools:context=".ui.UIOptimizeActivity"
    android:orientation="vertical">

    <include
        android:id="@+id/include"
        layout="@layout/layout_title"
        android:layout_width="match_parent"
        android:layout_height="100dp"
        android:layout_marginTop="60dp" />

    <Button
        android:id="@+id/btn_show_tips"
        android:layout_width="match_parent"
        android:layout_height="45dp"
        android:layout_margin="16dp"
        android:text="SHOW TIPS"/>

    <ViewStub
        android:id="@+id/vs_tips"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout="@layout/layout_view_stub"/>

</LinearLayout>

 定义ViewStub

private lateinit var btnShowTips: Button
private lateinit var vsTips: ViewStub
//通过 by lazy 关键字 在使用 tips 对象的时候再初始化 tips 对象
private val tips: View by lazy { vsTips.inflate() }


override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_ui_optimize)

    btnShowTips = findViewById<Button?>(R.id.btn_show_tips).apply {
        setOnClickListener {
            showTips()
        }
    }

    vsTips = findViewById(R.id.vs_tips)

}


private fun showTips() {
    tips.visibility = View.VISIBLE
}

 (调用ViewStub

2、为什么使用ViewStub,而不直接View.setVisibiliy(View.GONE)

使用 View.setVisibiliy 的方式虽然 View 没有展示出来,实际上LayoutInflator还是会创建View的示例并加载资源的,如果使用ViewStub,那么就只会加载 ViewStub,如图:

layout inspector

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值