Jeff Hatfield
Jeff Hatfield

Reputation: 161

Setting Constraints to a Fragment

I'm trying to dynamically add a Fragment to my Activity that will have certain constraints inside of the Constraint Layout it is being put inside.

In a nutshell what I want is to add a Fragment to a Constraint Layout. The Constraint Layout has bounds that cover the entire screen, but has a Header at the top. I want the Fragment to have constraints with a Top-Bottom constraint with the Header and a Bottom-Bottom constraint with the parent Constraint Layout

I've tried putting the Constraints inside the Fragment's Layout XML I've tried programmatically setting the constraints with ConstraintSet

Activity Layout XML (Main Activity)

<android.support.constraint.ConstraintLayout
        android:id="@+id/main_activity_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <com.seven.eleven.ideation.views.HeaderLayout
            android:id="@+id/header"
            android:layout_width="match_parent"
            android:layout_height="@dimen/header_height"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

    </android.support.constraint.ConstraintLayout>

Activity code

getSupportFragmentManager().beginTransaction()
                    .add(R.id.main_activity_layout, homeFragment, HOME_TAG).commit();

            ConstraintSet constraintSet = new ConstraintSet();
            constraintSet.clone(mainLayout);
            constraintSet.connect(R.id.fragment_home_root,  ConstraintSet.TOP,
                                    R.id.header,            ConstraintSet.BOTTOM);
            constraintSet.connect(R.id.fragment_home_root,  ConstraintSet.BOTTOM,
                                    R.id.root,              ConstraintSet.BOTTOM);
            constraintSet.applyTo(mainLayout);

Fragment Layout XML (Home Fragment)

<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/fragment_home_root"
    android:layout_width="match_parent"
    android:layout_height="0dp"
    app:layout_constraintTop_toBottomOf="@+id/header"
    app:layout_constraintBottom_toBottomOf="parent">

    <TextView
        android:id="@+id/welcome_text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toTopOf="@+id/welcome_paragraph_text"
        android:layout_margin="@dimen/box_margins"
        android:text="@string/welcome"
        android:textSize="@dimen/oversized_text_size"
        android:textColor="@color/primary_text_color"
        android:textStyle="bold"/>

    <TextView
        android:id="@+id/welcome_paragraph_text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        android:layout_marginLeft="@dimen/box_margins"
        android:layout_marginRight="@dimen/box_margins"
        android:text="@string/welcome_paragraph"
        android:textSize="@dimen/primary_text_size"
        android:textColor="@color/primary_text_color"/>

</android.support.constraint.ConstraintLayout>

Depending on what method I use, either the Fragment just goes to the top or is center on the entire screen instead of being constrained to the bottom of the Header

Upvotes: 1

Views: 5343

Answers (1)

Jeff Hatfield
Jeff Hatfield

Reputation: 161

If anyone happens by this question who has a similar issue perhaps my workaround can help:

Instead of placing the Fragment in the parent Constraint Layout, make a new FrameLayout with the constraints you want and place the Fragment in that.

Using the same layout for the Main Activity here's what I did

<android.support.constraint.ConstraintLayout
        android:id="@+id/main_activity_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <com.my.project.ideation.views.HeaderLayout
            android:id="@+id/header"
            android:layout_width="match_parent"
            android:layout_height="@dimen/header_height"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <FrameLayout
            android:id="@+id/fragment_layout"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            app:layout_constraintTop_toBottomOf="@+id/header"
            app:layout_constraintBottom_toBottomOf="parent"/>

    </android.support.constraint.ConstraintLayout>

And in the Activity's code

getSupportFragmentManager().beginTransaction()
                    .add(R.id.fragment_layout, homeFragment, HOME_TAG).commit();

You can see that the FrameLayout has the desired constraints that I want. No need to add them programmatically or assume with id's in other layout XML. Now the FrameLayout will be the parent for the Fragment

Upvotes: 1

Related Questions