如何在scrollview中制作嵌套约束布局以匹配主父布局的大小

时间:2019-10-22 12:04:07

标签: android android-studio android-constraintlayout android-scrollview

编辑:我想要的是用两个按钮使底部的红色部分占据屏幕底部的整个空间,当屏幕尺寸大于6.3时,顶部保持88dp的空白。 现在发生了什么:红色背景直到底部才占据空间(请参见屏幕截图)。我找不到使约束布局扩展的方法 我想在scrollView内使底部约束布局与父布局大小匹配,而不从底部创建任何间隙。这仅在6.3及更高尺寸的屏幕上发生

Here's a screenshot Sceenshot

我尝试使用两个按钮仅取出底部约束布局。它虽然可以解决问题,但在较小的屏幕尺寸下使视图更难看

<?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"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/ic_background"
    tools:context=".presentation.offers.OfferDetailsActiviy">

    <androidx.appcompat.widget.Toolbar
        android:id="@+id/toolbar_offer_details"
        style="@style/AppToolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        app:contentInsetStart="10dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:titleTextAppearance="@style/ToolbarTextAppearance.Title" />

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/toolbar_offer_details">

        <androidx.constraintlayout.widget.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <androidx.cardview.widget.CardView
                android:id="@+id/cardView_offer_details"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_marginStart="20dp"
                android:layout_marginTop="20dp"
                android:layout_marginEnd="20dp"
                app:cardCornerRadius="10dp"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent">

                <androidx.constraintlayout.widget.ConstraintLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content">

                    <ImageView
                        android:id="@+id/iv_offer_details_image"
                        android:layout_width="0dp"
                        android:layout_height="335dp"
                        android:background="@drawable/food_item_temp"
                        android:scaleType="centerCrop"
                        android:src="@drawable/bg_transparent_gradient"
                        app:layout_constraintBottom_toBottomOf="parent"
                        app:layout_constraintEnd_toEndOf="parent"
                        app:layout_constraintStart_toStartOf="parent"
                        app:layout_constraintTop_toTopOf="parent" />

                    <TextView
                        android:id="@+id/tv_offer_details_name"
                        style="@style/colorBlackTextStyle.size20"
                        android:layout_width="0dp"
                        android:layout_height="wrap_content"
                        android:layout_marginStart="12dp"
                        android:layout_marginTop="10dp"
                        android:fontFamily="@font/myraid_pro_bold"
                        android:text="Offer Name Here"
                        app:layout_constraintStart_toStartOf="@id/iv_offer_details_image"
                        app:layout_constraintTop_toTopOf="@id/iv_offer_details_image" />


                </androidx.constraintlayout.widget.ConstraintLayout>
            </androidx.cardview.widget.CardView>

            <TextView
                android:id="@+id/tv_offer_details_ends"
                style="@style/colorLightGrayTextStyle.size18"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_marginStart="20dp"
                android:layout_marginTop="15dp"
                android:fontFamily="@font/myraid_pro_semibold"
                android:text="@string/text_offer_ends"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toBottomOf="@+id/cardView_offer_details" />

            <TextView
                android:id="@+id/tv_offer_details_end_countdown"
                style="@style/colorBlackTextStyle.size20"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_marginStart="5dp"
                android:fontFamily="@font/myraid_pro_semibold"
                android:gravity="start"
                android:text="2 Days 10 Hours"
                app:layout_constraintBottom_toBottomOf="@+id/tv_offer_details_ends"
                app:layout_constraintStart_toEndOf="@+id/tv_offer_details_ends" />

            <TextView
                android:id="@+id/label_offer_details_terms"
                style="@style/colorBlackTextStyle.size16"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_marginStart="20dp"
                android:layout_marginTop="16dp"
                android:fontFamily="@font/myraid_pro_regular"
                android:gravity="start"
                android:text="@string/label_terms"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toBottomOf="@+id/tv_offer_details_ends" />

            <TextView
                android:id="@+id/tv_offer_details_terms"
                style="@style/colorBlackTextStyle.size16"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_marginStart="20dp"
                android:layout_marginTop="4dp"
                android:layout_marginEnd="20dp"
                android:fontFamily="@font/myraid_pro_regular"
                android:gravity="start"
                android:text="@string/description_offer_terms"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toBottomOf="@+id/label_offer_details_terms" />


            <androidx.constraintlayout.widget.ConstraintLayout
                android:id="@+id/layout"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_marginTop="88dp"
                android:background="@color/colorRed"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toBottomOf="@+id/tv_offer_details_terms">

                <Button
                    android:id="@+id/btn_redeem_at_cashier"
                    style="@style/PrimaryButtonStyle.padding4"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="15dp"
                    android:fontFamily="@font/myraid_pro_bold"
                    android:text="@string/action_redeem_at_cashier"
                    app:layout_constraintBottom_toTopOf="@+id/btn_redeem_and_order"
                    app:layout_constraintEnd_toEndOf="parent"
                    app:layout_constraintStart_toStartOf="parent"
                    app:layout_constraintTop_toTopOf="parent"
                    app:layout_constraintVertical_chainStyle="packed" />

                <Button
                    android:id="@+id/btn_redeem_and_order"
                    style="@style/PrimaryButtonStyle.padding4"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="16dp"
                    android:layout_marginBottom="16dp"
                    android:fontFamily="@font/myraid_pro_bold"
                    android:text="@string/action_redeem_and_order"
                    app:layout_constraintBottom_toBottomOf="parent"
                    app:layout_constraintEnd_toEndOf="parent"
                    app:layout_constraintStart_toStartOf="parent"
                    app:layout_constraintTop_toBottomOf="@+id/btn_redeem_at_cashier" />

            </androidx.constraintlayout.widget.ConstraintLayout>

        </androidx.constraintlayout.widget.ConstraintLayout>

    </ScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>

