【问题标题】:How can I use ConstraintLayout to have the first View shrink to fit remaining space?如何使用 ConstraintLayout 让第一个 View 缩小以适应剩余空间?
【发布时间】:2019-10-15 15:01:19
【问题描述】:

我有以下布局。注意Z 位于Y 下方,但被限制在底部。 YZ 之间有一个很好的间隙,这是由多余的垂直空间提供的。这是我的期望实际在存在多余的垂直空间时的行为。

但是,当显示键盘时,我用完了多余的垂直空间。

期望的行为(没有多余的垂直空间)当我用完垂直空间时,我希望发生以下情况:X (ScrollView),缩小以填充剩余空间,允许YZ 以全尺寸显示。

实际行为(没有多余的垂直空间) Y 反而缩小了。

我的来源如下。如何修改它以在两种情况下都获得我想要的行为(多余的垂直空间和没有多余的垂直空间)?

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

    <ScrollView
        android:id="@+id/scrollView"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="#fbe9e7"
            android:gravity="center"
            android:text="X"
            android:textSize="96sp">

        </TextView>
    </ScrollView>

    <TextView
        android:id="@+id/text_Y"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#f3e5f5"
        android:gravity="center"
        android:text="Y"
        android:textSize="96sp"
        app:layout_constraintTop_toBottomOf="@+id/scrollView" />

    <TextView
        android:id="@+id/text_Z"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#e1f5fe"
        android:gravity="center"
        android:text="Z"
        android:textSize="96sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/text_Y"
        app:layout_constraintVertical_bias="1" />

</androidx.constraintlayout.widget.ConstraintLayout>

问题主要源于X 滚动视图在垂直空间有限时需要为0dp,但在垂直空间过多时需要为wrap_content

注意:您可以通过在 Android Studio 中的布局的预览窗格中相应地拖动右下角来演示布局在较少垂直空间的情况下的行为

【问题讨论】:

  • @Racu 抱歉,我认为我的来源格式不正确

标签: android android-layout android-constraintlayout


【解决方案1】:

试试这个

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

    <ScrollView
        android:id="@+id/scrollView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constrainedHeight="true"
        app:layout_constraintBottom_toTopOf="@+id/text_Y"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0"
        app:layout_constraintVertical_chainStyle="packed">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="#fbe9e7"
            android:gravity="center"
            android:text="X"
            android:textSize="96sp">

        </TextView>
    </ScrollView>

    <TextView
        android:id="@+id/text_Y"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#f3e5f5"
        android:gravity="center"
        android:text="Y"
        android:textSize="96sp"
        app:layout_constraintBottom_toTopOf="@+id/text_Z"
        app:layout_constraintTop_toBottomOf="@+id/scrollView"
        app:layout_constraintVertical_bias="0" />

    <TextView
        android:id="@+id/text_Z"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#e1f5fe"
        android:gravity="center"
        android:text="Z"
        android:textSize="96sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

