Android ScrollView:如何使用约束布局创建带有静态页眉和页脚的滚动视图

Android ScrollView: How to create a scrolling view with static header and footer using constraint layout

我正在尝试创建一个带有静态页眉和页脚的滚动视图,如 this。 这是此布局的源代码

<?xml version="1.0" encoding="utf-8"?>

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

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <TextView
            android:id="@+id/title"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentTop="true"
            android:text="Title"
            android:textColor="#000"
            android:textSize="64sp"
            android:textStyle="bold"/>

        <ScrollView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_above="@+id/divider"
            android:layout_below="@+id/title">

            <TextView
                android:id="@+id/description"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="@string/description"
                android:textColor="#000"
                android:textSize="50.7sp" />

        </ScrollView>

        <ImageView
            android:id="@+id/divider"
            android:layout_width="match_parent"
            android:layout_height="4dp"
            android:background="#000"
            android:layout_above="@+id/buttons"/>

        <androidx.constraintlayout.widget.ConstraintLayout
            android:id="@+id/buttons"
            android:layout_alignParentBottom="true"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true">

            <Button
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:id="@+id/btnPos"
                android:text="Ok"
                android:textAllCaps="false"
                android:textColor="#000"
                android:textSize="45.7sp"
                android:textStyle="bold"
                android:onClick="home"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="@+id/buttons"/>

            <Button
                android:id="@+id/btnNeg"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Cancel"
                android:textAllCaps="false"
                android:textColor="#000"
                android:textSize="45.7sp"
                android:textStyle="bold"
                android:onClick="home"
                app:layout_constraintStart_toEndOf="@id/btnPos"
                app:layout_constraintTop_toTopOf="@+id/buttons"/>

        </androidx.constraintlayout.widget.ConstraintLayout>

    </RelativeLayout>

</RelativeLayout>

这是一个使用相对布局解决的问题,但我无法使用约束布局使其工作。您可以看到 here 滚动视图没有限制在页脚上方。这是此布局的来源

    <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto">

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

        <TextView
            android:id="@+id/title"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Title"
            android:textColor="#000"
            android:textSize="64sp"
            android:textStyle="bold"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <ScrollView
            android:id="@+id/scroll"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_constraintBottom_toTopOf="@id/divider"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/title"
            app:layout_constraintVertical_bias="0.0">

            <TextView
                android:id="@+id/description"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="@string/description"
                android:textColor="#000"
                android:textSize="50sp" />
        </ScrollView>

        <ImageView
            android:id="@+id/divider"
            android:layout_width="match_parent"
            android:layout_height="4dp"
            android:background="#000"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintBottom_toTopOf="@+id/buttons"/>

        <androidx.constraintlayout.widget.ConstraintLayout
            android:id="@+id/buttons"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:paddingTop="10dp"
            android:paddingBottom="10dp"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toEndOf="parent">

            <Button
                android:id="@+id/btnPos"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Ok"
                android:textSize="45.7sp"
                android:textAllCaps="false"
                android:onClick="home"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintStart_toStartOf="parent" />

            <Button
                android:id="@+id/btnNeg"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Cancel"
                android:textAllCaps="false"
                android:textSize="45.7sp"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toEndOf="@+id/btnPos"/>

        </androidx.constraintlayout.widget.ConstraintLayout>

    </androidx.constraintlayout.widget.ConstraintLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

根据,属性从 Relative 到 Constraint 布局的转换如下

android:layout_above="" -> app:layout_constraintBottom_toTopOf=""

和android:layout_below="" -> app:layout_constraintTop_toBottomOf=""

演示应用程序的存储库是 here

相对布局有效,但我想使用最新的 android 布局以获得最佳性能,这应该是可能的。提前致谢!

布局有几个问题。 ConstraintLayout 的目的之一是提供平面布局结构。将 ConstraintLayout 嵌套在另一个 ConstraintLayout 中并没有错,但它破坏了布局的一个理想属性。

match_parentContraintLayout 中不鼓励视图的宽度或高度。使用具有适当约束集的 match_constraints (0dp) 而不是 match_parent。您的布局中有一些 match_parent。 (match_parentConstraintLayout 本身上是可以的,因为它将被放置在另一种类型的布局中。

我继续对下面的布局进行了一些调整。

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

    <TextView
        android:id="@+id/title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Title"
        android:textColor="#000"
        android:textSize="64sp"
        android:textStyle="bold"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <ScrollView
        android:id="@+id/scroll"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintBottom_toTopOf="@+id/btnNeg"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/title">

        <TextView
            android:id="@+id/description"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@string/description"
            android:textColor="#000"
            android:textSize="50sp" />
    </ScrollView>

    <ImageView
        android:id="@+id/divider"
        android:layout_width="match_parent"
        android:layout_height="4dp"
        android:background="#000"
        app:layout_constraintBottom_toTopOf="@+id/buttons"
        app:layout_constraintStart_toStartOf="parent" />

    <Button
        android:id="@+id/btnPos"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="home"
        android:text="Ok"
        android:textAllCaps="false"
        app:layout_constraintHorizontal_chainStyle="packed"
        android:textSize="45.7sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toStartOf="@+id/btnNeg"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent" />

    <Button
        android:id="@+id/btnNeg"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Cancel"
        android:textAllCaps="false"
        android:textSize="45.7sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toEndOf="@+id/btnPos" />

</androidx.constraintlayout.widget.ConstraintLayout>

是的,我同意 Cheticamp 所说的。 ConstraintLayout 的目的是拥有一个平面布局结构。如果你遇到这个文件的问题,你 post 它上面你可以添加一个滚动条到 TextView 来实现像这样的平面布局结构:

<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/title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Title"
        android:textColor="#000"
        android:textSize="64sp"
        android:textStyle="bold"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/description"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:text="@string/description"
        android:textColor="#000"
        android:scrollbars="vertical"
        android:textSize="50sp"
        app:layout_constraintBottom_toTopOf="@+id/btnNeg"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/title" />

    <ImageView
        android:id="@+id/divider"
        android:layout_width="match_parent"
        android:layout_height="4dp"
        android:background="#000"
        app:layout_constraintBottom_toTopOf="@+id/buttons"
        app:layout_constraintStart_toStartOf="parent" />

    <Button
        android:id="@+id/btnPos"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="home"
        android:text="Ok"
        android:textAllCaps="false"
        android:textSize="45.7sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toStartOf="@+id/btnNeg"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintHorizontal_chainStyle="packed"
        app:layout_constraintStart_toStartOf="parent" />

    <Button
        android:id="@+id/btnNeg"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Cancel"
        android:textAllCaps="false"
        android:textSize="45.7sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toEndOf="@+id/btnPos" />

</androidx.constraintlayout.widget.ConstraintLayout>

您需要做的最后一件事是在代码中向您的 TextView 添加移动方法,如下所示:

((TextView) findViewById(R.id.description)).setMovementMethod(new ScrollingMovementMethod());