我有一個GridLayout應該顯示 25 個均勻間隔的按鈕。為了能夠在onClickListener不呼叫每個人的情況下設定一個,我想以編程方式做到這一點。我用網格本身制作了一個布局資源檔案來系結它并能夠膨脹它
activity.xml
<?xml version="1.0" encoding="utf-8"?>
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:grid="http://schemas.android.com/apk/res-auto"
android:id="@ id/bingo_grid"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerHorizontal="true"
android:columnCount="5"
android:rowCount="5"
tools:context=".BingoActivity" />
現在我正在創建欄位:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val bingoField = (1).rangeTo(25).toSet().toIntArray()
binding = BingoActivityBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.bingoGrid.alignmentMode = GridLayout.ALIGN_BOUNDS
val bingoFieldGrid = binding.bingoGrid
bingoFieldGrid.alignmentMode = GridLayout.ALIGN_BOUNDS
bingoField.forEach {
val button = createButton(it.toString())
val gridLayoutParams = GridLayout.LayoutParams().apply {
rowSpec = spec(GridLayout.UNDEFINED, GridLayout.CENTER, 1f)
columnSpec = spec(GridLayout.UNDEFINED, GridLayout.CENTER, 1f)
height = GridLayout.LayoutParams.WRAP_CONTENT
width = GridLayout.LayoutParams.WRAP_CONTENT
}
bingoFieldGrid.addView(button, gridLayoutParams)
}
@RequiresApi(Build.VERSION_CODES.M)
private fun createButton(buttonText: String): Button {
var isCompleted = false
return Button(baseContext).apply {
setBackgroundColor(getColor(R.color.red))
gravity = Gravity.CENTER
text = buttonText
setOnClickListener {
isCompleted = if (!isCompleted) {
setBackgroundColor(getColor(R.color.green))
true
} else {
setBackgroundColor(getColor(R.color.red))
false
}
}
}
}
因此,這些欄位是自動生成的,沒有問題,但間距不正確:

我對舊的布局很陌生,有沒有辦法輕松實作?
uj5u.com熱心網友回復:
您正在創建兩種不同型別的 LayoutParams,這是沒有意義的。根本不應該涉及 LinearLayout。
他們的作業方式是每個孩子都應該獲得一組與其父 ViewGroup 使用的 LayoutParams 型別相匹配的 LayoutParams。所以在這種情況下,父節點是 GridLayout,所以每個子節點都應該使用 GridLayout.LayoutParams 的實體添加。
GridLayout.LayoutParams 的作業方式是定義一個行 Spec 和一個列 Spec 來描述子項應該如何占用單元格。我們希望它們采用單個下一個單元格,因此我們可以將第一個引數保留為 UNDEFINED。我們需要給它們一個weight大于 0的相等,以便它們都均勻地共享剩余空間。我是1f用來稱體重的。
我使用大小為 0 的 FILL 用于按鈕,以便它們填充它們的單元格。邊距在它們之間留下了一些差距。
我將高度和寬度設定為 0 以防止它們過大。如果行或列變得太大而無法適應螢屏,則布局會變得太大。
您可能想要使用 MaterialButton 而不是普通的 Button,這樣您就可以輕松地為背景顏色著色,而無需簡單地將其設為靜態純色矩形。
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = BingoBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.bingoGrid.alignmentMode = GridLayout.ALIGN_BOUNDS
for (num in 1..25) {
val button = MaterialButton(this).apply {
setBackgroundColor(resources.getColor(R.color.blue_500))
gravity = Gravity.CENTER
text = num.toString()
setPadding(0)
}
val params = GridLayout.LayoutParams().apply {
rowSpec = spec(GridLayout.UNDEFINED, GridLayout.FILL, 1f)
columnSpec = spec(GridLayout.UNDEFINED, GridLayout.FILL, 1f)
width = 0
height = 0
setMargins((4 * resources.displayMetrics.density).toInt())
}
binding.bingoGrid.addView(button, params)
}
}
AndroidStudio 對匯入spec函式很挑剔。我不得不在頂部手動添加:
import android.widget.GridLayout.Spec.*

uj5u.com熱心網友回復:
您可以考慮 Google ConstraintLayout Flows:
要設定元素的數量,請使用 app:flow_maxElementsWrap="5"
布局:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@ id/root"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.constraintlayout.helper.widget.Flow
android:id="@ id/flow"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:flow_horizontalGap="8dp"
app:flow_maxElementsWrap="5"
app:flow_verticalGap="8dp"
app:flow_verticalStyle="packed"
app:flow_wrapMode="chain" />
</androidx.constraintlayout.widget.ConstraintLayout>
然后以編程方式將按鈕添加到ConstraintLayout:
val root = findViewById<ViewGroup>(R.id.root)
val size = 25
val array = IntArray(size)
for (i in 0 until size) {
array[i] = i 1
val button = Button(this).apply {
layoutParams = ViewGroup.LayoutParams(0, 0)
id = i 1
text = (i 1).toString()
}
root.addView(button)
}
val flow = findViewById<Flow>(R.id.flow)
flow.referencedIds = array
提示:您可以使用WRAP_CONTENT按鈕高度來避免拉伸按鈕高度。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/371515.html
標籤:安卓 科特林 安卓布局 android-jetpack
下一篇:四分之一計數器(kotlin)
