Skip to content

Commit 9f9d07d

Browse files
AlexBalothagikura
authored andcommitted
Flexline width exceeds container width (#521)
In this PR I am trying to address an issue that occurs when the calculation of flexlines exceeds the permitted size of their container and some items can be shrunk. After successfully calculating the number of flexline the FlexboxLayout proceeds its measurement by determining the main size through the determineMainSize() method. In certain situations, the width of some flexlines might be bigger than the size of their container. In this cases, we need to restrict their calculated width by retriggering a second layout calculation and enforcing their width as the one of their containers.
1 parent 239d5f7 commit 9f9d07d

File tree

2 files changed

+76
-1
lines changed

2 files changed

+76
-1
lines changed

flexbox/src/androidTest/java/com/google/android/flexbox/FlexboxHelperTest.kt

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package com.google.android.flexbox
1818

1919
import android.view.View
20+
import android.widget.TextView
2021
import androidx.test.rule.ActivityTestRule
2122
import androidx.test.runner.AndroidJUnit4
2223
import com.google.android.flexbox.test.FlexboxTestActivity
@@ -36,6 +37,13 @@ import org.junit.runner.RunWith
3637
@RunWith(AndroidJUnit4::class)
3738
class FlexboxHelperTest {
3839

40+
private val LONG_TEXT = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do " +
41+
"eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim " +
42+
"veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo " +
43+
"consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum " +
44+
"dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, " +
45+
"sunt in culpa qui officia deserunt mollit anim id est laborum."
46+
3947
@JvmField
4048
@Rule
4149
var activityRule = ActivityTestRule(FlexboxTestActivity::class.java)
@@ -325,6 +333,72 @@ class FlexboxHelperTest {
325333
assertThat(view4.measuredHeight, `is`(125))
326334
}
327335

336+
@Test
337+
@Throws(Throwable::class)
338+
fun testDetermineMainSize_directionRow_fixedSizeViewAndShrinkable_doNotExceedMaxMainSize() {
339+
val activity = activityRule.activity
340+
val lp1 = FlexboxLayout.LayoutParams(100, 100)
341+
val view1 = View(activity)
342+
lp1.flexShrink = 0f
343+
view1.layoutParams = lp1
344+
val lp2 = FlexboxLayout.LayoutParams(
345+
FlexboxLayout.LayoutParams.WRAP_CONTENT,
346+
FlexboxLayout.LayoutParams.WRAP_CONTENT)
347+
val view2 = TextView(activity)
348+
view2.layoutParams = lp2
349+
view2.text = LONG_TEXT
350+
flexContainer.addView(view1)
351+
flexContainer.addView(view2)
352+
flexContainer.flexWrap = FlexWrap.NOWRAP
353+
val widthMeasureSpec = View.MeasureSpec.makeMeasureSpec(500, View.MeasureSpec.AT_MOST)
354+
val heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(1000, View.MeasureSpec.UNSPECIFIED)
355+
val result = FlexboxHelper.FlexLinesResult()
356+
flexboxHelper.calculateHorizontalFlexLines(result, widthMeasureSpec, heightMeasureSpec)
357+
flexContainer.flexLines = result.mFlexLines
358+
flexboxHelper.determineMainSize(widthMeasureSpec, heightMeasureSpec)
359+
360+
// Container with WRAP_CONTENT and a max width forces resizable children to shrink
361+
// to avoid exceeding max available space.
362+
assertThat(view1.measuredWidth, `is`(100))
363+
assertThat(view2.measuredWidth, `is`(400))
364+
}
365+
366+
@Test
367+
@Throws(Throwable::class)
368+
fun testDetermineMainSize_directionRow_twoFixedSizeViewsAndShrinkable_doNotExceedMaxMainSize() {
369+
val activity = activityRule.activity
370+
val lp1 = FlexboxLayout.LayoutParams(100, 100)
371+
val view1 = View(activity)
372+
lp1.flexShrink = 0f
373+
view1.layoutParams = lp1
374+
val lp2 = FlexboxLayout.LayoutParams(
375+
FlexboxLayout.LayoutParams.WRAP_CONTENT,
376+
FlexboxLayout.LayoutParams.WRAP_CONTENT)
377+
val view2 = TextView(activity)
378+
view2.layoutParams = lp2
379+
view2.text = LONG_TEXT
380+
val lp3 = FlexboxLayout.LayoutParams(100, 100)
381+
val view3 = View(activity)
382+
lp3.flexShrink = 0f
383+
view3.layoutParams = lp3
384+
flexContainer.addView(view1)
385+
flexContainer.addView(view2)
386+
flexContainer.addView(view3)
387+
flexContainer.flexWrap = FlexWrap.NOWRAP
388+
val widthMeasureSpec = View.MeasureSpec.makeMeasureSpec(500, View.MeasureSpec.AT_MOST)
389+
val heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(1000, View.MeasureSpec.UNSPECIFIED)
390+
val result = FlexboxHelper.FlexLinesResult()
391+
flexboxHelper.calculateHorizontalFlexLines(result, widthMeasureSpec, heightMeasureSpec)
392+
flexContainer.flexLines = result.mFlexLines
393+
flexboxHelper.determineMainSize(widthMeasureSpec, heightMeasureSpec)
394+
395+
// Container with WRAP_CONTENT and a max width forces resizable children to shrink
396+
// to avoid exceeding max available space.
397+
assertThat(view1.measuredWidth, `is`(100))
398+
assertThat(view2.measuredWidth, `is`(300))
399+
assertThat(view3.measuredWidth, `is`(100))
400+
}
401+
328402
@Test
329403
@Throws(Throwable::class)
330404
fun testDetermineCrossSize_direction_row_alignContent_stretch() {

flexbox/src/main/java/com/google/android/flexbox/FlexboxHelper.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -946,10 +946,11 @@ void determineMainSize(int widthMeasureSpec, int heightMeasureSpec, int fromInde
946946
case FlexDirection.ROW_REVERSE:
947947
int widthMode = View.MeasureSpec.getMode(widthMeasureSpec);
948948
int widthSize = View.MeasureSpec.getSize(widthMeasureSpec);
949+
int largestMainSize = mFlexContainer.getLargestMainSize();
949950
if (widthMode == View.MeasureSpec.EXACTLY) {
950951
mainSize = widthSize;
951952
} else {
952-
mainSize = mFlexContainer.getLargestMainSize();
953+
mainSize = largestMainSize > widthSize ? widthSize : largestMainSize;
953954
}
954955
paddingAlongMainAxis = mFlexContainer.getPaddingLeft()
955956
+ mFlexContainer.getPaddingRight();

0 commit comments

Comments
 (0)