自定義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")

在這裏插入圖片描述

通過斷點可以看到,只有一個childLinearLayout數量只有一個,LinearLayout下面纔是我們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代碼

package cn.sccl.app.tfkjymanage;

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會使設置的屬性失效,所以在代碼中在設置一次。

然後我們在打斷點試一下看下效果
在這裏插入圖片描述
這下就是我們佈局裏面的兩個TextView了,少了一層嵌套;開發中的一個小細節,在此記錄,有不對的地方歡迎留言指正。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章