未验证 提交 d6c186b1 编写于 作者: T Takeshi Hagikura 提交者: GitHub

Reduce the number of measure calls for children of Flexbox (#514)

This PR reduces the number of measure calls for the children of the
Flexbox.
If any items in a FlexLine don't have the flexGrow or flexShrink
attributes set, the children in the FlexLine don't have to be measured
in the FlexboxHelper#determineMainSize method.

Similarly, if the AlignItems attribute for the Flexbox is not equal to
AlignItems.STRETCH nor any items in a FlexLine don't have the
AlignSelf.STRETCH attributes, the items in the FlexLine don't have to be
measured in the FlexboxHelpers#stretchViews method.

Also this PR changes the default values of FlexboxLayout as follows:
- mAlignItems: STRETCH -> FLEX_START
- mAlignContent: STRETCH -> FLEX_START
上级 441e885e
......@@ -427,4 +427,43 @@ class FlexboxHelperTest {
assertThat(flexboxHelper.extractHigherInt(combined), `is`(higher))
assertThat(flexboxHelper.extractLowerInt(combined), `is`(lower))
}
@Test
fun testFlexLine_anyItemsHaveFlexGrow() {
val activity = activityRule.activity
val lp1 = FlexboxLayout.LayoutParams(100, 100).apply {
flexGrow = 1.0f
}
val view1 = View(activity)
view1.layoutParams = lp1
val lp2 = FlexboxLayout.LayoutParams(100, 200)
val view2 = View(activity)
view2.layoutParams = lp2
val lp3 = FlexboxLayout.LayoutParams(100, 300)
val view3 = View(activity)
view3.layoutParams = lp3
val lp4 = FlexboxLayout.LayoutParams(100, 400).apply {
flexGrow = 2.0f
}
val view4 = View(activity)
view4.layoutParams = lp4
flexContainer.apply {
addView(view1)
addView(view2)
addView(view3)
addView(view4)
flexDirection = FlexDirection.COLUMN
flexWrap = FlexWrap.WRAP
alignContent = AlignContent.STRETCH
}
val widthMeasureSpec = View.MeasureSpec.makeMeasureSpec(1000, View.MeasureSpec.EXACTLY)
val heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(500, View.MeasureSpec.EXACTLY)
val result = FlexboxHelper.FlexLinesResult()
flexboxHelper.calculateVerticalFlexLines(result, widthMeasureSpec, heightMeasureSpec)
flexContainer.flexLines = result.mFlexLines
assertThat(flexContainer.flexLines.size, `is`(3))
assertThat(flexContainer.flexLines[0].mAnyItemsHaveFlexGrow, `is`(true))
assertThat(flexContainer.flexLines[1].mAnyItemsHaveFlexGrow, `is`(false))
assertThat(flexContainer.flexLines[2].mAnyItemsHaveFlexGrow, `is`(true))
}
}
......@@ -833,6 +833,7 @@ class FlexboxAndroidTest {
override fun apply(flexboxLayout: FlexboxLayout) {
flexboxLayout.justifyContent = JustifyContent.FLEX_END
flexboxLayout.flexDirection = FlexDirection.COLUMN
flexboxLayout.alignItems = AlignItems.STRETCH
}
})
......
......@@ -20,7 +20,8 @@
android:layout_height="360dp"
app:flexDirection="row"
app:flexWrap="wrap"
app:alignItems="stretch">
app:alignItems="stretch"
app:alignContent="stretch" >
<TextView
android:id="@+id/text1"
......
......@@ -35,6 +35,9 @@ interface FlexItem extends Parcelable {
/** The default value for the flex shrink attribute */
float FLEX_SHRINK_DEFAULT = 1f;
/** The value representing the flex shrink attribute is not set */
float FLEX_SHRINK_NOT_SET = 0f;
/** The default value for the flex basis percent attribute */
float FLEX_BASIS_PERCENT_DEFAULT = -1f;
......
......@@ -65,7 +65,7 @@ public class FlexLine {
/**
* The largest value of the individual child's baseline (obtained by View#getBaseline()
* if the {@link FlexboxLayout#mAlignItems} value is not {@link AlignItems#BASELINE}
* if the {@link FlexContainer#getAlignItems()} value is not {@link AlignItems#BASELINE}
* or the flex direction is vertical, this value is not used.
* If the alignment direction is from the bottom to top,
* (e.g. flexWrap == WRAP_REVERSE and flexDirection == ROW)
......@@ -90,6 +90,18 @@ public class FlexLine {
int mLastIndex;
/**
* Set to true if any {@link FlexItem}s in this line have {@link FlexItem#getFlexGrow()}
* attributes set (have the value other than {@link FlexItem#FLEX_GROW_DEFAULT})
*/
boolean mAnyItemsHaveFlexGrow;
/**
* Set to true if any {@link FlexItem}s in this line have {@link FlexItem#getFlexShrink()}
* attributes set (have the value other than {@link FlexItem#FLEX_SHRINK_NOT_SET})
*/
boolean mAnyItemsHaveFlexShrink;
/**
* @return the size of the flex line in pixels along the main axis of the flex container.
*/
......
......@@ -18,6 +18,9 @@ package com.google.android.flexbox;
import static com.google.android.flexbox.FlexContainer.NOT_SET;
import static com.google.android.flexbox.FlexItem.FLEX_BASIS_PERCENT_DEFAULT;
import static com.google.android.flexbox.FlexItem.FLEX_GROW_DEFAULT;
import static com.google.android.flexbox.FlexItem.FLEX_SHRINK_DEFAULT;
import static com.google.android.flexbox.FlexItem.FLEX_SHRINK_NOT_SET;
import static androidx.recyclerview.widget.RecyclerView.NO_POSITION;
......@@ -554,6 +557,9 @@ class FlexboxHelper {
flexLine.mItemCount++;
indexInFlexLine++;
}
flexLine.mAnyItemsHaveFlexGrow |= flexItem.getFlexGrow() != FLEX_GROW_DEFAULT;
flexLine.mAnyItemsHaveFlexShrink |= flexItem.getFlexShrink() != FLEX_SHRINK_NOT_SET;
if (mIndexToFlexLine != null) {
mIndexToFlexLine[i] = flexLines.size();
}
......@@ -971,10 +977,10 @@ class FlexboxHelper {
List<FlexLine> flexLines = mFlexContainer.getFlexLinesInternal();
for (int i = flexLineIndex, size = flexLines.size(); i < size; i++) {
FlexLine flexLine = flexLines.get(i);
if (flexLine.mMainSize < mainSize) {
if (flexLine.mMainSize < mainSize && flexLine.mAnyItemsHaveFlexGrow) {
expandFlexItems(widthMeasureSpec, heightMeasureSpec, flexLine,
mainSize, paddingAlongMainAxis, false);
} else {
} else if (flexLine.mMainSize > mainSize && flexLine.mAnyItemsHaveFlexShrink) {
shrinkFlexItems(widthMeasureSpec, heightMeasureSpec, flexLine,
mainSize, paddingAlongMainAxis, false);
}
......@@ -1571,7 +1577,7 @@ class FlexboxHelper {
/**
* Expand the view if the {@link FlexContainer#getAlignItems()} attribute is set to {@link
* AlignItems#STRETCH} or {@link FlexboxLayout.LayoutParams#mAlignSelf} is set as
* AlignItems#STRETCH} or {@link FlexItem#getAlignSelf()} is set as
* {@link AlignItems#STRETCH}.
*
* @param fromIndex the index from which value, stretch is calculated
......@@ -1579,7 +1585,7 @@ class FlexboxHelper {
* @see FlexContainer#setFlexDirection(int)
* @see FlexContainer#getAlignItems()
* @see FlexContainer#setAlignItems(int)
* @see FlexboxLayout.LayoutParams#mAlignSelf
* @see FlexItem#getAlignSelf()
*/
void stretchViews(int fromIndex) {
if (fromIndex >= mFlexContainer.getFlexItemCount()) {
......@@ -2008,6 +2014,7 @@ class FlexboxHelper {
return index - another.index;
}
@NonNull
@Override
public String toString() {
return "Order{" +
......
......@@ -102,7 +102,7 @@ public class FlexboxLayout extends ViewGroup implements FlexContainer {
/**
* The current value of the {@link AlignItems}, the default value is
* {@link AlignItems#STRETCH}.
* {@link AlignItems#FLEX_START}.
*
* @see AlignItems
*/
......@@ -110,7 +110,7 @@ public class FlexboxLayout extends ViewGroup implements FlexContainer {
/**
* The current value of the {@link AlignContent}, the default value is
* {@link AlignContent#STRETCH}.
* {@link AlignContent#FLEX_START}.
*
* @see AlignContent
*/
......@@ -223,8 +223,8 @@ public class FlexboxLayout extends ViewGroup implements FlexContainer {
mFlexWrap = a.getInt(R.styleable.FlexboxLayout_flexWrap, FlexWrap.NOWRAP);
mJustifyContent = a
.getInt(R.styleable.FlexboxLayout_justifyContent, JustifyContent.FLEX_START);
mAlignItems = a.getInt(R.styleable.FlexboxLayout_alignItems, AlignItems.STRETCH);
mAlignContent = a.getInt(R.styleable.FlexboxLayout_alignContent, AlignContent.STRETCH);
mAlignItems = a.getInt(R.styleable.FlexboxLayout_alignItems, AlignItems.FLEX_START);
mAlignContent = a.getInt(R.styleable.FlexboxLayout_alignContent, AlignContent.FLEX_START);
mMaxLine = a.getInt(R.styleable.FlexboxLayout_maxLine, NOT_SET);
Drawable drawable = a.getDrawable(R.styleable.FlexboxLayout_dividerDrawable);
if (drawable != null) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册