Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ConstrainLayout ConstraintSet - not working properly with Start/End constrains

Looks like ConstraintSet is finding hard to cope up with Start/End constrains.

This example is taken from Google samples. Github: android-ConstraintLayoutExamples


When you replace Left & Right constrains with Start & End, ConstraintSet - not working properly, It's working with Left/Right constrains only.
For example replace layout_constraintStart_toStartOf with layout_constraintLeft_toLeftOf & replace layout_constraintEnd_toEndOf with layout_constraintRight_toRightOf

in following files:
constraintset_example_main.xml
constraintset_example_big.xml

Behaviour:

onClick of image:

private ConstraintSet mConstraintSetNormal = new ConstraintSet();

private ConstraintSet mConstraintSetBig = new ConstraintSet();

public void toggleMode(View v) {
    TransitionManager.beginDelayedTransition(mRootLayout);
    mShowBigImage = !mShowBigImage;
    applyConfig();
}

private void applyConfig() {
    if (mShowBigImage) {
       mConstraintSetBig.applyTo(mRootLayout);
    } else {
        mConstraintSetNormal.applyTo(mRootLayout);
    }
}

By default Android studio uses start/ end constrains hence it's I want to know root cause and possible fix.
Or Is this a bug with ConstrainSet itself?

like image 463
AskQ Avatar asked Mar 12 '18 10:03

AskQ


People also ask

How do you fix a constraint error?

You can fix this using the Infer Constraints button or by dragging the constraint arrows to the edge of the app layout yourself.

Which is better RelativeLayout or ConstraintLayout?

If you have the choice start with ConstraintLayout, but if you already have your app in RelativeLayout, stay with it. That's all I have been following. RelativeLayout is very limited in functionality and many complex layouts can't be made using it, especially when ratios are involved.

Can we use LinearLayout in ConstraintLayout?

Most of what can be achieved in LinearLayout and RelativeLayout can be done in ConstraintLayout. However, learning the basics of LinearLayout and RelativeLayout is important before trying to understand how to use it with ConstraintLayout.

Why do we prefer constraint ConstraintLayout in Android?

It helps to improve the UI performance over other layouts. With the help of ConstraintLayout, we can control the group of widgets through a single line of code. With the help of ConstraintLayout, we can easily add animations to the UI components which we used in our app.


1 Answers

This does look like a problem with ConstraintSet, but let's see. The following analysis is based upon the sample project with the link that you supplied.

In the sample project, I have updated ConstraintLayout to the most recent version:

compile 'com.android.support.constraint:constraint-layout:1.1.0-beta5'

I did this in case we are trying to track down an issue that has already been addressed. I also updated the layout constraintset_example_big and replaced all left/right constraints with start/end constraints as follows:

constraintset_example_big.xml

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

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginEnd="24dp"
        android:layout_marginStart="24dp"
        android:layout_marginTop="24dp"
        android:onClick="toggleMode"
        android:scaleType="centerCrop"
        android:src="@drawable/lake"
        app:layout_constraintDimensionRatio="h,16:9"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:contentDescription="@string/lake_tahoe_image" />

    <TextView
        android:id="@+id/textView9"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/lake_tahoe_title"
        android:textSize="30sp"
        app:layout_constraintStart_toStartOf="@+id/imageView"
        android:layout_marginTop="8dp"
        app:layout_constraintTop_toBottomOf="@+id/imageView" />

    <TextView
        android:id="@+id/textView11"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:text="@string/lake_discription"
        app:layout_constraintStart_toStartOf="@+id/textView9"
        android:layout_marginTop="8dp"
        app:layout_constraintTop_toBottomOf="@+id/textView9"
        app:layout_constraintEnd_toEndOf="@+id/imageView"
        app:layout_constraintBottom_toBottomOf="parent"
        android:layout_marginBottom="16dp"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintVertical_bias="0.0" />

</android.support.constraint.ConstraintLayout>

With these changes in place, this is what we see.

enter image description here

This is clearly not right. It is supposed to look like this after the transition.

After some debugging, I tracked the issue down to this line in ConstraintSetExampleActivity.java:

mConstraintSetBig.load(this, R.layout.constraintset_example_big);

ConstraintSet#load() seems to be straightforward, but if we replace the code above with an explicit inflation of the layout followed by a clone of the ConstraintSet on the inflated layout as follows:

// mConstraintSetBig.load(this, R.layout.constraintset_example_big);
ConstraintLayout cl = (ConstraintLayout) getLayoutInflater().inflate(R.layout.constraintset_example_big,null);
mConstraintSetBig.clone(cl);

We see this behavior in the app which is much better.

enter image description here

So my takeaway is that ConstraintSet#load() has a problem with start/end constraints. The workaround is to inflate the ConstraintLayout then do a clone.

ConstraintSetExampleActivity#onCreate()

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.constraintset_example_main);

    mRootLayout = (ConstraintLayout) findViewById(R.id.activity_constraintset_example);
    // Note that this can also be achieved by calling
    // `mConstraintSetNormal.load(this, R.layout.constraintset_example_main);`
    // Since we already have an inflated ConstraintLayout in `mRootLayout`, clone() is
    // faster and considered the best practice.
    mConstraintSetNormal.clone(mRootLayout);
    // Load the constraints from the layout where ImageView is enlarged.

    // Toggle the comment status on the following three lines to fix/break.
    // mConstraintSetBig.load(this, R.layout.constraintset_example_big);
    ConstraintLayout cl = (ConstraintLayout) getLayoutInflater().inflate(R.layout.constraintset_example_big,null);
    mConstraintSetBig.clone(cl);

    if (savedInstanceState != null) {
        boolean previous = savedInstanceState.getBoolean(SHOW_BIG_IMAGE);
        if (previous != mShowBigImage) {
            mShowBigImage = previous;
            applyConfig();
        }
    }
}
like image 150
Cheticamp Avatar answered Oct 17 '22 13:10

Cheticamp