Android 约束布局-具有最大宽度的两个视图
我想创建一个布局(使用约束布局),如下所示: 在不同的语言中,Button1可能比button2大。我该怎么做 我只能在包含两个按钮的约束内使用LinearLayout来实现这一点,但我尝试只使用布局Android 约束布局-具有最大宽度的两个视图,android,android-layout,android-constraintlayout,Android,Android Layout,Android Constraintlayout,我想创建一个布局(使用约束布局),如下所示: 在不同的语言中,Button1可能比button2大。我该怎么做 我只能在包含两个按钮的约束内使用LinearLayout来实现这一点,但我尝试只使用布局 谢谢根据我对您问题的理解,下面的代码将帮助您 <?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://sche
谢谢根据我对您问题的理解,下面的代码将帮助您
<?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">
<TextView
android:id="@+id/text1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello world"
app:layout_constraintBottom_toTopOf="@+id/text2"
app:layout_constraintVertical_chainStyle="packed"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/text2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello world"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/text1" />
</androidx.constraintlayout.widget.ConstraintLayout>
更新 我想提到的是,Remq的答案是有效的,它绕过了我在下面提到的自参考问题,即视图的宽度是由使用相同视图作为参考id的屏障的位置决定的。关键似乎是两个视图的
app:layout\u constraintWidth\u min=“wrap”
规范。我不清楚为什么会这样,或者它会继续工作,但我想把它记下来
更新#2
我又看了一眼为什么Remq的答案有效。我的经验是,如果不为视图指定app:layout\u constraintWidth\u min=“wrap”
,两个视图都会折叠为零宽度。一旦视图测量为零宽度,app:layout\u constraintWidth\u min=“wrap”
将再次增长视图,以便包装内容。这正是我的猜测,没有证据表明这是正在发生的事情,但这是有道理的
我在堆栈溢出上多次看到类似于此的问题。这些问题在IMO(包括我已经回答的问题)中从来没有令人满意的答案。困难在于存在依赖性问题,因为一个视图取决于另一个视图的宽度,而另一个视图取决于第一个视图的宽度。我们陷入了一个参考的两难境地。(以编程方式强制宽度始终是一个选项,但似乎不可取。) 另一种可能更好的方法是使用自定义约束器,该约束器将检查引用视图的大小,并将所有视图的宽度调整为最大视图的宽度 自定义约束器放置在布局的XML中,并参照以下示例布局中受影响的视图: 主要活动
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:gravity="center"
android:text="Button1"
app:layout_constraintBottom_toTopOf="@+id/button2"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="packed" />
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="Button2 may be larger"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.498"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/button1" />
<com.example.constraintlayoutlayer.GreatestWidthHelper
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:constraint_referenced_ids="button1,button2"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
布局显示如下所示
我偶然发现了这个问题,并能够使用约束布局的
1.1.0-beta1
中引入的androidx.constraintlayout.widget.Barrier
解决它。因此,我认为与遇到同样问题的人分享是件好事:
无法将它们水平居中,因此如果有人发现了这一点,我将更新此示例。发布适用于linearlayout的xml!!我会帮你把它转换成你的。谢谢!但是,在ContrainLayout轻松支持之前,我将使用LinearLayout解决方案。@Mateu LinearLayout解决方案是可以接受的(IMO),但有些人会反对离开平面布局。保存了我的day mate!!
class GreatestWidthHelper @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : ConstraintHelper(context, attrs, defStyleAttr) {
override fun updatePostMeasure(container: ConstraintLayout) {
var maxWidth = 0
// Find the greatest width of the referenced widgets.
for (i in 0 until this.mCount) {
val id = this.mIds[i]
val child = container.getViewById(id)
val widget = container.getViewWidget(child)
if (widget.width > maxWidth) {
maxWidth = widget.width
}
}
// Set the width of all referenced view to the width of the view with the greatest width.
for (i in 0 until this.mCount) {
val id = this.mIds[i]
val child = container.getViewById(id)
val widget = container.getViewWidget(child)
if (widget.width != maxWidth) {
widget.width = maxWidth
// Fix the gravity.
if (child is TextView && child.gravity != Gravity.NO_GRAVITY) {
// Just toggle the gravity to make it right.
child.gravity = child.gravity.let { gravity ->
child.gravity = Gravity.NO_GRAVITY
gravity
}
}
}
}
}
}