ScrollView 中的 ConstraintLayout

ConstraintLayout inside a ScrollView

我正在使用以下 Android 布局资源构建一个应用程序,它在 Android Studio 预览版和 phone 中都显示良好,如图所示。

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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.support.constraint.Guideline
        android:id="@+id/guideline_article_header"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:layout_constraintGuide_percent="@dimen/guideline_article_header" />

    <ImageView
        android:id="@+id/photo"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:contentDescription="@string/article_image"
        android:scaleType="centerCrop"
        app:layout_constraintBottom_toTopOf="@+id/guideline_article_header"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:srcCompat="@drawable/empty_detail" />

    <View
        android:id="@+id/view"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:background="@drawable/photo_background_protection"
        app:layout_constraintBottom_toTopOf="@+id/guideline_article_header"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/article_byline"
        style="?android:attr/textAppearanceSmall"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="8dp"
        android:layout_marginStart="16dp"
        android:textColor="@android:color/white"
        app:layout_constraintBottom_toTopOf="@+id/guideline_article_header"
        app:layout_constraintStart_toStartOf="parent"
        tools:text="Jan 1, 1912 by JackLondon" />

    <TextView
        android:id="@+id/article_title"
        style="?android:attr/textAppearanceLarge"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="8dp"
        android:layout_marginStart="16dp"
        android:fontFamily="sans-serif-condensed"
        android:textColor="@android:color/white"
        android:textSize="@dimen/detail_title_text_size"
        android:textStyle="bold"
        app:layout_constraintBottom_toTopOf="@+id/article_byline"
        app:layout_constraintStart_toStartOf="parent"
        tools:text="The Scarlet Plague" />

    <TextView
        android:id="@+id/article_body"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginBottom="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginStart="16dp"
        android:layout_marginTop="8dp"
        android:textColorLink="@color/colorAccent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/view"
        app:layout_constraintVertical_bias="0.0"
        tools:text="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas et efficitur nunc, nec tincidunt eros. Quisque pharetra quam quam. Ut eleifend nulla eros, tempus mattis augue lacinia eget. Praesent dignissim, tellus sit amet pulvinar pretium, augue turpis congue dui, non tempor nisi est a diam. Proin id malesuada nibh. Phasellus fermentum neque lorem, at rutrum enim vehicula vel. Curabitur et enim pretium, euismod nunc in, pretium dolor. Nullam varius eros ut massa condimentum porttitor. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Proin nulla diam, dapibus maximus nulla et, maximus congue risus. Aliquam erat volutpat. Duis vel augue ut diam euismod varius. Vestibulum quam magna, convallis blandit vulputate sed, elementum et odio. Maecenas efficitur sem volutpat luctus euismod. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Pellentesque facilisis sapien consequat erat sodales aliquet. Maecenas enim nisi, dignissim non vulputate commodo, tempus ut arcu. Suspendisse potenti. Nulla facilisi. Nam vestibulum orci ex, ac pulvinar elit dapibus ac. Curabitur ut elit justo. Aenean sit amet erat finibus, laoreet lectus quis, eleifend orci. Donec feugiat dui ut nisl euismod auctor. Donec neque magna, tincidunt in tortor ac, fermentum laoreet velit. Sed mollis et ligula non ullamcorper. Etiam at rhoncus tortor. Mauris hendrerit commodo euismod. Interdum et malesuada fames ac ante ipsum primis in faucibus. Quisque maximus orci a neque tempus pellentesque. Sed erat erat, ultrices eget arcu ac, laoreet cursus odio. Maecenas tristique aliquet vestibulum. Curabitur nec nisi ante. Suspendisse sed dui faucibus, mattis libero maximus, ullamcorper enim. Nulla sodales tellus at tristique fermentum. Fusce sapien nunc, imperdiet vitae arcu et, luctus euismod massa. Proin sed molestie lacus. Nulla vitae ipsum ac orci mattis facilisis. Proin massa risus, cursus et purus vitae, luctus mattis ante. Nulla sagittis id mauris a luctus. Suspendisse blandit orci sit amet purus rhoncus consequat. Duis sapien tortor, interdum mollis tempus sit amet, ullamcorper fringilla mauris. Cras at felis fringilla quam vulputate scelerisque. Sed vestibulum mollis odio elementum lobortis. Proin consequat efficitur neque non varius. Integer in finibus neque, a eleifend ligula. Quisque id faucibus sapien, id porttitor enim. Integer malesuada odio diam, ut sollicitudin nisi egestas ac. Duis sit amet libero purus." />
