constraint layout - Two views with largest width

前端 未结 3 1952
你的背包
你的背包 2021-01-03 08:46

I want to create a layout (using constraint layout) like the following:

In different languages Button1 may be larger than button2. How can I do this?

<
相关标签:
3条回答
  • 2021-01-03 08:56

    As per what I understand from your question, below code will help you.

    <?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>
    
    0 讨论(0)
  • 2021-01-03 08:58

    I have seen questions akin to this one on Stack Overflow a number of times. These questions never have a satisfactory answer IMO (including ones that I have answered.) The difficulty is that there is a dependency problem since one view depends on the width of another but that other view depends on the width of the first. We fall into a referential quandary. (Forcing widths programmatically is always an option but seems undesirable.)

    Another and, probably, better approach is to use a custom ConstraintHelper that will inspect the sizes of the referenced views and adjust the width of all views to the width of the largest.

    The custom ConstraintHelper is placed in the XML for the layout and references the effected views as in the following sample layout:

    activity_main

    <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>
    

    The custom ConstraintHelper looks like this:

    GreatestWidthHelper

    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
                        }
                    }
                }
            }
        }
    }
    

    The layout displays as shown below.

    0 讨论(0)
  • 2021-01-03 08:58

    I stumbled upon this question and was able to solve it with androidx.constraintlayout.widget.Barrier which were introduced in 1.1.0-beta1 of constraint layout. So I thought it'd be nice to share with people who run into the same issue:

    <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">
    
        <Button
            android:id="@+id/button1"
            android:layout_width="0dp"
            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="@id/barrierEnd"
            app:layout_constraintHorizontal_bias="1.0"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_chainStyle="packed"
            app:layout_constraintWidth_min="wrap" />
    
        <Button
            android:id="@+id/button2"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:text="Button2 may be larger"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="@id/barrierEnd"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@id/button1"
            app:layout_constraintWidth_min="wrap" />
    
        <androidx.constraintlayout.widget.Barrier
            android:id="@+id/barrierEnd"
            android:layout_width="0dp"
            android:layout_height="0dp"
            app:barrierDirection="end"
            app:constraint_referenced_ids="button1,button2"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
    
    </androidx.constraintlayout.widget.ConstraintLayout>
    

    Haven't been able to center them horizontally, so if someone figures that out I'll update this example.

    0 讨论(0)
提交回复
热议问题