LayoutInflater.inflate()
让XML
布局文件变成View
对象
获取LayoutInflater
对象的方式
val layoutInflater: LayoutInflater = LayoutInflater.from(this)
val layoutInflater: LayoutInflater = getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
layoutInflater
LayoutInflater.inflate()
方法详解
public View inflate(
@LayoutRes int resource,
@Nullable ViewGroup root,
boolean attachToRoot
){}
XML文件
R.layout.activity_main
根布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/root_ll"
android:layout_width="300dp"
android:layout_height="300dp"
android:gravity="center"
android:background="@android:color/holo_red_light">
<TextView
android:id="@+id/root_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!" />
</LinearLayout>
R.layout.inflate_layout
要动态填充的布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/inflate_ll"
android:layout_width="200dp"
android:layout_height="200dp"
android:gravity="center"
android:background="@android:color/holo_blue_light">
<TextView
android:id="@+id/inflate_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello inflate" />
</LinearLayout>
如果root==null
,不管attachRoot
为true
还是false
const val TAG = "Yang"
class MainActivity : AppCompatActivity() {
var rootLinearLayout : LinearLayout ?= null
var inflateLinearLayout : LinearLayout ?= null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
rootLinearLayout = findViewById(R.id.root_ll)
inflateLinearLayout = layoutInflater.inflate(R.layout.inflate_layout, null) as? LinearLayout
Log.i(TAG, "rootLinearLayout = ${rootLinearLayout}, rootLinearLayout?.layoutParams = ${rootLinearLayout?.layoutParams}, rootLinearLayout?.parent = ${rootLinearLayout?.parent}")
Log.i(TAG, "<---------最外层LinearLayout start----------->")
rootLinearLayout?.forEach {
Log.i(TAG, "child = $it, child.layoutParams = ${it.layoutParams}")
}
Log.i(TAG, "<---------最外层LinearLayout end----------->")
Log.i(TAG, "addView before inflateLinearLayout = ${inflateLinearLayout}, inflateLinearLayout?.layoutParams = ${inflateLinearLayout?.layoutParams}, inflateLinearLayout?.parent = ${inflateLinearLayout?.parent}")
Log.i(TAG, "<---------内层LinearLayout addView before start----------->")
inflateLinearLayout?.forEach {
Log.i(TAG, "child = $it, child.layoutParams = ${it.layoutParams}")
}
Log.i(TAG, "<---------内层LinearLayout addView before end----------->")
rootLinearLayout?.addView(inflateLinearLayout)
Log.i(TAG, "addView after inflateLinearLayout = ${inflateLinearLayout}, inflateLinearLayout?.layoutParams = ${inflateLinearLayout?.layoutParams}, inflateLinearLayout?.parent = ${inflateLinearLayout?.parent}")
Log.i(TAG, "<---------内层LinearLayout addView after start----------->")
inflateLinearLayout?.forEach {
Log.i(TAG, "child = $it, child.layoutParams = ${it.layoutParams}")
}
Log.i(TAG, "<---------内层LinearLayout addView after end----------->")
}
}
2024-05-16 20:48:47.437 21332-21332 Yang I rootLinearLayout = android.widget.LinearLayout{40b9e68 V.E...... ......ID 0,0-0,0 #7f0a03cf app:id/root_ll}, rootLinearLayout?.layoutParams = android.widget.FrameLayout$LayoutParams@fa65281, rootLinearLayout?.parent = androidx.appcompat.widget.ContentFrameLayout{7ba9f26 V.E...... ......I. 0,0-0,0 #1020002 android:id/content}
2024-05-16 20:48:47.437 21332-21332 Yang I <---------最外层LinearLayout start----------->
2024-05-16 20:48:47.437 21332-21332 Yang I child = androidx.appcompat.widget.AppCompatTextView{4578767 V.ED..... ......ID 0,0-0,0 #7f0a03d2 app:id/root_tv}, child.layoutParams = android.widget.LinearLayout$LayoutParams@5303914
2024-05-16 20:48:47.437 21332-21332 Yang I <---------最外层LinearLayout end----------->
2024-05-16 20:48:47.437 21332-21332 Yang I addView before inflateLinearLayout = android.widget.LinearLayout{6495bd V.E...... ......ID 0,0-0,0 #7f0a01ca app:id/inflate_ll}, inflateLinearLayout?.layoutParams = null, inflateLinearLayout?.parent = null
2024-05-16 20:48:47.437 21332-21332 Yang I <---------内层LinearLayout addView before start----------->
2024-05-16 20:48:47.438 21332-21332 Yang I child = androidx.appcompat.widget.AppCompatTextView{da187b2 V.ED..... ......ID 0,0-0,0 #7f0a01cb app:id/inflate_tv}, child.layoutParams = android.widget.LinearLayout$LayoutParams@acb3303
2024-05-16 20:48:47.438 21332-21332 Yang I <---------内层LinearLayout addView before end----------->
2024-05-16 20:48:47.438 21332-21332 Yang I addView after inflateLinearLayout = android.widget.LinearLayout{6495bd V.E...... ......ID 0,0-0,0 #7f0a01ca app:id/inflate_ll}, inflateLinearLayout?.layoutParams = android.widget.LinearLayout$LayoutParams@961d280, inflateLinearLayout?.parent = android.widget.LinearLayout{40b9e68 V.E...... ......ID 0,0-0,0 #7f0a03cf app:id/root_ll}
2024-05-16 20:48:47.438 21332-21332 Yang I <---------内层LinearLayout addView after start----------->
2024-05-16 20:48:47.438 21332-21332 Yang I child = androidx.appcompat.widget.AppCompatTextView{da187b2 V.ED..... ......ID 0,0-0,0 #7f0a01cb app:id/inflate_tv}, child.layoutParams = android.widget.LinearLayout$LayoutParams@acb3303
2024-05-16 20:48:47.438 21332-21332 Yang I <---------内层LinearLayout addView after end----------->
- 未通过
ViewGroup.addView()
添加的ViewGroup
不在任何父布局中,其LayoutParams
为null
。但是这个ViewGroup
包裹的View
对象的LayoutParams
不为null
,因为包裹的View
对象有确定的父布局,只是这个父布局没有自己的父布局 - 通过
ViewGroup.addView()
添加的ViewGroup
已经被添加到一个父布局中,其LayoutParams
不再为null
。这个ViewGroup
包裹的View
对象的LayoutParams
也不为null
,因为包裹的View
对象有确定的父布局
如果root!=null
,attachRoot==false
class MainActivity : AppCompatActivity() {
var rootLinearLayout : LinearLayout ?= null
var inflateLinearLayout : LinearLayout ?= null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
rootLinearLayout = findViewById(R.id.root_ll)
inflateLinearLayout = layoutInflater.inflate(R.layout.inflate_layout, rootLinearLayout, false) as? LinearLayout
Log.i(TAG, "rootLinearLayout = ${rootLinearLayout}, rootLinearLayout?.layoutParams = ${rootLinearLayout?.layoutParams}, rootLinearLayout?.parent = ${rootLinearLayout?.parent}")
Log.i(TAG, "<---------最外层LinearLayout start----------->")
rootLinearLayout?.forEach {
Log.i(TAG, "child = $it, child.layoutParams = ${it.layoutParams}")
}
Log.i(TAG, "<---------最外层LinearLayout end----------->")
Log.i(TAG, "addView before inflateLinearLayout = ${inflateLinearLayout}, inflateLinearLayout?.layoutParams = ${inflateLinearLayout?.layoutParams}, inflateLinearLayout?.parent = ${inflateLinearLayout?.parent}")
Log.i(TAG, "<---------内层LinearLayout addView before start----------->")
inflateLinearLayout?.forEach {
Log.i(TAG, "child = $it, child.layoutParams = ${it.layoutParams}")
}
Log.i(TAG, "<---------内层LinearLayout addView before end----------->")
rootLinearLayout?.addView(inflateLinearLayout)
Log.i(TAG, "addView after inflateLinearLayout = ${inflateLinearLayout}, inflateLinearLayout?.layoutParams = ${inflateLinearLayout?.layoutParams}, inflateLinearLayout?.parent = ${inflateLinearLayout?.parent}")
Log.i(TAG, "<---------内层LinearLayout addView after start----------->")
inflateLinearLayout?.forEach {
Log.i(TAG, "child = $it, child.layoutParams = ${it.layoutParams}")
}
Log.i(TAG, "<---------内层LinearLayout addView after end----------->")
}
}
2024-05-16 21:01:34.611 23963-23963 Yang I rootLinearLayout = android.widget.LinearLayout{ff5db0c V.E...... ......ID 0,0-0,0 #7f0a03cf app:id/root_ll}, rootLinearLayout?.layoutParams = android.widget.FrameLayout$LayoutParams@bb41c55, rootLinearLayout?.parent = androidx.appcompat.widget.ContentFrameLayout{b10266a V.E...... ......I. 0,0-0,0 #1020002 android:id/content}
2024-05-16 21:01:34.611 23963-23963 Yang I <---------最外层LinearLayout start----------->
2024-05-16 21:01:34.612 23963-23963 Yang I child = androidx.appcompat.widget.AppCompatTextView{190d75b V.ED..... ......ID 0,0-0,0 #7f0a03d2 app:id/root_tv}, child.layoutParams = android.widget.LinearLayout$LayoutParams@7ab9bf8
2024-05-16 21:01:34.612 23963-23963 Yang I <---------最外层LinearLayout end----------->
2024-05-16 21:01:34.612 23963-23963 Yang I addView before inflateLinearLayout = android.widget.LinearLayout{76728d1 V.E...... ......ID 0,0-0,0 #7f0a01ca app:id/inflate_ll}, inflateLinearLayout?.layoutParams = android.widget.LinearLayout$LayoutParams@1fb8e37, inflateLinearLayout?.parent = null
2024-05-16 21:01:34.612 23963-23963 Yang I <---------内层LinearLayout addView before start----------->
2024-05-16 21:01:34.612 23963-23963 Yang I child = androidx.appcompat.widget.AppCompatTextView{2fa7fa4 V.ED..... ......ID 0,0-0,0 #7f0a01cb app:id/inflate_tv}, child.layoutParams = android.widget.LinearLayout$LayoutParams@464810d
2024-05-16 21:01:34.612 23963-23963 Yang I <---------内层LinearLayout addView before end----------->
2024-05-16 21:01:34.613 23963-23963 Yang I addView after inflateLinearLayout = android.widget.LinearLayout{76728d1 V.E...... ......ID 0,0-0,0 #7f0a01ca app:id/inflate_ll}, inflateLinearLayout?.layoutParams = android.widget.LinearLayout$LayoutParams@1fb8e37, inflateLinearLayout?.parent = android.widget.LinearLayout{ff5db0c V.E...... ......ID 0,0-0,0 #7f0a03cf app:id/root_ll}
2024-05-16 21:01:34.613 23963-23963 Yang I <---------内层LinearLayout addView after start----------->
2024-05-16 21:01:34.613 23963-23963 Yang I child = androidx.appcompat.widget.AppCompatTextView{2fa7fa4 V.ED..... ......ID 0,0-0,0 #7f0a01cb app:id/inflate_tv}, child.layoutParams = android.widget.LinearLayout$LayoutParams@464810d
2024-05-16 21:01:34.613 23963-23963 Yang I <---------内层LinearLayout addView after end----------->
- 未通过
ViewGroup.addView()
添加的ViewGroup
因为LayoutInflater.inflate()
传入了root!=null
参数,其LayoutParams
不为null
,但是因为传入了attachRoot==false
参数,要填充的布局不会显示,需要使用ViewGroup.addView()
方法要填充的布局R.layout.inflate_layout
才能显示到根布局R.layout.activity_main
中
如果root!=null
,attachRoot==true
class MainActivity : AppCompatActivity() {
var rootLinearLayout : LinearLayout ?= null
var inflateLinearLayout : LinearLayout ?= null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
rootLinearLayout = findViewById(R.id.root_ll)
inflateLinearLayout = layoutInflater.inflate(R.layout.inflate_layout, rootLinearLayout, true) as? LinearLayout
Log.i(TAG, "rootLinearLayout = ${rootLinearLayout}, rootLinearLayout?.layoutParams = ${rootLinearLayout?.layoutParams}, rootLinearLayout?.parent = ${rootLinearLayout?.parent}")
Log.i(TAG, "<---------最外层LinearLayout start----------->")
rootLinearLayout?.forEach {
Log.i(TAG, "child = $it, child.layoutParams = ${it.layoutParams}")
}
Log.i(TAG, "<---------最外层LinearLayout end----------->")
Log.i(TAG, "addView before inflateLinearLayout = ${inflateLinearLayout}, inflateLinearLayout?.layoutParams = ${inflateLinearLayout?.layoutParams}, inflateLinearLayout?.parent = ${inflateLinearLayout?.parent}")
Log.i(TAG, "<---------内层LinearLayout start----------->")
inflateLinearLayout?.forEach {
Log.i(TAG, "child = $it, child.layoutParams = ${it.layoutParams}")
}
Log.i(TAG, "<---------内层LinearLayout end----------->")
}
}
2024-05-16 21:14:32.730 24204-24204 Yang I rootLinearLayout = android.widget.LinearLayout{f4b682d V.E...... ......ID 0,0-0,0 #7f0a03cf app:id/root_ll}, rootLinearLayout?.layoutParams = android.widget.FrameLayout$LayoutParams@ca74162, rootLinearLayout?.parent = androidx.appcompat.widget.ContentFrameLayout{ceee2f3 V.E...... ......I. 0,0-0,0 #1020002 android:id/content}
2024-05-16 21:14:32.730 24204-24204 Yang I <---------最外层LinearLayout start----------->
2024-05-16 21:14:32.730 24204-24204 Yang I child = androidx.appcompat.widget.AppCompatTextView{5cedbb0 V.ED..... ......ID 0,0-0,0 #7f0a03d2 app:id/root_tv}, child.layoutParams = android.widget.LinearLayout$LayoutParams@a235a29
2024-05-16 21:14:32.730 24204-24204 Yang I child = android.widget.LinearLayout{b3c11ae V.E...... ......ID 0,0-0,0 #7f0a01ca app:id/inflate_ll}, child.layoutParams = android.widget.LinearLayout$LayoutParams@8abb4f
2024-05-16 21:14:32.730 24204-24204 Yang I <---------最外层LinearLayout end----------->
2024-05-16 21:14:32.731 24204-24204 Yang I addView before inflateLinearLayout = android.widget.LinearLayout{f4b682d V.E...... ......ID 0,0-0,0 #7f0a03cf app:id/root_ll}, inflateLinearLayout?.layoutParams = android.widget.FrameLayout$LayoutParams@ca74162, inflateLinearLayout?.parent = androidx.appcompat.widget.ContentFrameLayout{ceee2f3 V.E...... ......I. 0,0-0,0 #1020002 android:id/content}
2024-05-16 21:14:32.731 24204-24204 Yang I <---------内层LinearLayout start----------->
2024-05-16 21:14:32.731 24204-24204 Yang I child = androidx.appcompat.widget.AppCompatTextView{5cedbb0 V.ED..... ......ID 0,0-0,0 #7f0a03d2 app:id/root_tv}, child.layoutParams = android.widget.LinearLayout$LayoutParams@a235a29
2024-05-16 21:14:32.731 24204-24204 Yang I child = android.widget.LinearLayout{b3c11ae V.E...... ......ID 0,0-0,0 #7f0a01ca app:id/inflate_ll}, child.layoutParams = android.widget.LinearLayout$LayoutParams@8abb4f
2024-05-16 21:14:32.731 24204-24204 Yang I <---------内层LinearLayout end----------->
- 未通过
ViewGroup.addView()
添加的ViewGroup
因为LayoutInflater.inflate()
传入了root!=null
参数,其LayoutParams
不为null
,传入了attachRoot==true
参数,要填充的布局会直接显示,不需要使用ViewGroup.addView()
方法手动添加