</android.support.constraint.ConstraintLayout>

然而,article_body TextView 可能是可滚动的,所以我试图用 ScrollView 包围 ConstraintLayout,但 ConstraintLayout 只需要一个如下图所示的屏幕部分。

<?xml version="1.0" encoding="utf-8"?>
<ScrollView 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.support.constraint.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.support.constraint.Guideline
            android:id="@+id/guideline_article_header"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            app:layout_constraintGuide_percent="@dimen/guideline_article_header" />

        <ImageView
            android:id="@+id/photo"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:contentDescription="@string/article_image"
            android:scaleType="centerCrop"
            app:layout_constraintBottom_toTopOf="@+id/guideline_article_header"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:srcCompat="@drawable/empty_detail" />

        <View
            android:id="@+id/view"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:background="@drawable/photo_background_protection"
            app:layout_constraintBottom_toTopOf="@+id/guideline_article_header"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <TextView
            android:id="@+id/article_byline"
            style="?android:attr/textAppearanceSmall"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="8dp"
            android:layout_marginStart="16dp"
            android:textColor="@android:color/white"
            app:layout_constraintBottom_toTopOf="@+id/guideline_article_header"
            app:layout_constraintStart_toStartOf="parent"
            tools:text="Jan 1, 1912 by JackLondon" />

        <TextView
            android:id="@+id/article_title"
            style="?android:attr/textAppearanceLarge"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="8dp"
            android:layout_marginStart="16dp"
            android:fontFamily="sans-serif-condensed"
            android:textColor="@android:color/white"
            android:textSize="@dimen/detail_title_text_size"
            android:textStyle="bold"
            app:layout_constraintBottom_toTopOf="@+id/article_byline"
            app:layout_constraintStart_toStartOf="parent"
            tools:text="The Scarlet Plague" />

        <TextView
            android:id="@+id/article_body"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:layout_marginBottom="8dp"
            android:layout_marginEnd="8dp"
            android:layout_marginStart="16dp"
            android:layout_marginTop="8dp"
            android:textColorLink="@color/colorAccent"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.0"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/view"
            app:layout_constraintVertical_bias="0.0"
            tools:text="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas et efficitur nunc, nec tincidunt eros. Quisque pharetra quam quam. Ut eleifend nulla eros, tempus mattis augue lacinia eget. Praesent dignissim, tellus sit amet pulvinar pretium, augue turpis congue dui, non tempor nisi est a diam. Proin id malesuada nibh. Phasellus fermentum neque lorem, at rutrum enim vehicula vel. Curabitur et enim pretium, euismod nunc in, pretium dolor. Nullam varius eros ut massa condimentum porttitor. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Proin nulla diam, dapibus maximus nulla et, maximus congue risus. Aliquam erat volutpat. Duis vel augue ut diam euismod varius. Vestibulum quam magna, convallis blandit vulputate sed, elementum et odio. Maecenas efficitur sem volutpat luctus euismod. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Pellentesque facilisis sapien consequat erat sodales aliquet. Maecenas enim nisi, dignissim non vulputate commodo, tempus ut arcu. Suspendisse potenti. Nulla facilisi. Nam vestibulum orci ex, ac pulvinar elit dapibus ac. Curabitur ut elit justo. Aenean sit amet erat finibus, laoreet lectus quis, eleifend orci. Donec feugiat dui ut nisl euismod auctor. Donec neque magna, tincidunt in tortor ac, fermentum laoreet velit. Sed mollis et ligula non ullamcorper. Etiam at rhoncus tortor. Mauris hendrerit commodo euismod. Interdum et malesuada fames ac ante ipsum primis in faucibus. Quisque maximus orci a neque tempus pellentesque. Sed erat erat, ultrices eget arcu ac, laoreet cursus odio. Maecenas tristique aliquet vestibulum. Curabitur nec nisi ante. Suspendisse sed dui faucibus, mattis libero maximus, ullamcorper enim. Nulla sodales tellus at tristique fermentum. Fusce sapien nunc, imperdiet vitae arcu et, luctus euismod massa. Proin sed molestie lacus. Nulla vitae ipsum ac orci mattis facilisis. Proin massa risus, cursus et purus vitae, luctus mattis ante. Nulla sagittis id mauris a luctus. Suspendisse blandit orci sit amet purus rhoncus consequat. Duis sapien tortor, interdum mollis tempus sit amet, ullamcorper fringilla mauris. Cras at felis fringilla quam vulputate scelerisque. Sed vestibulum mollis odio elementum lobortis. Proin consequat efficitur neque non varius. Integer in finibus neque, a eleifend ligula. Quisque id faucibus sapien, id porttitor enim. Integer malesuada odio diam, ut sollicitudin nisi egestas ac. Duis sit amet libero purus." />
    </android.support.constraint.ConstraintLayout>
