如何在单个ConstraintLayout内实现CardView中3视图水平均匀分布?
问题
我使用了ConstraintLayout作为根布局,其中包含若干子视图,还有一个作为ConstraintLayout子视图的CardView。我希望在该CardView内水平均匀放置3个视图,且仅使用一个ConstraintLayout来保持扁平布局层级。我尝试过链式布局但未成功,请问是否可以实现?
原布局代码:
<androidx.constraintlayout.widget.ConstraintLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/black" android:padding="@dimen/padding_normal"> <com.google.android.material.imageview.ShapeableImageView android:id="@+id/profile_image" android:layout_width="84dp" android:layout_height="84dp" android:backgroundTint="@color/black" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" app:srcCompat="@drawable/ic_person" /> <TextView android:id="@+id/full_name" style="@style/Material.Headline6.Light" android:layout_width="wrap_content" android:layout_height="@dimen/none" app:layout_constraintStart_toEndOf="@id/profile_image" app:layout_constraintTop_toTopOf="parent" tools:text="Roger Mphile Nkosi" /> <TextView android:id="@+id/job_title" style="@style/Material.Subtitle1.Light" android:layout_width="wrap_content" android:layout_height="@dimen/none" app:layout_constraintStart_toEndOf="@id/profile_image" app:layout_constraintTop_toBottomOf="@id/full_name" tools:text="Android Developer" /> <androidx.cardview.widget.CardView app:layout_constraintTop_toBottomOf="@id/job_title" app:layout_constraintStart_toEndOf="@id/profile_image" android:layout_width="wrap_content" android:layout_height="wrap_content" > <TextView android:id="@+id/years_title" style="@style/Material.Caption.Light" android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintEnd_toStartOf="@+id/coffees_title" app:layout_constraintHorizontal_bias="0.5" app:layout_constraintHorizontal_chainStyle="spread" app:layout_constraintStart_toEndOf="@+id/profile_image" app:layout_constraintTop_toBottomOf="@id/job_title" tools:text="Years" /> <TextView android:id="@+id/coffees_title" style="@style/Material.Caption.Light" android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintEnd_toStartOf="@+id/bugs_title" app:layout_constraintHorizontal_bias="0.5" app:layout_constraintHorizontal_chainStyle="spread" app:layout_constraintStart_toEndOf="@+id/years_title" app:layout_constraintTop_toBottomOf="@id/job_title" app:layout_constraintVertical_chainStyle="packed" tools:text="Coffees" /> <TextView android:id="@+id/bugs_title" style="@style/Material.Caption.Light" android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.5" app:layout_constraintStart_toEndOf="@+id/coffees_title" app:layout_constraintTop_toBottomOf="@id/job_title" tools:text="Bugs" /> </androidx.cardview.widget.CardView> </androidx.constraintlayout.widget.ConstraintLayout>
解决方案
可以实现,问题出在你错误地将CardView内部的TextView约束到了外层布局的View,嵌套层级导致链式布局失效。要保持扁平层级,只需将三个TextView与CardView设为同级(都属于根ConstraintLayout的子View),通过约束让CardView作为三个TextView的背景容器,再对三个TextView设置水平链式布局即可。
关键调整点:
- 将三个TextView从CardView标签中移出,与CardView同级,避免嵌套布局
- 设置CardView的约束,使其自动包裹三个TextView的区域(宽度设为
0dp,匹配约束范围) - 对三个TextView设置水平链式布局,指定
spread风格实现均匀分布
修正后的布局代码:
<androidx.constraintlayout.widget.ConstraintLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/black" android:padding="@dimen/padding_normal"> <com.google.android.material.imageview.ShapeableImageView android:id="@+id/profile_image" android:layout_width="84dp" android:layout_height="84dp" android:backgroundTint="@color/black" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" app:srcCompat="@drawable/ic_person" /> <TextView android:id="@+id/full_name" style="@style/Material.Headline6.Light" android:layout_width="wrap_content" android:layout_height="@dimen/none" app:layout_constraintStart_toEndOf="@id/profile_image" app:layout_constraintTop_toTopOf="parent" tools:text="Roger Mphile Nkosi" /> <TextView android:id="@+id/job_title" style="@style/Material.Subtitle1.Light" android:layout_width="wrap_content" android:layout_height="@dimen/none" app:layout_constraintStart_toEndOf="@id/profile_image" app:layout_constraintTop_toBottomOf="@id/full_name" tools:text="Android Developer" /> <!-- CardView作为背景容器,与TextView同级 --> <androidx.cardview.widget.CardView android:layout_width="0dp" android:layout_height="wrap_content" app:layout_constraintBottom_toBottomOf="@+id/bugs_title" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toEndOf="@id/profile_image" app:layout_constraintTop_toBottomOf="@id/job_title" /> <!-- 三个TextView水平均匀分布 --> <TextView android:id="@+id/years_title" style="@style/Material.Caption.Light" android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintEnd_toStartOf="@+id/coffees_title" app:layout_constraintHorizontal_chainStyle="spread" app:layout_constraintStart_toEndOf="@id/profile_image" app:layout_constraintTop_toBottomOf="@id/job_title" tools:text="Years" /> <TextView android:id="@+id/coffees_title" style="@style/Material.Caption.Light" android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintEnd_toStartOf="@+id/bugs_title" app:layout_constraintStart_toEndOf="@+id/years_title" app:layout_constraintTop_toBottomOf="@id/job_title" tools:text="Coffees" /> <TextView android:id="@+id/bugs_title" style="@style/Material.Caption.Light" android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toEndOf="@+id/coffees_title" app:layout_constraintTop_toBottomOf="@id/job_title" tools:text="Bugs" /> </androidx.constraintlayout.widget.ConstraintLayout>
说明:
- CardView宽度设为
0dp,通过start/end约束匹配父布局右侧到profile_image右侧的区域,top/bottom约束自动包裹三个TextView的高度 - 三个TextView形成双向链式约束:
years_title的end连coffees_title的start,coffees_title的end连bugs_title的start;bugs_title的end连父布局end,years_title的start连profile_image的end,配合horizontal_chainStyle="spread"实现均匀分布 - 所有视图均属于根ConstraintLayout,保持了完全扁平的布局层级
内容的提问来源于stack exchange,提问作者Roger Nkosi
相关产品推荐
相关产品推荐

