Android: ConstraintLayout: createHorizontalChain() 不工作
Android: ConstraintLayout: createHorizontalChain() not working
我正在尝试创建一个视图,其中包含水平均匀分布的可变数量的视图。
我认为最好的选择是 ConstraintLayout
,但是我尝试在一个干净的项目上实现它:
fragment.xml:
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".FirstFragment">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/cl"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
myFragment.kt:
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
container = view.findViewById(R.id.cl)
buildViews()
}
private val views = mutableListOf<AppCompatImageView>()
private lateinit var container: ConstraintLayout
private fun buildViews() {
val viewLp =
ConstraintLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT)
repeat(6) {
val view = AppCompatImageView(context)
//I used a random vector drawable here
view.setImageDrawable(ContextCompat.getDrawable(requireContext(), R.drawable.ic_baseline_account_circle_10))
view.layoutParams = viewLp
view.id = RelativeLayout.generateViewId()
container.addView(view)
views.add(view)
}
val set = ConstraintSet()
set.clone(container)
val ids = views.mapTo(mutableListOf(), { it.id }).toIntArray()
set.createHorizontalChain(
ConstraintSet.PARENT_ID,
ConstraintSet.LEFT,
ConstraintSet.PARENT_ID,
ConstraintSet.RIGHT,
ids,
null,
ConstraintSet.CHAIN_SPREAD
)
set.applyTo(container)
}
但这给了我以下结果:
我期待这样的水平链:
请注意 ImageView
都已正确绘制,它们都在同一个位置。
从调试中,我可以看到 set
中的约束都是正确的(第一个视图连接到父视图和第二个视图,第二个视图连接到第一个和第三个等等......)。此外,ConstraintLayout 正确地拉伸到整个屏幕宽度,因此视图应该适合。
我也尝试手动为每个视图分配约束,但我得到了相同的结果。
我在这里错过了什么?
可能还有其他问题,但您的代码存在的一个问题是它在视图之间共享一组布局参数。每个视图都需要自己的一组布局参数来存储其布局约束。移动
val viewLp =
ConstraintLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT)
在repeat(6)
循环中,你会得到更好的结果。
我正在尝试创建一个视图,其中包含水平均匀分布的可变数量的视图。
我认为最好的选择是 ConstraintLayout
,但是我尝试在一个干净的项目上实现它:
fragment.xml:
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".FirstFragment">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/cl"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
myFragment.kt:
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
container = view.findViewById(R.id.cl)
buildViews()
}
private val views = mutableListOf<AppCompatImageView>()
private lateinit var container: ConstraintLayout
private fun buildViews() {
val viewLp =
ConstraintLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT)
repeat(6) {
val view = AppCompatImageView(context)
//I used a random vector drawable here
view.setImageDrawable(ContextCompat.getDrawable(requireContext(), R.drawable.ic_baseline_account_circle_10))
view.layoutParams = viewLp
view.id = RelativeLayout.generateViewId()
container.addView(view)
views.add(view)
}
val set = ConstraintSet()
set.clone(container)
val ids = views.mapTo(mutableListOf(), { it.id }).toIntArray()
set.createHorizontalChain(
ConstraintSet.PARENT_ID,
ConstraintSet.LEFT,
ConstraintSet.PARENT_ID,
ConstraintSet.RIGHT,
ids,
null,
ConstraintSet.CHAIN_SPREAD
)
set.applyTo(container)
}
但这给了我以下结果:
我期待这样的水平链:
请注意 ImageView
都已正确绘制,它们都在同一个位置。
从调试中,我可以看到 set
中的约束都是正确的(第一个视图连接到父视图和第二个视图,第二个视图连接到第一个和第三个等等......)。此外,ConstraintLayout 正确地拉伸到整个屏幕宽度,因此视图应该适合。
我也尝试手动为每个视图分配约束,但我得到了相同的结果。
我在这里错过了什么?
可能还有其他问题,但您的代码存在的一个问题是它在视图之间共享一组布局参数。每个视图都需要自己的一组布局参数来存储其布局约束。移动
val viewLp =
ConstraintLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT)
在repeat(6)
循环中,你会得到更好的结果。