【讨论】:

    【解决方案2】:

    我会推荐一个障碍约束: https://developer.android.com/reference/android/support/constraint/Barrier

    您将有两个底部视图的顶部,Z 和一个从父底部到 Y 底部的空视图。

    <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">
    
    <ScrollView
        android:id="@+id/scrollView"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">
    
        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="#fbe9e7"
            android:gravity="center"
            android:text="X"
            android:textSize="96sp">
    
        </TextView>
    </ScrollView>
    
    <TextView
        android:id="@+id/text_Y"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#f3e5f5"
        android:gravity="center"
        android:text="Y"
        android:textSize="96sp"
        app:layout_constraintTop_toBottomOf="@+id/scrollView" 
        app:layout_constraintBottom_topTopOf="@+barrier_bottom"/>
    
    <androidx.constraintlayout.widget.Barrier
                android:id="@+id/barrier_bottom"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                app:barrierDirection="bottom"
                app:constraint_referenced_ids="text_Z,spacer" />
    
    <TextView
        android:id="@+id/spacer
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_constraintTop_topBottomOf="@+id/text_Y"
        app:layout_constraintBottom_toBottomOf="parent"/>
    
    <TextView
        android:id="@+id/text_Z"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#e1f5fe"
        android:gravity="center"
        android:text="Z"
        android:textSize="96sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintVertical_bias="1" />
    
    </androidx.constraintlayout.widget.ConstraintLayout>
    

    【讨论】:

    • 不幸的是,这展示了与上述实际行为相同的行为,而不是在没有多余垂直空间时的期望行为
    • 好的。我会再考虑一下。
    【解决方案3】:

    就我自己的解决方案测试而言,我发现无法实现您想要的行为。我花了大约 2 个小时将不同的链变体和另一个 ConstraintLayout 东西结合起来。 这是我唯一可能的解决方案。调整大小后的 TextY 和 TextZ 保持完全可见,但 TextX 不会调整大小保持相同的高度并隐藏在 TextY 后面。

    解决方案本身:

    <?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">
    
        <ScrollView
            android:id="@+id/scrollView"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent">
    
            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="#fbe9e7"
                android:gravity="center"
                android:text="X"
                android:textSize="96sp">
    
            </TextView>
        </ScrollView>
    
        <TextView
            android:id="@+id/text_Y"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="#f3e5f5"
            android:gravity="center"
            android:text="Y"
            android:textSize="96sp"
            app:layout_constraintBottom_toTopOf="@id/text_Z"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/scrollView"
            app:layout_constraintVertical_bias="1"
            app:layout_constraintVertical_chainStyle="spread_inside" />
    
        <TextView
            android:id="@+id/text_Z"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="#e1f5fe"
            android:gravity="center"
            android:text="Z"
            android:textSize="96sp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/text_Y" />
    
    </androidx.constraintlayout.widget.ConstraintLayout>
    
    

    【讨论】:

      【解决方案4】:

      下面的代码可以按照您的预期工作,并已亲自测试过。值得注意的是,您想要的行为,即当 text_y 开始重叠时更改其大小的滚动视图,仅通过单个约束布局无法实现,因此我将 text_y 和 text_z 放在另一个约束布局中。

      <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">
      
          <ScrollView
              android:id="@+id/scrollView"
              android:layout_width="match_parent"
              android:layout_height="0dp"
              app:layout_constraintHeight_max="wrap"
              app:layout_constraintBottom_toTopOf="@id/constraint"
              app:layout_constraintTop_toTopOf="parent"
              app:layout_constraintVertical_chainStyle="spread_inside"
              app:layout_constraintVertical_bias="0">
      
              <TextView
                  android:layout_width="match_parent"
                  android:layout_height="match_parent"
                  android:background="#fbe9e7"
                  android:gravity="center"
                  android:text="X"
                  android:textSize="96sp">
      
              </TextView>
          </ScrollView>
      
          <androidx.constraintlayout.widget.ConstraintLayout
              android:id="@+id/constraint"
              android:layout_width="match_parent"
              android:layout_height="0dp"
              app:layout_constraintHeight_min="wrap"
              app:layout_constraintTop_toBottomOf="@id/scrollView"
              app:layout_constraintBottom_toBottomOf="parent">  
              <TextView
                  android:id="@+id/text_Y"
                  android:layout_width="match_parent"
                  android:layout_height="wrap_content"
                  android:background="#f3e5f5"
                  android:gravity="center"
                  android:text="Y"
                  android:textSize="96sp"
                  app:layout_constraintVertical_chainStyle="spread_inside"
                  app:layout_constraintTop_toTopOf="parent"
                  app:layout_constraintBottom_toTopOf="@id/text_Z"/>
      
              <TextView
                  android:id="@+id/text_Z"
                  android:layout_width="match_parent"
                  android:layout_height="wrap_content"
                  android:background="#e1f5fe"
                  android:gravity="center"
                  android:text="Z"
                  android:textSize="96sp"
                  app:layout_constraintTop_toBottomOf="@id/text_Y"
                  app:layout_constraintBottom_toBottomOf="parent"/>
          </androidx.constraintlayout.widget.ConstraintLayout>
      
      
      </androidx.constraintlayout.widget.ConstraintLayout>
      

      【讨论】:

        猜你喜欢
        • 2013-11-19
        • 2011-09-13
        • 2020-12-20
        • 2011-04-10
        • 2018-04-10
        • 2019-01-19
        • 2013-06-18
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多