提交 79ce8e82 编写于 作者: Y Yuichi Araki

Merge pull request #60 from google/add_wrapping_attribute

Add the layout_wrapBefore attribute.
...@@ -166,6 +166,16 @@ Also you can specify the following attributes for the children of a FlexboxLayou ...@@ -166,6 +166,16 @@ Also you can specify the following attributes for the children of a FlexboxLayou
`flexDirection` attribute as to which attribute imposes the size constraint along the `flexDirection` attribute as to which attribute imposes the size constraint along the
main axis) regardless of the `layout_flexGrow` attribute. main axis) regardless of the `layout_flexGrow` attribute.
* layout_wrapBefore
* This attribute forces a flex line wrapping. i.e. if this is set to `true` for a
flex item, the item will become the first item of a flex line. (A wrapping happens
regardless of the flex items being processed in the the previous flex line)
This attribute is ignored if the `flex_wrap` attribute is set to `nowrap`.
The equivalent attribute isn't defined in the original CSS Flexible Box Module
specification, but having this attribute is useful for Android developers to flatten
the layouts when building a grid like layout or for a situation where developers want
to put a new flex line to make a semantic difference from the previous one, etc.
## Known differences from the original CSS specification ## Known differences from the original CSS specification
This library tries to achieve the same capabilities of the original This library tries to achieve the same capabilities of the original
[Flexible Box specification](https://www.w3.org/TR/css-flexbox-1) as much as possible, [Flexible Box specification](https://www.w3.org/TR/css-flexbox-1) as much as possible,
...@@ -194,6 +204,11 @@ equivalent attribute ...@@ -194,6 +204,11 @@ equivalent attribute
accepts percentage values, which can't be done through layout_width (or layout_height) for accepts percentage values, which can't be done through layout_width (or layout_height) for
simplicity. simplicity.
(4) `layout_wrapBefore` is introduced.
* The equivalent attribute doesn't exist in the CSS Flexible Box Module speicification,
but as explained above, Android developers will benefit by having this attribute for having
more control over when a wrapping happens.
## How to make contributions ## How to make contributions
Please read and follow the steps in [CONTRIBUTING.md](https://github.com/google/flexbox-layout/blob/master/CONTRIBUTING.md) Please read and follow the steps in [CONTRIBUTING.md](https://github.com/google/flexbox-layout/blob/master/CONTRIBUTING.md)
......
...@@ -76,6 +76,8 @@ public class FlexItem implements Parcelable { ...@@ -76,6 +76,8 @@ public class FlexItem implements Parcelable {
/** Maximum height in DP */ /** Maximum height in DP */
public int maxHeight; public int maxHeight;
public boolean wrapBefore;
public FlexItem() { public FlexItem() {
} }
...@@ -106,6 +108,7 @@ public class FlexItem implements Parcelable { ...@@ -106,6 +108,7 @@ public class FlexItem implements Parcelable {
dest.writeInt(this.minHeight); dest.writeInt(this.minHeight);
dest.writeInt(this.maxWidth); dest.writeInt(this.maxWidth);
dest.writeInt(this.maxHeight); dest.writeInt(this.maxHeight);
dest.writeByte((byte) (wrapBefore ? 1 : 0));
} }
protected FlexItem(Parcel in) { protected FlexItem(Parcel in) {
...@@ -129,6 +132,7 @@ public class FlexItem implements Parcelable { ...@@ -129,6 +132,7 @@ public class FlexItem implements Parcelable {
this.minHeight = in.readInt(); this.minHeight = in.readInt();
this.maxWidth = in.readInt(); this.maxWidth = in.readInt();
this.maxHeight = in.readInt(); this.maxHeight = in.readInt();
this.wrapBefore = in.readByte() != 0;
} }
public FlexboxLayout.LayoutParams toLayoutParams(Context context) { public FlexboxLayout.LayoutParams toLayoutParams(Context context) {
...@@ -148,6 +152,7 @@ public class FlexItem implements Parcelable { ...@@ -148,6 +152,7 @@ public class FlexItem implements Parcelable {
lp.minHeight = Util.dpToPixel(context, minHeight); lp.minHeight = Util.dpToPixel(context, minHeight);
lp.maxWidth = Util.dpToPixel(context, maxWidth); lp.maxWidth = Util.dpToPixel(context, maxWidth);
lp.maxHeight = Util.dpToPixel(context, maxHeight); lp.maxHeight = Util.dpToPixel(context, maxHeight);
lp.wrapBefore = wrapBefore;
return lp; return lp;
} }
...@@ -174,6 +179,7 @@ public class FlexItem implements Parcelable { ...@@ -174,6 +179,7 @@ public class FlexItem implements Parcelable {
flexItem.minHeight = Util.pixelToDp(view.getContext(), lp.minHeight); flexItem.minHeight = Util.pixelToDp(view.getContext(), lp.minHeight);
flexItem.maxWidth = Util.pixelToDp(view.getContext(), lp.maxWidth); flexItem.maxWidth = Util.pixelToDp(view.getContext(), lp.maxWidth);
flexItem.maxHeight = Util.pixelToDp(view.getContext(), lp.maxHeight); flexItem.maxHeight = Util.pixelToDp(view.getContext(), lp.maxHeight);
flexItem.wrapBefore = lp.wrapBefore;
return flexItem; return flexItem;
} }
......
...@@ -43,6 +43,8 @@ import android.view.inputmethod.InputMethodManager; ...@@ -43,6 +43,8 @@ import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView; import android.widget.AdapterView;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.Button; import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText; import android.widget.EditText;
import android.widget.Spinner; import android.widget.Spinner;
import android.widget.TextView; import android.widget.TextView;
...@@ -228,6 +230,15 @@ public class FlexItemEditFragment extends DialogFragment { ...@@ -228,6 +230,15 @@ public class FlexItemEditFragment extends DialogFragment {
// No op // No op
} }
}); });
CheckBox wrapBeforeCheckBox = (CheckBox) view.findViewById(R.id.checkbox_wrap_before);
wrapBeforeCheckBox.setChecked(mFlexItem.wrapBefore);
wrapBeforeCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
mFlexItem.wrapBefore = isChecked;
}
});
int alignSelfPosition = arrayAdapter.getPosition(alignSelfAsString(mFlexItem.alignSelf)); int alignSelfPosition = arrayAdapter.getPosition(alignSelfAsString(mFlexItem.alignSelf));
alignSelfSpinner.setSelection(alignSelfPosition); alignSelfSpinner.setSelection(alignSelfPosition);
......
...@@ -20,7 +20,7 @@ limitations under the License. ...@@ -20,7 +20,7 @@ limitations under the License.
android:layout_marginEnd="@dimen/activity_horizontal_margin" android:layout_marginEnd="@dimen/activity_horizontal_margin"
android:layout_marginStart="@dimen/activity_horizontal_margin" android:layout_marginStart="@dimen/activity_horizontal_margin"
android:layout_marginTop="@dimen/activity_vertical_margin" android:layout_marginTop="@dimen/activity_vertical_margin"
android:layout_marginBottom="@dimen/activity_vertical_margin" > android:layout_marginBottom="@dimen/activity_vertical_margin">
<com.google.android.flexbox.FlexboxLayout <com.google.android.flexbox.FlexboxLayout
android:layout_width="match_parent" android:layout_width="match_parent"
...@@ -33,8 +33,7 @@ limitations under the License. ...@@ -33,8 +33,7 @@ limitations under the License.
android:id="@+id/input_layout_order" android:id="@+id/input_layout_order"
android:layout_width="100dp" android:layout_width="100dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:layout_flexGrow="1" app:layout_flexGrow="1">
app:layout_flexBasisPercent="30%">
<EditText <EditText
android:id="@+id/edit_text_order" android:id="@+id/edit_text_order"
...@@ -50,8 +49,7 @@ limitations under the License. ...@@ -50,8 +49,7 @@ limitations under the License.
android:id="@+id/input_layout_flex_grow" android:id="@+id/input_layout_flex_grow"
android:layout_width="100dp" android:layout_width="100dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:layout_flexGrow="1" app:layout_flexGrow="1">
app:layout_flexBasisPercent="30%">
<EditText <EditText
android:id="@+id/edit_text_flex_grow" android:id="@+id/edit_text_flex_grow"
...@@ -67,8 +65,7 @@ limitations under the License. ...@@ -67,8 +65,7 @@ limitations under the License.
android:id="@+id/input_layout_flex_shrink" android:id="@+id/input_layout_flex_shrink"
android:layout_width="100dp" android:layout_width="100dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:layout_flexGrow="1" app:layout_flexGrow="1">
app:layout_flexBasisPercent="30%">
<EditText <EditText
android:id="@+id/edit_text_flex_shrink" android:id="@+id/edit_text_flex_shrink"
...@@ -82,10 +79,9 @@ limitations under the License. ...@@ -82,10 +79,9 @@ limitations under the License.
<android.support.design.widget.TextInputLayout <android.support.design.widget.TextInputLayout
android:id="@+id/input_layout_flex_basis_percent" android:id="@+id/input_layout_flex_basis_percent"
android:layout_width="150dp" android:layout_width="200dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:layout_flexGrow="1" app:layout_flexGrow="1">
app:layout_flexBasisPercent="90%">
<EditText <EditText
android:id="@+id/edit_text_flex_basis_percent" android:id="@+id/edit_text_flex_basis_percent"
...@@ -101,6 +97,7 @@ limitations under the License. ...@@ -101,6 +97,7 @@ limitations under the License.
android:id="@+id/input_layout_width" android:id="@+id/input_layout_width"
android:layout_width="300dp" android:layout_width="300dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:layout_wrapBefore="true"
app:layout_flexGrow="1"> app:layout_flexGrow="1">
<EditText <EditText
...@@ -133,6 +130,7 @@ limitations under the License. ...@@ -133,6 +130,7 @@ limitations under the License.
android:id="@+id/input_layout_min_width" android:id="@+id/input_layout_min_width"
android:layout_width="150dp" android:layout_width="150dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:layout_wrapBefore="true"
app:layout_flexGrow="1"> app:layout_flexGrow="1">
<EditText <EditText
...@@ -193,18 +191,23 @@ limitations under the License. ...@@ -193,18 +191,23 @@ limitations under the License.
android:hint="@string/hint_max_height" /> android:hint="@string/hint_max_height" />
</android.support.design.widget.TextInputLayout> </android.support.design.widget.TextInputLayout>
<CheckBox
android:id="@+id/checkbox_wrap_before"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:text="@string/hint_wrap_before"
app:layout_wrapBefore="true"
app:layout_flexGrow="1" />
<LinearLayout <LinearLayout
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="horizontal"> android:orientation="horizontal"
app:layout_flexGrow="1">
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:paddingEnd="@dimen/margin_tiny"
android:paddingLeft="@dimen/margin_tiny"
android:paddingRight="@dimen/margin_tiny"
android:paddingStart="@dimen/margin_tiny"
android:text="@string/hint_align_self" /> android:text="@string/hint_align_self" />
<Spinner <Spinner
...@@ -215,6 +218,7 @@ limitations under the License. ...@@ -215,6 +218,7 @@ limitations under the License.
android:gravity="end" /> android:gravity="end" />
</LinearLayout> </LinearLayout>
<LinearLayout <LinearLayout
android:id="@+id/button_panel" android:id="@+id/button_panel"
android:layout_width="match_parent" android:layout_width="match_parent"
......
...@@ -104,6 +104,7 @@ limitations under the License. ...@@ -104,6 +104,7 @@ limitations under the License.
<string name="hint_min_height">Min Height</string> <string name="hint_min_height">Min Height</string>
<string name="hint_max_width">Max Width</string> <string name="hint_max_width">Max Width</string>
<string name="hint_max_height">Max Height</string> <string name="hint_max_height">Max Height</string>
<string name="hint_wrap_before">Wrap Before</string>
<string name="must_be_non_negative_float">Must be a non-negative float value</string> <string name="must_be_non_negative_float">Must be a non-negative float value</string>
<string name="must_be_non_negative_integer">Must be a non-negative integer value</string> <string name="must_be_non_negative_integer">Must be a non-negative integer value</string>
......
...@@ -2757,6 +2757,83 @@ public class FlexboxAndroidTest { ...@@ -2757,6 +2757,83 @@ public class FlexboxAndroidTest {
assertThat(textView3.getTop(), is(textView1.getBottom())); assertThat(textView3.getTop(), is(textView1.getBottom()));
} }
@Test
@FlakyTest(tolerance = TOLERANCE)
public void testWrapBefore() throws Throwable {
final FlexboxTestActivity activity = mActivityRule.getActivity();
mActivityRule.runOnUiThread(new Runnable() {
@Override
public void run() {
activity.setContentView(R.layout.activity_wrap_before_test);
}
});
FlexboxLayout flexboxLayout = (FlexboxLayout) activity.findViewById(R.id.flexbox_layout);
// layout_wrapBefore for the text2 and text3 are set to true, the text2 and text3 should
// be the first item for each flex line.
assertThat(flexboxLayout.getFlexWrap(), is(FlexboxLayout.FLEX_WRAP_WRAP));
assertThat(flexboxLayout.getFlexDirection(), is(FlexboxLayout.FLEX_DIRECTION_ROW));
onView(withId(R.id.text1)).check(isTopAlignedWith(withId(R.id.flexbox_layout)));
onView(withId(R.id.text1)).check(isLeftAlignedWith(withId(R.id.flexbox_layout)));
onView(withId(R.id.text2)).check(isLeftAlignedWith(withId(R.id.flexbox_layout)));
onView(withId(R.id.text2)).check(isBelow(withId(R.id.text1)));
onView(withId(R.id.text3)).check(isLeftAlignedWith(withId(R.id.flexbox_layout)));
onView(withId(R.id.text3)).check(isBelow(withId(R.id.text2)));
TextView textView1 = (TextView) activity.findViewById(R.id.text1);
final TextView textView2 = (TextView) activity.findViewById(R.id.text2);
TextView textView3 = (TextView) activity.findViewById(R.id.text3);
assertThat(flexboxLayout.getHeight(), is(textView1.getHeight() + textView2.getHeight() +
textView3.getHeight()));
mActivityRule.runOnUiThread(new Runnable() {
@Override
public void run() {
FlexboxLayout.LayoutParams lp2 = (FlexboxLayout.LayoutParams)
textView2.getLayoutParams();
lp2.wrapBefore = false;
textView2.setLayoutParams(lp2);
}
});
onView(withId(R.id.text1)).check(isTopAlignedWith(withId(R.id.flexbox_layout)));
onView(withId(R.id.text1)).check(isLeftAlignedWith(withId(R.id.flexbox_layout)));
onView(withId(R.id.text2)).check(isTopAlignedWith(withId(R.id.flexbox_layout)));
onView(withId(R.id.text2)).check(isRightOf(withId(R.id.text1)));
onView(withId(R.id.text3)).check(isLeftAlignedWith(withId(R.id.flexbox_layout)));
onView(withId(R.id.text3)).check(isBelow(withId(R.id.text1)));
onView(withId(R.id.text3)).check(isBelow(withId(R.id.text2)));
assertThat(flexboxLayout.getHeight(), is(textView1.getHeight() + textView3.getHeight()));
}
@Test
@FlakyTest(tolerance = TOLERANCE)
public void testWrapBefore_nowrap() throws Throwable {
final FlexboxTestActivity activity = mActivityRule.getActivity();
mActivityRule.runOnUiThread(new Runnable() {
@Override
public void run() {
activity.setContentView(R.layout.activity_wrap_before_test);
FlexboxLayout flexboxLayout = (FlexboxLayout) activity.findViewById(R.id.flexbox_layout);
flexboxLayout.setFlexWrap(FlexboxLayout.FLEX_WRAP_NOWRAP);
}
});
FlexboxLayout flexboxLayout = (FlexboxLayout) activity.findViewById(R.id.flexbox_layout);
// layout_wrapBefore for the text2 and text3 are set to true, but the flexWrap is set to
// FLEX_WRAP_NOWRAP, three text views should not be wrapped.
assertThat(flexboxLayout.getFlexWrap(), is(FlexboxLayout.FLEX_WRAP_NOWRAP));
assertThat(flexboxLayout.getFlexDirection(), is(FlexboxLayout.FLEX_DIRECTION_ROW));
onView(withId(R.id.text1)).check(isTopAlignedWith(withId(R.id.flexbox_layout)));
onView(withId(R.id.text1)).check(isLeftAlignedWith(withId(R.id.flexbox_layout)));
onView(withId(R.id.text1)).check(isBottomAlignedWith(withId(R.id.flexbox_layout)));
onView(withId(R.id.text2)).check(isTopAlignedWith(withId(R.id.flexbox_layout)));
onView(withId(R.id.text2)).check(isRightOf(withId(R.id.text1)));
onView(withId(R.id.text2)).check(isBottomAlignedWith(withId(R.id.flexbox_layout)));
onView(withId(R.id.text3)).check(isTopAlignedWith(withId(R.id.flexbox_layout)));
onView(withId(R.id.text3)).check(isRightOf(withId(R.id.text2)));
onView(withId(R.id.text3)).check(isBottomAlignedWith(withId(R.id.flexbox_layout)));
}
private TextView createTextView(Context context, String text, int order) { private TextView createTextView(Context context, String text, int order) {
TextView textView = new TextView(context); TextView textView = new TextView(context);
textView.setText(text); textView.setText(text);
......
<?xml version="1.0" encoding="utf-8"?><!--
Copyright 2016 Google Inc. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<com.google.android.flexbox.FlexboxLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/flexbox_layout"
android:layout_width="360dp"
android:layout_height="wrap_content"
app:flexDirection="row"
app:flexWrap="wrap">
<TextView
android:id="@+id/text1"
android:layout_width="100dp"
android:layout_height="80dp"
android:text="1" />
<TextView
android:id="@+id/text2"
android:layout_width="100dp"
android:layout_height="80dp"
android:text="2"
app:layout_wrapBefore="true" />
<TextView
android:id="@+id/text3"
android:layout_width="100dp"
android:layout_height="80dp"
android:text="3"
app:layout_wrapBefore="true" />
</com.google.android.flexbox.FlexboxLayout>
\ No newline at end of file
...@@ -494,7 +494,7 @@ public class FlexboxLayout extends ViewGroup { ...@@ -494,7 +494,7 @@ public class FlexboxLayout extends ViewGroup {
child.getMeasuredHeight() + lp.topMargin + lp.bottomMargin); child.getMeasuredHeight() + lp.topMargin + lp.bottomMargin);
if (isWrapRequired(mFlexWrap, widthMode, widthSize, flexLine.mainSize, if (isWrapRequired(mFlexWrap, widthMode, widthSize, flexLine.mainSize,
child.getMeasuredWidth())) { child.getMeasuredWidth(), lp)) {
flexLine.mainSize += paddingEnd; flexLine.mainSize += paddingEnd;
mFlexLines.add(flexLine); mFlexLines.add(flexLine);
...@@ -645,7 +645,7 @@ public class FlexboxLayout extends ViewGroup { ...@@ -645,7 +645,7 @@ public class FlexboxLayout extends ViewGroup {
child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin); child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin);
if (isWrapRequired(mFlexWrap, heightMode, heightSize, flexLine.mainSize, if (isWrapRequired(mFlexWrap, heightMode, heightSize, flexLine.mainSize,
child.getMeasuredHeight())) { child.getMeasuredHeight(), lp)) {
flexLine.mainSize += paddingBottom; flexLine.mainSize += paddingBottom;
mFlexLines.add(flexLine); mFlexLines.add(flexLine);
...@@ -1354,14 +1354,21 @@ public class FlexboxLayout extends ViewGroup { ...@@ -1354,14 +1354,21 @@ public class FlexboxLayout extends ViewGroup {
* @param maxSize the max size along the main axis direction * @param maxSize the max size along the main axis direction
* @param currentLength the accumulated current length * @param currentLength the accumulated current length
* @param childLength the length of a child view which is to be collected to the flex line * @param childLength the length of a child view which is to be collected to the flex line
* @param lp the LayoutParams for the view being determined whether a new flex line
* is needed
* @return {@code true} if a wrap is required, {@code false} otherwise * @return {@code true} if a wrap is required, {@code false} otherwise
* @see #getFlexWrap() * @see #getFlexWrap()
* @see #setFlexWrap(int) * @see #setFlexWrap(int)
*/ */
private boolean isWrapRequired(int flexWrap, int mode, int maxSize, private boolean isWrapRequired(int flexWrap, int mode, int maxSize,
int currentLength, int childLength) { int currentLength, int childLength, LayoutParams lp) {
return flexWrap != FLEX_WRAP_NOWRAP && if (flexWrap == FLEX_WRAP_NOWRAP) {
(mode == MeasureSpec.EXACTLY || mode == MeasureSpec.AT_MOST) && return false;
}
if (lp.wrapBefore) {
return true;
}
return (mode == MeasureSpec.EXACTLY || mode == MeasureSpec.AT_MOST) &&
maxSize < currentLength + childLength; maxSize < currentLength + childLength;
} }
...@@ -1976,6 +1983,18 @@ public class FlexboxLayout extends ViewGroup { ...@@ -1976,6 +1983,18 @@ public class FlexboxLayout extends ViewGroup {
*/ */
public int maxHeight = MAX_SIZE; public int maxHeight = MAX_SIZE;
/**
* This attribute forces a flex line wrapping. i.e. if this is set to {@code true} for a
* flex item, the item will become the first item of the new flex line. (A wrapping happens
* regardless of the flex items being processed in the the previous flex line)
* This attribute is ignored if the flex_wrap attribute is set as nowrap.
* The equivalent attribute isn't defined in the original CSS Flexible Box Module
* specification, but having this attribute is useful for Android developers to flatten
* the layouts when building a grid like layout or for a situation where developers want
* to put a new flex line to make a semantic difference from the previous one, etc.
*/
public boolean wrapBefore;
public LayoutParams(Context context, AttributeSet attrs) { public LayoutParams(Context context, AttributeSet attrs) {
super(context, attrs); super(context, attrs);
...@@ -1998,6 +2017,7 @@ public class FlexboxLayout extends ViewGroup { ...@@ -1998,6 +2017,7 @@ public class FlexboxLayout extends ViewGroup {
MAX_SIZE); MAX_SIZE);
maxHeight = a.getDimensionPixelSize(R.styleable.FlexboxLayout_Layout_layout_maxHeight, maxHeight = a.getDimensionPixelSize(R.styleable.FlexboxLayout_Layout_layout_maxHeight,
MAX_SIZE); MAX_SIZE);
wrapBefore = a.getBoolean(R.styleable.FlexboxLayout_Layout_layout_wrapBefore, false);
a.recycle(); a.recycle();
} }
......
...@@ -104,5 +104,17 @@ limitations under the License. ...@@ -104,5 +104,17 @@ limitations under the License.
<attr name="layout_minHeight" format="dimension" /> <attr name="layout_minHeight" format="dimension" />
<attr name="layout_maxWidth" format="dimension" /> <attr name="layout_maxWidth" format="dimension" />
<attr name="layout_maxHeight" format="dimension" /> <attr name="layout_maxHeight" format="dimension" />
<!--
This attribute forces a flex line wrapping. i.e. if this is set to true for a
flex item, the item will become the first item of a flex line. (A wrapping happens
regardless of the flex items being processed in the the previous flex line)
This attribute is ignored if the flex_wrap attribute is set to nowrap.
The equivalent attribute isn't defined in the original CSS Flexible Box Module
specification, but having this attribute is useful for Android developers to flatten
the layouts when building a grid like layout or for a situation where developers want
to put a new flex line to make a semantic difference from the previous one, etc.
-->
<attr name="layout_wrapBefore" format="boolean" />
</declare-styleable> </declare-styleable>
</resources> </resources>
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册