'Constraint Flow widget ignores max width attributes
I have multiple layouts that I want to display in a different location depending on screen size. If the screen is wide enough (tablet), I want the layouts to display horizontally then wrap down to the next row. If the screen is narrow (phone), I want the layouts to stack vertically.
The Constraint Flow widget works correctly for this when I supply a fixed layout_width.
I would like to change the layout of the child containers to be dynamic…up to a limit. Spreading out the contents of the containers is only useful up to a certain point. Basically, when displayed on a phone I want the size of the containers to adapt to the screen size. When displayed on a tablet or large phone/portrait, limit the width so that it doesn’t consume the entire screen.
To achieve this, I set android:layout_width="match_parent" and app:layout_constraintWidth_max="350dp". The behavior works correctly in other layout containers but not Constraint with the Flow widget. The Flow widget ignores the max width attributes and relies on the layout_width. The second layout containers is pushed off the screen to the right. The outline of the second layout can be seen in Android Studio when the mouse is hovered over it.
How do I achieve my objective of a dynamic layout size and placement?
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/layoutOne"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/holo_blue_dark"
android:maxWidth="350dp"
android:minHeight="490dp"
app:layout_constraintWidth_max="350dp" />
<androidx.appcompat.widget.LinearLayoutCompat
android:id="@+id/layoutTwo"
android:layout_width="350dp"
android:layout_height="wrap_content"
android:background="@android:color/holo_purple"
android:minHeight="490dp" />
<androidx.appcompat.widget.LinearLayoutCompat
android:id="@+id/layoutThree"
android:layout_width="350dp"
android:layout_height="wrap_content"
android:background="@android:color/holo_red_dark"
android:minHeight="490dp" />
<androidx.appcompat.widget.LinearLayoutCompat
android:id="@+id/layoutFour"
android:layout_width="350dp"
android:layout_height="wrap_content"
android:background="@android:color/black"
android:minHeight="490dp" />
<androidx.constraintlayout.helper.widget.Flow
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:constraint_referenced_ids="layoutOne,layoutTwo,layoutThree,layoutFour"
app:flow_horizontalStyle="packed"
app:flow_verticalAlign="top"
app:flow_wrapMode="chain"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
Solution 1:[1]
This is how I solved it. In the onCreate(), read the width value that was originally set in the XML. If the layout width exceeds the screen width then the layout width is set to the screen width.
I tried setting matchConstraintMaxWidth programmatically but it doesn't work. The layouts don't flow/wrap.
DisplayMetrics displayMetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
ConstraintLayout.LayoutParams layoutParams = (ConstraintLayout.LayoutParams)myConstraintLayout.getLayoutParams();
if(displayMetrics.widthPixels < (int) layoutParams.width )
layoutParams.width = displayMetrics.widthPixels;
myConstraintLayout.setLayoutParams(layoutParams);
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |