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?
You can fix this using the Infer Constraints button or by dragging the constraint arrows to the edge of the app layout yourself.
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.
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.
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.
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.
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.
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();
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With