Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to set constraint to different view if certain view visibility is gone in constraint layout?

I have two different toolbars in my main activity. I only show one toolbar at a time. if one toolbar visibility is visible, the other will be gone. it is controlled by if else statement

the two toolbar is called:

  • general toolbar
  • search toolbar

those two have different height.

I am using include to attach the toolbar in my main activity.

here is the xml of my main activity

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

as you can see, include_toolbar_general is initially visible. and the fragment below it has constraintTop_toBottomOf to include_toolbar_general

the problem is, when in certain condition, the include_toolbar_general will be gone. and the fragment will go up and it seems overlap the include_toolbar_search (that visible, if general toolbar is gone).

i want to make, when include_toolbar_general visibility is gone, then the fragment below it will have constraintTop_toBottomOf include_toolbar_search

how to do that ?

like image 936
Alexa289 Avatar asked Aug 18 '19 10:08

Alexa289


2 Answers

You can set a Barrier to be aligned with the bottom of whichever toolbar is currently showing and constrain the top of the Fragment to that 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" />

And in your <fragment> change:

app:layout_constraintTop_toBottomOf="@+id/include_toolbar_general"

to:

app:layout_constraintTop_toBottomOf="@+id/barrier"
like image 165
Pawel Laskowski Avatar answered Oct 12 '22 16:10

Pawel Laskowski


In your design, you have two toolbars only one of which is visible at any given time; the other is gone. A fragment below the toolbar should be be constrained to the bottom of the toolbar that is showing. Here is one way to do this without introducing additional complexity or views. Take a look at Visibility Behavior in the documentation for reference.

Below is a layout that mimics your layout with TextViews instead of includes for simplicity, but the concepts will work for your included files. Each TextView has its top constrained to the view above.

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

In the following video, the TextViews that represent your included layout are alternated set to gone. As you can see, the fragment responds by setting its top to the bottom of the view that is visible.

enter image description here

like image 42
Cheticamp Avatar answered Oct 12 '22 16:10

Cheticamp