前言
大部分時(shí)候,我們是在 xml 文件中創(chuàng)建視圖和布局的,但有些時(shí)候我們不得不在代碼中動(dòng)態(tài)創(chuàng)建視圖并顯示。
動(dòng)態(tài)創(chuàng)建視圖
動(dòng)態(tài)創(chuàng)建視圖有幾種情況,一種是利用 xml 中的容器,往里面添加 view ,第二種是沒有 xml 文件,一切需要用代碼創(chuàng)建,第三種是 xml 文件中保存的是具體的 ImageView , Button , TextView 之類的控件 ,我們需要將其解析成 view 并加到界面上去。
1.xml中有容器的情況下
首先是要在 xml 中有根容器
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:id="@+id/root"
android:layout_height="match_parent">
</androidx.constraintlayout.widget.ConstraintLayout>
然后在代碼中添加下面這些
//首先創(chuàng)建一個(gè)ImageView
val imageView = ImageView(this).apply {
//在創(chuàng)建ImageView的同時(shí),設(shè)置它所要顯示的圖片
setImageResource(R.drawable.ic_launcher_foreground)
}
//設(shè)置控件的必要參數(shù),參數(shù)都是在這里設(shè)置
val layoutParams = ConstraintLayout.LayoutParams(
//設(shè)置寬高為300px
300,300
).apply {
/**設(shè)置layoutParams的同時(shí)
* 將它相對(duì)于父容器的位置確定
*/
startToStart = R.id.root
endToEnd = R.id.root
topToTop = R.id.root
bottomToBottom = R.id.root
}
//最后將這個(gè)視圖添加到容器中
val root = findViewById<ConstraintLayout>(R.id.root)
root.addView(imageView,layoutParams)
2.沒有xml文件時(shí)
用代碼動(dòng)態(tài)創(chuàng)建視圖時(shí),我們有時(shí)是沒有xml文件的,那么在Activity的 onCreate() 方法中的 setContentView() 中,需要與綁定的就不再是 xml 文件了,而是我們自己創(chuàng)建的容器。
a.首先需要在 values 文件下新建一個(gè) id.xml 文件用來儲(chǔ)存各種 id
<?xml version="1.0" encoding="utf-8" ?>
<resources>
<item name="root_id" type="id"/>
</resources>
b.在代碼中添加一個(gè)容器,并與 Activity 綁定
//因?yàn)槭歉萜?,它自?dòng)填滿整個(gè)屏幕
val constraintLayout = ConstraintLayout(this).apply {
id = R.id.root_id
}
setContentView(constraintLayout)
c.向根容器中添加子控件
//這里的方式就和第一種創(chuàng)建視圖的代碼一致
val view = View(this).apply {
setBackgroundColor(Color.BLACK)
}
val constraintLayoutParams = ConstraintLayout.LayoutParams(
100,100
).apply {
startToStart = R.id.root_id
endToEnd = R.id.root_id
topToTop = R.id.root_id
bottomToBottom = R.id.root_id
}
constraintLayout.addView(view,constraintLayoutParams)
}
3.xml中保存的是獨(dú)立的view時(shí)
當(dāng)xml文件中是一個(gè)個(gè)獨(dú)立的 view 時(shí),如:
//這個(gè)xml文件名叫作 activity_main.xml
//這樣的好處是可以在xml中直觀方便的設(shè)置一些屬性
<?xml version="1.0" encoding="utf-8"?>
<View xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:id="@+id/root"
android:background="@color/purple_700"
android:layout_marginStart="20dp"
android:layout_marginEnd="20dp"
android:layout_height="match_parent"/>
接著在 Activity 中將這個(gè) xml 文件中解析成 view,并設(shè)置一些布局參數(shù),最后將其添加進(jìn)容器中。
a.將 xml 解析成 view
//將xml中的控件加到容器中
//LayoutInflater這個(gè)類的功能就是將xml轉(zhuǎn)化為view
//可以用 val inflater = LayoutInflater.from(this) 得到inflater
//但是kotlin已經(jīng)給我們提供了這個(gè)inflater(其實(shí)內(nèi)部也是調(diào)用上面的方法得到的)
//因此我們能直接用這個(gè)layoutInflater
val view = layoutInflater.inflate (
R.layout.activity_main,
constraintLayout,
false
)
inflater() 方法中有三個(gè)參數(shù),分別是控件的 布局資源文件,容器,是否將此控件綁定到容器上,我們通常寫 false ,因?yàn)榻壎ㄖ笪恢檬窍到y(tǒng)默認(rèn)的,通常在容器中的位置不是我們預(yù)想中的位置,我們還需要給其加一些布局參數(shù)。
b.添加布局參數(shù),并添加到容器中
//這些代碼同樣和前面一致
val constraintLayoutParams = ConstraintLayout.LayoutParams(
100,100
).apply {
startToStart = R.id.root_id
endToEnd = R.id.root_id
topToTop = R.id.root_id
bottomToBottom = R.id.root_id
}
constraintLayout.addView(view,constraintLayoutParams)