如何在Android View中实现指定的多ImageView与TextView复杂布局(无需自定义View)
不用自定义View也能搞定这个Android布局!
嘿,完全不用搞自定义View,咱们用ConstraintLayout就能完美实现你要的布局,它的灵活性刚好能满足所有约束条件。先理清楚咱们的核心需求:
- 4个ImageView(IV1-IV4):至少显示1个,所有显示的ImageView宽高完全一致
- 3个TextView(TV1-TV3):必须显示,且每个TextView的高度都要和ImageView相同
- 布局分为三行:顶部行(IV1+TV1+IV2)、中间行(TV2)、底部行(IV3+TV3+IV4)
下面是完整的布局代码,我会逐部分解释怎么满足你的要求:
<?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:layout_width="match_parent" android:layout_height="match_parent" android:padding="10dp"> <!-- 顶部行:IV1 + TV1 + IV2 --> <ImageView android:id="@+id/iv_top_left" android:layout_width="60dp" android:layout_height="60dp" android:src="@drawable/ic_launcher_background" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent"/> <TextView android:id="@+id/tv_top" android:layout_width="0dp" android:layout_height="0dp" android:text="@string/lorem_ipsum" android:gravity="center" android:paddingHorizontal="4dp" app:layout_constraintTop_toTopOf="@id/iv_top_left" app:layout_constraintBottom_toBottomOf="@id/iv_top_left" app:layout_constraintStart_toEndOf="@id/iv_top_left" app:layout_constraintEnd_toStartOf="@id/iv_top_right"/> <ImageView android:id="@+id/iv_top_right" android:layout_width="60dp" android:layout_height="60dp" android:src="@drawable/ic_launcher_background" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="@id/iv_top_left"/> <!-- 中间行:TV2 --> <TextView android:id="@+id/tv_middle" android:layout_width="match_parent" android:layout_height="0dp" android:text="@string/lorem_ipsum" android:gravity="center" android:layout_marginVertical="10dp" app:layout_constraintHeight_toEqual="@id/iv_top_left" app:layout_constraintTop_toBottomOf="@id/iv_top_left"/> <!-- 底部行:IV3 + TV3 + IV4 --> <ImageView android:id="@+id/iv_bottom_left" android:layout_width="60dp" android:layout_height="60dp" android:src="@drawable/ic_launcher_background" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/tv_middle"/> <TextView android:id="@+id/tv_bottom" android:layout_width="0dp" android:layout_height="0dp" android:text="@string/lorem_ipsum" android:gravity="center" android:paddingHorizontal="4dp" app:layout_constraintTop_toTopOf="@id/iv_bottom_left" app:layout_constraintBottom_toBottomOf="@id/iv_bottom_left" app:layout_constraintStart_toEndOf="@id/iv_bottom_left" app:layout_constraintEnd_toStartOf="@id/iv_bottom_right"/> <ImageView android:id="@+id/iv_bottom_right" android:layout_width="60dp" android:layout_height="60dp" android:src="@drawable/ic_launcher_background" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="@id/iv_bottom_left"/> </androidx.constraintlayout.widget.ConstraintLayout>
怎么满足你的所有约束?
ImageView可选(至少1个可见):
如果你需要隐藏某个ImageView,只需要在代码里设置iv_top_left.setVisibility(View.GONE),ConstraintLayout会自动调整相邻TextView的布局,完全不用修改xml结构。哪怕只留一个ImageView,布局也能正常显示。TextView必填:
所有TextView在布局里都默认保留,不会设置gone,满足必填要求。所有ImageView宽高完全相同:
我给所有ImageView设置了固定的60dp宽高,你也可以用比例(比如app:layout_constraintDimensionRatio="1:1")配合0dp宽度,让它们自适应父容器的同时保持正方形,只要所有ImageView的尺寸规则一致就行。TextView高度与ImageView匹配:
- 顶部和底部的TextView(TV1、TV3)通过
app:layout_constraintTop_toTopOf和app:layout_constraintBottom_toBottomOf绑定到对应的ImageView,高度自动和ImageView一致。 - 中间的TextView(TV2)用
app:layout_constraintHeight_toEqual="@id/iv_top_left"直接绑定到ImageView的高度,保证和ImageView一样高。
- 顶部和底部的TextView(TV1、TV3)通过
额外优化点
- 如果你的ImageView需要自适应不同屏幕尺寸,可以把固定的
60dp换成wrap_content,然后用app:layout_constraintDimensionRatio="1:1"保证正方形,同时给TextView设置相同的高度约束,效果一样。 - 可以给ImageView设置
app:layout_constraintWidth_percent(比如0.15)来让它们占父容器宽度的固定比例,这样在不同屏幕上的显示比例更一致。
这样就完全不用自定义View,用系统自带的ConstraintLayout就能实现你想要的布局啦!
内容的提问来源于stack exchange,提问作者Hector
相关产品推荐
相关产品推荐

