Заставить ViewPager заполнить оставшееся пространство в ConstraintLayout - PullRequest
3 голосов
/ 03 августа 2020

У меня следующий код XML, мне не удалось заставить 'summaryViewPager' заполнить оставшееся пространство по вертикали до нижней части экрана:

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

        <com.google.android.material.card.MaterialCardView
            android:id="@+id/mainCardView"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginStart="10dp"
            android:layout_marginLeft="10dp"
            android:layout_marginTop="10dp"
            android:layout_marginEnd="10dp"
            android:layout_marginRight="10dp"
            android:background="#666266"
            android:padding="10dp"
            app:cardCornerRadius="20dp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent">

                <TextView
                    android:id="@+id/textView"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginStart="3dp"
                    android:layout_marginLeft="3dp"
                    android:layout_marginTop="2dp"
                    android:text="@string/category"
                    android:textColor="#FFBA93"
                    android:textSize="20sp"
                    android:textStyle="bold"
                    app:layout_constraintStart_toStartOf="parent"
                    app:layout_constraintTop_toTopOf="parent" />
        </com.google.android.material.card.MaterialCardView>

        <com.google.android.material.card.MaterialCardView
            android:id="@+id/cardView2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="10dp"
            android:layout_marginLeft="10dp"
            android:layout_marginTop="10dp"
            android:layout_marginEnd="10dp"
            android:layout_marginRight="10dp"
            android:background="#666266"
            android:padding="10dp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@id/mainCardView">


                <Button
                    android:id="@+id/shareButton"
                    android:layout_width="30dp"
                    android:layout_height="30dp"
                    android:layout_marginStart="5dp"
                    android:layout_marginLeft="5dp"
                    android:layout_marginTop="8dp"
                    android:layout_marginEnd="5dp"
                    android:layout_marginRight="5dp"
                    android:background="@drawable/ic_share"
                    app:layout_constraintEnd_toStartOf="@+id/copyButton"
                    app:layout_constraintHorizontal_bias="0.5"
                    app:layout_constraintStart_toStartOf="parent"
                    app:layout_constraintTop_toTopOf="parent" />


                <ImageView
                    android:id="@+id/seenImageView"
                    android:layout_width="20dp"
                    android:layout_height="20dp"
                    android:layout_marginStart="3dp"
                    android:layout_marginLeft="3dp"
                    android:layout_marginTop="15dp"
                    android:layout_marginEnd="5dp"
                    android:layout_marginRight="5dp"
                    android:contentDescription="@string/todo"
                    app:layout_constraintEnd_toEndOf="parent"
                    app:layout_constraintHorizontal_bias="0.5"
                    app:layout_constraintStart_toEndOf="@+id/favoriteButton"
                    app:layout_constraintTop_toTopOf="parent"
                    app:srcCompat="@drawable/unseen" />
        </com.google.android.material.card.MaterialCardView>

    <androidx.viewpager2.widget.ViewPager2
        android:id="@+id/summaryViewPager"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_marginTop="2dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/cardView2" />

    </androidx.constraintlayout.widget.ConstraintLayout>

В приведенном выше коде не отображается PageViewer вообще ниже cardView2, однако когда я устанавливаю android: layout_height = "500dp, он показывает PageViewer, но не заполняет весь экран.

1 Ответ

1 голос
/ 03 августа 2020

Начальные мысли

  1. Я скопировал, вставил ваш макет в Android Studio 4.x, заменил все ссылки @string на «что-то», а все @drawables на существующий (из @android:drawable/), поэтому мой макет будет отображаться.

Насколько я вижу, это выглядит правильно:

android-studio-preview

  1. Я заметил некоторые несоответствия в вашем макете.

CardView Number 1 (вверху)

  • Осторожно с заполнением в CardView (не знаю свой min / max API, поэтому не уверен, что это относится к вам).
  • Ваш CardView не имеет ограничений для своего BOTTOM, ему остается «независимо от размера, который вы вычисляете после упаковки» (Height = wrap, Bottom_To = null).
  • Это означает, что для CardView, чтобы иметь высоту, все его внутренние виджеты должны вычислять свои размеры, поэтому верхний вид карты знает, какой размер + поля + отступы ему нужны. Он не зависит от ДРУГИХ виджетов (не являющихся дочерними), потому что все его ограничения относятся к родителю. (ему нужен только его родительский элемент).

