Reputation: 1971
I'm trying to create a view which contains a variable number of views evenly spread horizontally.
I think the best option is a ConstraintLayout
, however I tried implementing this on a clean project:
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)
}
but this gives me the following result:
I expect an horizontal chain like this:
Note that the ImageView
s are all correctly drawn, they're just all in the same spot.
From the debug, I can see that the constraints in the set
are all correct (first view is connected to parent and second view, second view to first and third and so on...). Also, the ConstraintLayout is correctly stretching to the whole screen width, so the views should fit.
I also tried to manually assign constraints to each view and I got the same result.
What am I missing here?
Upvotes: 1
Views: 463
Reputation: 62851
There may be other problems, but one issue that your code has is that it shares one set of layout params among the views. Each view needs its own set of layout params to store its layout constraints. Move
val viewLp =
ConstraintLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT)
inside the repeat(6)
loop and you will get a better result.
Upvotes: 2