как установить ограничение на другой вид, если определенная видимость вида исчезла в макете ограничения?

У меня есть две разные панели инструментов в моей основной деятельности. Я показываю только одну панель инструментов за раз. если видна одна панель инструментов, другая исчезнет. он управляется оператором if else

две панели инструментов называются:

  • общая панель инструментов
  • панель инструментов поиска

эти двое имеют разный рост.

Я использую include, чтобы прикрепить панель инструментов к своей основной деятельности.

вот xml моей основной деятельности

<androidx.constraintlayout.widget.ConstraintLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".Activities.MainActivity" android:id="@+id/constraintLayout_main_activity">


    <include
            android:id="@+id/include_toolbar_general"
            layout="@layout/include_toolbar_general"
            android:visibility="visible"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintTop_toTopOf="parent" android:layout_width="0dp"
            android:layout_height="wrap_content"/>

    <include
            android:id="@+id/include_toolbar_search"
            layout="@layout/include_toolbar_search"
            android:visibility="gone"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintTop_toTopOf="parent" android:layout_width="0dp"
            android:layout_height="wrap_content"/>


    <fragment
            android:id="@+id/nav_host_fragment"
            android:layout_width="0dp"
            android:layout_height="0dp"
            app:layout_constraintBottom_toTopOf="@+id/bottom_nav"
            app:layout_constraintTop_toBottomOf="@+id/include_toolbar_general"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            android:name="androidx.navigation.fragment.NavHostFragment"
            app:navGraph="@navigation/main_graph"
            app:defaultNavHost="true"/>


</androidx.constraintlayout.widget.ConstraintLayout>

как видите, include_toolbar_general изначально виден. и фрагмент под ним имеет ограничениеTop_toBottomOf to include_toolbar_general

проблема в том, что в определенных условиях include_toolbar_general исчезнет. а фрагмент пойдет вверх и как бы перекроет include_toolbar_search (что видно, если общего тулбара нет).

я хочу сделать, когда include_toolbar_general видимость пропадет, то фрагмент под ним будет иметь limitedTop_toBottomOf include_toolbar_search

как это сделать ?


person Alexa289    schedule 18.08.2019    source источник
comment
Самый простой способ — переместить оба элемента ‹include› в один и тот же макет. Это означает, что вы можете обернуть оба включения внутри ‹FrameLayout›, а затем сделать зависимое ограничение для nav_host_fragment на app:layout_constraintTop_toBottomOf=@+id/frameLayout.   -  person mmmatey    schedule 18.08.2019


Ответы (2)


Вы можете установить Barrier для выравнивания с нижней частью любой панели инструментов, отображаемой в данный момент, и ограничить верхнюю часть Fragment этой Barrier:

<androidx.constraintlayout.widget.Barrier
        android:id="@+id/barrier"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:barrierDirection="bottom"
        app:constraint_referenced_ids="include_toolbar_general,include_toolbar_search" />

И в вашем <fragment> изменении:

app:layout_constraintTop_toBottomOf="@+id/include_toolbar_general"

to:

app:layout_constraintTop_toBottomOf="@+id/barrier"
person Pawel Laskowski    schedule 18.08.2019
comment
Большое спасибо. Я, наконец, понял, как использовать барьер. - person 6rchid; 07.11.2019

В вашем дизайне у вас есть две панели инструментов, только одна из которых видна в любой момент времени; другой gone. Фрагмент под панелью инструментов должен быть ограничен нижней частью отображаемой панели инструментов. Вот один из способов сделать это без дополнительных сложностей или представлений. Взгляните на Поведение видимости в документации для справки.

Ниже приведен макет, который имитирует ваш макет с TextViews вместо включения для простоты, но концепции будут работать для ваших включенных файлов. Верх каждого элемента TextView ограничен представленным выше представлением.

<androidx.constraintlayout.widget.ConstraintLayout 
    android:id="@+id/constraintLayout_main_activity"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/holo_green_light"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/include_toolbar_general"
        android:layout_width="0dp"
        android:layout_height="100dp"
        android:background="@android:color/holo_blue_bright"
        android:gravity="center"
        android:text="include_toolbar_general"
        android:textAppearance="@style/TextAppearance.AppCompat.Display1"
        android:visibility="visible"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/include_toolbar_search"
        android:layout_width="0dp"
        android:layout_height="100dp"
        android:background="@android:color/holo_red_light"
        android:gravity="center"
        android:text="include_toolbar_search"
        android:textAppearance="@style/TextAppearance.AppCompat.Display1"
        android:visibility="visible"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/include_toolbar_general" />


    <TextView
        android:id="@+id/nav_host_fragment"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:background="@android:color/holo_orange_light"
        android:gravity="center_horizontal"
        android:text="nav_host_fragment"
        android:textAppearance="@style/TextAppearance.AppCompat.Display1"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/include_toolbar_search" />

</androidx.constraintlayout.widget.ConstraintLayout>

В следующем видео TextViews, представляющие включенный макет, попеременно имеют значение gone. Как видите, фрагмент реагирует, устанавливая свою верхнюю часть в нижнюю часть видимого представления.

введите здесь описание изображения

person Cheticamp    schedule 18.08.2019
comment
Хороший ответ, я предпочитаю этот подход моему. - person Pawel Laskowski; 19.08.2019
comment
Спасибо, @PawelLaskowski. Несколько способов сделать это. Вопросы, как правило, упрощаются (к счастью!), поэтому никто не знает, что еще в нераскрытом дизайне побуждает ОП предпочесть один ответ другому. - person Cheticamp; 19.08.2019
comment
Это очень хорошее решение для стекирования представлений в подобных случаях. Но для случая, когда два представления накладываются друг на друга и оба требуют ограничений из другого представления, в соответствии с решением Павла будет работать только барьер. Чтобы поля и ограничения оставались согласованными, лучше всего использовать барьер для обмена видимостью представлений. - person 6rchid; 07.11.2019