自定义ViewGroup结合merge标签减少嵌套

自定义ViewGroup结合merge标签减少嵌套

废话不多说,直奔主题

在开发中经常会继承LinearLayout、RelativeLayout、FrameLayout等系统自带的ViewGroup来实现自己的布局,先来看我之前的写法

首先看布局,拿LinearLayout 举例;文件名R.layout.tes

<?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="35dp"
    android:orientation="horizontal">

    <TextView
        android:layout_width="80dp"
        android:layout_height="match_parent"
        android:gravity="center"
        android:text="名称:"
        android:textColor="@color/black" />


    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center_vertical"
        android:text="张三"
        android:textColor="@color/black" />

</LinearLayout>

再来看看自定义View

public class MyLinearLayout extends LinearLayout {

    public MyLinearLayout(Context context) {
        this(context, null);
    }

    public MyLinearLayout(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public MyLinearLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        
        View view = LayoutInflater.from(context).inflate(R.layout.test, this);
        
        //其他业务省略...
    }
}

这样一看好像没什么问题啊,确实没问题;我们接着来看一下测试代码

 val layout=MyLinearLayout(this)
 XLogUtils.d("childCount数量+$layout.childCount")

在这里插入图片描述

通过断点可以看到,MyLinearLayout只有一个childLinearLayout,我想要的效果是MyLinearLayout下面直接是两个TextViewMyLinearLayout的childLinearLayout下面才是我XML里面的两个TextView,我之前一直以为
LayoutInflater.from(context).inflate(R.layout.test, this)这种写法不会再嵌套一层,在开发中偶然一个debug发现了这个问题;虽然这种做法对现在的手机性能影响并不是很大,但是多多少少还是有一定影响,平时开发中就要注意,能优化的尽量还是优化一下。

解决办法就是用 < merge >标签

直接上代码

布局R.layout.test

<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="35dp"
    xmlns:tools="http://schemas.android.com/tools"
    tools:parentTag="android.widget.LinearLayout"
    android:orientation="horizontal">

    <TextView
        android:layout_width="80dp"
        android:layout_height="match_parent"
        android:gravity="center"
        android:text="名称:"
        android:textColor="@color/black" />


    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center_vertical"
        android:text="张三"
        android:textColor="@color/black" />

</merge>

tools:parentTag="xxxx"这里的gogle考虑到在Ide中可能不能直观的看到布局长啥样,这里我继承LinearLayout就填写tools:parentTag="android.widget.LinearLayout";如果自定义RelativrLayot的话这里就写RelativrLayot,保证java代码继承的ViewGroup和xml一致就Ok。

Java代码


import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;

import androidx.annotation.Nullable;

public class MyLinearLayout extends LinearLayout {

    public MyLinearLayout(Context context) {
        this(context, null);
    }

    public MyLinearLayout(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public MyLinearLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        View view = LayoutInflater.from(context).inflate(R.layout.test, this);

        //XML中用merge会使设置的属性失效,所以在代码中在设置一次。
        setOrientation(LinearLayout.HORIZONTAL);
        setLayoutParams(
                new ViewGroup.LayoutParams(
                        ViewGroup.LayoutParams.MATCH_PARENT,
                        ViewGroup.LayoutParams.WRAP_CONTENT
                ));
        //设置背景、居中、边距等等........

        //其他业务省略...
    }
}

Java代码需要注意的就是XML中用merge会使设置的属性失效,所以在代码中在设置一次。

然后我们在打断点试一下看下效果
在这里插入图片描述
这下layout就是我们自定义的LinearLayout,里面是两个TextView了,少了一层嵌套;开发中的一个小细节,在此记录,有不对的地方欢迎留言指正。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值