</ScrollView>

约束布局的高度应为 android:layout_height="wrap_content",然后将 @+id/article_body 的高度也设置为 android:layout_height="wrap_content"

像@tgrable 所说的那样使用代码发现了 ConstraintLayout 的紧张行为。

app:layout_constraintGuide_percent="@dimen/guideline_article_header"

引导线百分比未设置为 phone 屏幕高度,但其设置为 ConstraintLayout 高度,这意味着如果 @+id/article_body 文本减少,它将减少并增加。如问题所述

However, the article_body TextView may be scrollable, Blockquote

如果您只想滚动 TextView,则 Visit this link 或仅使 TextView 可滚动,如下所示

<ScrollView
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:layout_marginBottom="8dp"
    android:layout_marginEnd="8dp"
    android:layout_marginStart="16dp"
    android:layout_marginTop="8dp"
    app:layout_constraintHorizontal_bias="0.0"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintVertical_bias="0.0"
    app:layout_constraintTop_toBottomOf="@+id/view">

    <TextView
        android:id="@+id/article_body"
        style="?android:attr/textAppearanceSmall"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas et efficitur nunc, nec tincidunt eros. Quisque pharetra quam quam. Ut eleifend nulla eros, tempus mattis augue lacinia eget. Praesent dignissim, tellus sit amet pulvinar pretium, augue turpis congue dui, non tempor nisi est a diam. Proin id malesuada nibh. Phasellus fermentum neque lorem, at rutrum enim vehicula vel. Curabitur et enim pretium, euismod nunc in, pretium dolor. Nullam varius eros ut massa condimentum porttitor. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Proin nulla diam, dapibus maximus nulla et, maximus congue risus. Aliquam erat volutpat. Duis vel augue ut diam euismod varius. Vestibulum quam magna, convallis blandit vulputate sed, elementum et odio. Maecenas efficitur sem volutpat luctus euismod. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Pellentesque facilisis sapien consequat erat sodales aliquet. Maecenas enim nisi, dignissim non vulputate commodo, tempus ut arcu. Suspendisse potenti. Nulla facilisi. Nam vestibulum orci ex, ac pulvinar elit dapibus ac. Curabitur ut elit justo. Aenean sit amet erat finibus, laoreet lectus quis, eleifend orci. Donec feugiat dui ut nisl euismod auctor. Donec neque magna, tincidunt in tortor ac, fermentum laoreet velit. Sed mollis et ligula non ullamcorper. Etiam at rhoncus tortor. Mauris hendrerit commodo euismod. Interdum et malesuada fames ac ante ipsum primis in faucibus. Quisque maximus orci a neque tempus pellentesque. Sed erat erat, ultrices eget arcu ac, laoreet cursus odio. Maecenas tristique aliquet vestibulum. Curabitur nec nisi ante. Suspendisse sed dui faucibus, mattis libero maximus, ullamcorper enim. Nulla sodales tellus at tristique fermentum. Fusce sapien nunc, imperdiet vitae arcu et, luctus euismod massa. Proin sed molestie lacus. Nulla vitae ipsum ac orci mattis facilisis. Proin massa risus, cursus et purus vitae, luctus mattis ante. Nulla sagittis id mauris a luctus. Suspendisse blandit orci sit amet purus rhoncus consequat. Duis sapien tortor, interdum mollis tempus sit amet, ullamcorper fringilla mauris. Cras at felis fringilla quam vulputate scelerisque. Sed vestibulum mollis odio elementum lobortis. Proin consequat efficitur neque non varius. Integer in finibus neque, a eleifend ligula. Quisque id faucibus sapien, id porttitor enim. Integer malesuada odio diam, ut sollicitudin nisi egestas ac. Duis sit amet libero purus."
        android:textColorLink="@color/colorAccent" />