2 个答案:

答案 0 :(得分:1)

<ScrollView
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/toolbar_offer_details"
        android:fillViewport="true">

也许在android:fillViewport="true"上设置ScrollView可以解决您的问题:

答案 1 :(得分:1)

您没有提到的是它现在正在做什么。您说您想要做某事,但是对我来说还不清楚。

您是指android:id="@+id/layout"吗?

如果是这样,那么我相信您在这里的要求太多了。

您的层次结构如下:

<CL> (ConstraintLayout)
   <Toolbar>
   <ScrollView>
      <CL>
        <CardView>
           <CL>
             <ImageView />
             <TextView />
           </CL>
        </CardView>
        <TextView />
        <TextView />
        <TextView />
        <TextView />
        <CL>
           <Button>
           <Button>
        </CL>
     </CL>
   </ScrollView>
</CL>

在使用任何技巧之前(我不喜欢android:fillViewport),我最初的建议是评估您的约束条件是否满足所有可能的方向和规模。

ScrollView要执行大量计算(必须询问其子级的大小)。他们可能无法做到书面上的某些事情,因为有些是“包装”内容,但没有完全的约束,这意味着他们必须等待并进行自我衡量,然后才能说出“我需要这么多的空间”。现在,将所有这些信息放入“度量/布局”过程中,并想象这将花费多长时间以及对引擎造成的痛苦。

ScrollViews也不是最好的,因为必须测量所有滚动视图以绘制其可滚动部分(滚动条和内容)。

我认为这里可能缺少的是垂直链,但请记住:

当您要求窗口小部件包装其内容并且仅提供一个约束时,例如,将TextView设置为WRAP其高度,但是仅具有“ top_to_”约束(但没有bottom_to ...),则小部件没有已知的大小,也没有计算方法,直到它的文本被测量(昂贵且缓慢的操作)为止,因为您可以具有任意字体大小,填充等。TextView是一个简单的示例,ImagesViews是另一个示例类似,因为现在可以在编译时并在运行时知道映像源。

避免大多数此类问题的方法是正确地 chain 小部件,并在需要时包装它们的内容。

有一个app:layout_constraintHeight_default="wrap"属性,可以让小部件知道它可以在需要时打破约束。

我建议您更多地使用它,以便在声明约束的方式上有改进的余地。