自定義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")
通過斷點可以看到,只有一個child
是LinearLayout
數量只有一個,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
了,少了一層嵌套;開發中的一個小細節,在此記錄,有不對的地方歡迎留言指正。