CardView Number 2 (внизу)

  • Этот cardView объединяет все свои измерения, но имеет ту же проблему, что и предыдущий, он не ограничивает его высоту (за исключением того, что он закреплен внизу предыдущего, CardView 1). Опять же, это нормально, если от этого никто не зависит (что неверно). Этот должен ждать, пока больше виджетов узнает свой размер, потому что он должен ждать, пока CardView1 узнает, сколько места осталось, а также необходимо знать, сколько его дочерних элементов. Это не так сложно, потому что оба (ImageView и Button) имеют фиксированные размеры (20 и 30 dp соответственно) + поля / отступы.
  • Дочерние элементы MaterialCardView не могут / не должны / не должны использовать constraints потому что CardView - это не ConstraintLayout, а прославленный FrameLayout, который может содержать только ОДИН дочерний элемент (или, если у него больше, он поместит их поверх другого). Таким образом, все эти ограничения (для shareButton и visibleImageView) игнорируются. 1039 * внутренний CL, поместите всех своих детей и их ограничения. Внутренний ConstraintLayout должен иметь ширину / высоту как wrap_content или match_parent, чтобы они использовали ограничения родителя. Поскольку у них фиксированные размеры, это не проблема. (и если бы они этого не сделали, это не было бы проблемой , но потребовался бы другой проход измерения).
  • Независимо от этого, этот второй CardView может вычислить свою высоту, потому что его дочерние элементы сообщают о размере 20 + 30 (перекрытие) + 15 верхнего края поля (изображение), так что ... все это вместе, вероятно, составляет 45dp ~ высоты (поскольку они перекрывают только самые большие числа, применимы здесь).
  • Все ограничения для этих двух дочерних элементов игнорируются.

ViewPager (внизу)

Наконец, мы достигаем VPager. Ширина этого viewPager составляет match_parent (поскольку у вас есть ограничения на начало / конец, вы должны просто использовать 0dp). И он имеет wrap_content для его высоты.

  • layout_height=wrap_content -> это проблема. Поскольку viewPager еще не знает (во время передачи / измерения макета), каким будет его содержимое. Таким образом, вы, вероятно, хотите, чтобы это было 0dp и чтобы ViewPager использовал все доступное пространство после того, как было вычислено выше.

  • marginTop у вас здесь, не будет работать как есть, потому что CardView 1 и 2 не имеют нижнего ограничения, поэтому этот должен был бы создать еще один проход макета / измерения после все сказано и сделано чтобы иметь возможность применить маржу (вот как это работает).

Хорошо Достаточно Rant - что вы можете сделать?

  1. Я бы «исправьте» макет, добавив правильные ограничения и, если необходимо, используйте VerticalChain и смещение для всех виджетов.

  2. Я бы исправил среднее (Cardview 2) содержимое, обернув textview и imageView в ConstraintLayout.

  3. Я бы удалил left/right и заменил start/end (если вы не нацеливаетесь на API 16 или ниже).

  4. Я бы установил ViewPager на 0dp на оба измерения.

  5. Дочерние элементы вашего CardView2 относятся к copyButton и favoriteButton, но их нет в вставленном вами макете, поэтому я предполагаю, что у вас там больше кнопок) .

Полная версия (измененная)

И, если вам интересно, вот что я сделал (я добавил цвет к фону VP, чтобы было легче «увидеть» ").

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

    <com.google.android.material.card.MaterialCardView
        android:id="@+id/mainCardView"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="10dp"
        android:layout_marginTop="10dp"
        android:layout_marginEnd="10dp"
        app:layout_constraintVertical_chainStyle="packed"
        android:background="#666266"
        android:padding="10dp"
        app:cardCornerRadius="20dp"
        app:layout_constraintBottom_toTopOf="@id/cardView2"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <TextView
            android:id="@+id/textView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="3dp"
            android:layout_marginTop="2dp"
            android:text="Category"
            android:textColor="#FFBA93"
            android:textSize="20sp"
            android:textStyle="bold" />
    </com.google.android.material.card.MaterialCardView>

    <com.google.android.material.card.MaterialCardView
        android:id="@+id/cardView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="10dp"
        android:layout_marginLeft="10dp"
        android:layout_marginTop="10dp"
        android:layout_marginEnd="10dp"
        android:layout_marginRight="10dp"
        android:background="#666266"
        android:padding="10dp"
        app:layout_constraintBottom_toTopOf="@id/summaryViewPager"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/mainCardView">

        <androidx.constraintlayout.widget.ConstraintLayout
            android:id="@+id/innerCardView2Root"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <Button
                android:id="@+id/shareButton"
                android:layout_width="30dp"
                android:layout_height="30dp"
                android:layout_marginStart="5dp"
                android:layout_marginTop="8dp"
                android:layout_marginEnd="5dp"
                android:background="@android:drawable/ic_menu_share"
                app:layout_constraintEnd_toStartOf="@+id/seenImageView"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent" />


            <ImageView
                android:id="@+id/seenImageView"
                android:layout_width="20dp"
                android:layout_height="20dp"
                android:layout_marginStart="3dp"
                android:layout_marginTop="15dp"
                android:layout_marginEnd="5dp"
                android:contentDescription="@null"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toEndOf="@+id/shareButton"
                app:layout_constraintTop_toTopOf="parent"
                app:srcCompat="@android:drawable/ic_menu_search" />
        </androidx.constraintlayout.widget.ConstraintLayout>

    </com.google.android.material.card.MaterialCardView>

    <androidx.viewpager2.widget.ViewPager2
        android:id="@+id/summaryViewPager"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginTop="2dp"
        android:background="@color/colorSecondary"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/cardView2" />

</androidx.constraintlayout.widget.ConstraintLayout>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...