Include
作用
- 公共布局复用:开发过程中如果xml布局多个地方用到,可以抽出到一个xml布局中,方便其他地方引用。
- 复杂布局结构更清晰:如果界面复杂也可以将一个xml分成几个子xml,利用include引用,使结构更清晰
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<include
android:id="@+id/bodyTempView"
layout="@layout/item_body_tem"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone" />
<include
android:id="@+id/bodyEnvTempView"
layout="@layout/item_body_env_tem"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone" />
<include
android:id="@+id/noSupportTemView"
layout="@layout/item_not_support_tem"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
class MTestView @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : AppCompatTextView(context, attrs, defStyleAttr) {
init {
"MTextView init...".e()
}
}
打印结果
MTextView init...
MTextView init...
MTextView init...
viewStub
作用
viewStub相比include有延迟加载的作用。
比如:例如我们通过一个ViewStub来惰性加载一个消息流的评论列表,因为一个帖子可能并没有评论,此时我可以不加载这个评论的ListView,只有当有评论时我才把它加载出来,这样就去除了加载ListView带来的资源消耗以及延时
通过调用setVisibility函数或者Inflate函数才会将其要装载的目标布局给加载出来,从而达到延迟加载的效果
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ViewStub
android:id="@+id/bodyTempView"
android:layout="@layout/item_body_tem"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone" />
<ViewStub
android:id="@+id/bodyEnvTempView"
android:layout="@layout/item_body_env_tem"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone" />
<ViewStub
android:id="@+id/noSupportTemView"
android:layout="@layout/item_not_support_tem"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
根据需求加载
when (type) {
TempType.BODY_TEMP -> {
if(!binding.bodyTempView.isInflated){
binding.bodyTempView.viewStub?.inflate()
}
}
TempType.BODY_ENV_TEMP -> {
if(!binding.bodyEnvTempView.isInflated){
binding.bodyEnvTempView.viewStub?.inflate()
}
}
TempType.NONE -> {
if(!binding.noSupportTemView.isInflated){
binding.noSupportTemView.viewStub?.inflate()
}
}
}
打印结果
MTextView init...
merge
作用
减少布局层数,加快视图的绘制,提高UI性能
使用
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
android:layout_height="match_parent">
<include layout="@layout/test_include_1"/>
</androidx.constraintlayout.widget.ConstraintLayout>
test_include_1
<merge xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="200dp"
android:layout_height="200dp"
android:text="hello"
android:gravity="center"
android:background="@color/purple_200"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
/>
</merge>`
可以看到 merge中使用的是外层布局ConstraintLayout的属性,同理如果外层布局是Linearlayout,使用对应的属性
注意事项
- merge必须放在布局文件的根节点上。
- merge并不是一个ViewGroup,也不是一个View,它相当于声明了一些视图,等待被添加。
- merge标签被添加到A容器下,那么merge下的所有视图将被添加到A容器下。
- 因为merge标签并不是View,所以在通过LayoutInflate.inflate方法渲染的时候, 第二个参数必须指定一个父容器,且第三个参数必须为true,也就是必须为merge下的视图指定- 一个父亲节点。
- 如果Activity的布局文件根节点是FrameLayout,可以替换为merge标签,这样,执行setConten- tView之后,会减少一层FrameLayout节点。
- 自定义View的时候,根节点如果需要设置成LinearLayout,建议让自定义的View点建议设置成m- erge,然后自定义的View
- 因为merge不是View,所以对merge标签设置的所有属性都是无效的。-