首页 > 解决方案 > 包含合并标签的 ConstraintLayout 不起作用

问题描述

这是我的 qff_layout.xml 文件

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

    <com.google.android.material.textview.MaterialTextView
            android:id="@+id/questions_label"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:text="@string/questions"
            android:textSize="@dimen/text_normal"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintEnd_toStartOf="@+id/followers_label"
            app:layout_constraintTop_toTopOf="parent"/>

    <com.google.android.material.textview.MaterialTextView
            android:id="@+id/followers_label"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:text="@string/followers"
            android:textSize="@dimen/text_normal"
            app:layout_constraintStart_toEndOf="@+id/questions_label"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintEnd_toStartOf="@+id/following_label"
            app:layout_constraintTop_toTopOf="parent"/>

    <com.google.android.material.textview.MaterialTextView
            android:id="@+id/following_label"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:text="@string/following"
            android:textSize="@dimen/text_normal"
            app:layout_constraintStart_toEndOf="@+id/followers_label"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintTop_toTopOf="parent"/>

    <com.google.android.material.textview.MaterialTextView
            android:id="@+id/questions_number"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:textSize="@dimen/text_normal"
            android:textStyle="bold"
            tools:text="0"
            app:layout_constraintStart_toStartOf="@+id/questions_label"
            android:layout_marginEnd="8dp"
            app:layout_constraintEnd_toEndOf="@+id/questions_label"
            android:layout_marginRight="8dp"
            app:layout_constraintTop_toBottomOf="@+id/questions_label"/>

    <com.google.android.material.textview.MaterialTextView
            android:id="@+id/followers_number"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:textSize="@dimen/text_normal"
            android:textStyle="bold"
            tools:text="0"
            android:layout_marginStart="8dp"
            android:layout_marginLeft="8dp"
            android:layout_marginEnd="8dp"
            android:layout_marginRight="8dp"
            app:layout_constraintStart_toEndOf="@+id/questions_label"
            app:layout_constraintEnd_toStartOf="@+id/following_label"
            app:layout_constraintTop_toBottomOf="@+id/followers_label"/>


    <com.google.android.material.textview.MaterialTextView
            android:id="@+id/following_number"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:textSize="@dimen/text_normal"
            android:textStyle="bold"
            tools:text="0"
            android:layout_marginEnd="8dp"
            android:layout_marginRight="8dp"
            app:layout_constraintStart_toStartOf="@+id/following_label"
            app:layout_constraintEnd_toEndOf="@+id/following_label"
            app:layout_constraintTop_toBottomOf="@+id/following_label"/>

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

这会在两行中显示 6 个文本视图,您会在 instagram 应用程序的个人资料部分中看到这些内容,其中包含 Posts-Followers-Following 和下面的数字。现在的问题是当我将它包含在我的主布局中时,即 ConstraintLayout:profile_fragment.xml

<?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:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

    <androidx.appcompat.widget.Toolbar
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:background="?attr/colorPrimary"
            android:theme="?attr/actionBarTheme"
            android:minHeight="?attr/actionBarSize"
            android:elevation="4dp"
            android:id="@+id/title"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintEnd_toEndOf="parent"/>

    <de.hdodenhof.circleimageview.CircleImageView
            android:id="@+id/profile_image"
            android:layout_width="80dp"
            android:layout_height="80dp"
            app:srcCompat="@drawable/ic_profile_24dp"
            tools:src="@drawable/ic_profile_24dp"
            app:civ_border_color="@color/secondaryDarkColor"
            app:civ_border_width="1dp"
            android:layout_marginTop="@dimen/spacing_normal"
            android:layout_marginStart="@dimen/spacing_normal"
            android:layout_marginLeft="@dimen/spacing_normal"
            app:layout_constraintTop_toBottomOf="@+id/title"
            app:layout_constraintStart_toStartOf="parent"/>

    <com.google.android.material.textview.MaterialTextView
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:id="@+id/description"
            android:layout_marginEnd="@dimen/spacing_normal"
            android:layout_marginRight="@dimen/spacing_normal"
            android:layout_marginLeft="@dimen/spacing_normal"
            android:layout_marginStart="@dimen/spacing_normal"
            app:layout_constraintStart_toEndOf="@+id/profile_image"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintBottom_toBottomOf="@+id/profile_image"
            app:layout_constraintTop_toTopOf="@+id/profile_image"/>

    <include
            layout="@layout/qff_layout"
            android:id="@+id/qff_layout"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginTop="@dimen/spacing_small"
            app:layout_constraintTop_toBottomOf="@+id/profile_image"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"/>

    <com.google.android.material.tabs.TabLayout
            android:id="@+id/sliding_tabs"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:background="@color/primaryLightColor"
            app:tabMode="fixed"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/qff_layout"/>

    <androidx.viewpager.widget.ViewPager
            android:id="@+id/view_pager"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:background="@android:color/white"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/sliding_tabs" />

</androidx.constraintlayout.widget.ConstraintLayout>

什么都没有显示。
我尝试将我的主要布局更改为线性,它是相同的。
但是,当我从 qff_layout.xml 中删除合并标记并在主布局中使用相同的包含标记时,它运行良好并显示 qff_layout,如何??为什么?
那么合并标签有什么用,请不要引用最愚蠢的文档中的内容,因为它没有任何意义。

标签: androidandroid-studioandroid-layoutandroid-constraintlayout

解决方案


当您不想重复相同的 ViewGroup 时,您应该使用合并。在这种情况下,它可以使您免于不使用两个嵌套的 ConstraintLayouts - 您可以从 qff_layout.xml 中删除 ConstraintLayout 并将合并用作您的根元素,例如:

<merge
xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

    <!-- your text view -->
</merge>

如果您在 qff_layout.xml 中的 ConstraintLayout 有其他用途,您只需保留它,并包含 qff_layout.xml 而不合并作为根元素。

也就是说merge的目的是为了替换根ViewGroup。在这里阅读更多。

更新:

您可以通过这种方式修复您的 XML,而无需删除边距。

您在元素上定义的定位约束也应应用于 qff_layout.xml 中的 ConstraintLayout,例如:

<merge
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">
    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/qff_layout"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="@dimen/spacing_small"
        app:layout_constraintTop_toBottomOf="@+id/profile_image"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent">

        <!-- your text view -->

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

为什么你需要应用这个:当你将布局放在元素内时,它基本上会被粘贴到你包含它的行中。当您没有为 ConstraintLyout 中的某些布局定义约束时,它会跳转到屏幕的左上角,这就是您包含的布局发生的情况。它没有在 qff_layout.xml 中定义当它被包含时将应用的约束,所以它跳到了左上角。


推荐阅读