提交 ddeeadc7 编写于 作者: T Takeshi Hagikura

Merge pull request #53 from google/maxWidth_maxHeight

Implement layout_maxWidth/layout_maxHeight attributes
...@@ -64,12 +64,18 @@ public class FlexItem implements Parcelable { ...@@ -64,12 +64,18 @@ public class FlexItem implements Parcelable {
public float flexBasisPercent; public float flexBasisPercent;
/** Minimum with in DP */ /** Minimum width in DP */
public int minWidth; public int minWidth;
/** Minimum height in DP */ /** Minimum height in DP */
public int minHeight; public int minHeight;
/** Maximum width in DP */
public int maxWidth;
/** Maximum height in DP */
public int maxHeight;
public FlexItem() { public FlexItem() {
} }
...@@ -98,6 +104,8 @@ public class FlexItem implements Parcelable { ...@@ -98,6 +104,8 @@ public class FlexItem implements Parcelable {
dest.writeFloat(this.flexBasisPercent); dest.writeFloat(this.flexBasisPercent);
dest.writeInt(this.minWidth); dest.writeInt(this.minWidth);
dest.writeInt(this.minHeight); dest.writeInt(this.minHeight);
dest.writeInt(this.maxWidth);
dest.writeInt(this.maxHeight);
} }
protected FlexItem(Parcel in) { protected FlexItem(Parcel in) {
...@@ -119,6 +127,8 @@ public class FlexItem implements Parcelable { ...@@ -119,6 +127,8 @@ public class FlexItem implements Parcelable {
this.flexBasisPercent = in.readFloat(); this.flexBasisPercent = in.readFloat();
this.minWidth = in.readInt(); this.minWidth = in.readInt();
this.minHeight = in.readInt(); this.minHeight = in.readInt();
this.maxWidth = in.readInt();
this.maxHeight = in.readInt();
} }
public FlexboxLayout.LayoutParams toLayoutParams(Context context) { public FlexboxLayout.LayoutParams toLayoutParams(Context context) {
...@@ -136,6 +146,8 @@ public class FlexItem implements Parcelable { ...@@ -136,6 +146,8 @@ public class FlexItem implements Parcelable {
lp.bottomMargin = bottomMargin; lp.bottomMargin = bottomMargin;
lp.minWidth = Util.dpToPixel(context, minWidth); lp.minWidth = Util.dpToPixel(context, minWidth);
lp.minHeight = Util.dpToPixel(context, minHeight); lp.minHeight = Util.dpToPixel(context, minHeight);
lp.maxWidth = Util.dpToPixel(context, maxWidth);
lp.maxHeight = Util.dpToPixel(context, maxHeight);
return lp; return lp;
} }
...@@ -160,6 +172,8 @@ public class FlexItem implements Parcelable { ...@@ -160,6 +172,8 @@ public class FlexItem implements Parcelable {
flexItem.paddingBottom = view.getPaddingBottom(); flexItem.paddingBottom = view.getPaddingBottom();
flexItem.minWidth = Util.pixelToDp(view.getContext(), lp.minWidth); flexItem.minWidth = Util.pixelToDp(view.getContext(), lp.minWidth);
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.maxHeight = Util.pixelToDp(view.getContext(), lp.maxHeight);
return flexItem; return flexItem;
} }
......
...@@ -2550,6 +2550,92 @@ public class FlexboxAndroidTest { ...@@ -2550,6 +2550,92 @@ public class FlexboxAndroidTest {
+ textView4.getHeight()); + textView4.getHeight());
} }
@Test
@FlakyTest(tolerance = TOLERANCE)
public void testMaxWidth_initial_width_more_than_maxWidth() throws Throwable {
final FlexboxTestActivity activity = mActivityRule.getActivity();
mActivityRule.runOnUiThread(new Runnable() {
@Override
public void run() {
activity.setContentView(R.layout.activity_maxwidth_test);
}
});
// This test case verifies if the maxWidth attribute works as a maximum constraint
// ff the initial view width is more than the value of maxWidth.
FlexboxLayout flexboxLayout = (FlexboxLayout) activity.findViewById(R.id.flexbox_layout);
TextView textView1 = (TextView) activity.findViewById(R.id.text1);
int maxWidth = ((FlexboxLayout.LayoutParams) textView1.getLayoutParams()).maxWidth;
onView(withId(R.id.text1)).check(hasWidth(maxWidth));
onView(withId(R.id.text2)).check(hasWidth(flexboxLayout.getWidth() - maxWidth));
}
@Test
@FlakyTest(tolerance = TOLERANCE)
public void testMaxWidth_works_as_upper_bound_expand_to() throws Throwable {
final FlexboxTestActivity activity = mActivityRule.getActivity();
mActivityRule.runOnUiThread(new Runnable() {
@Override
public void run() {
activity.setContentView(R.layout.activity_maxwidth_upper_bound_test);
}
});
// This test case verifies if the maxWidth attribute works as a upper bound
// when the view would expand more than the maxWidth if the maxWidth weren't set
FlexboxLayout flexboxLayout = (FlexboxLayout) activity.findViewById(R.id.flexbox_layout);
TextView textView1 = (TextView) activity.findViewById(R.id.text1);
TextView textView2 = (TextView) activity.findViewById(R.id.text2);
int maxWidth = ((FlexboxLayout.LayoutParams) textView1.getLayoutParams()).maxWidth;
onView(withId(R.id.text1)).check(hasWidth(maxWidth));
assertEquals(flexboxLayout.getWidth(), textView1.getWidth() + textView2.getWidth());
}
@Test
@FlakyTest(tolerance = TOLERANCE)
public void testMaxHeight_initial_height_more_than_maxHeight() throws Throwable {
final FlexboxTestActivity activity = mActivityRule.getActivity();
mActivityRule.runOnUiThread(new Runnable() {
@Override
public void run() {
activity.setContentView(R.layout.activity_maxheight_test);
}
});
// This test case verifies if the maxHeight attribute works as a maximum constraint
// ff the initial view height is more than the value of maxHeight.
FlexboxLayout flexboxLayout = (FlexboxLayout) activity.findViewById(R.id.flexbox_layout);
TextView textView1 = (TextView) activity.findViewById(R.id.text1);
int maxHeight = ((FlexboxLayout.LayoutParams) textView1.getLayoutParams()).maxHeight;
onView(withId(R.id.text1)).check(hasHeight(maxHeight));
onView(withId(R.id.text2)).check(hasHeight(flexboxLayout.getHeight() - maxHeight));
}
@Test
@FlakyTest(tolerance = TOLERANCE)
public void testMaxHeight_works_as_lower_bound_expand_to() throws Throwable {
final FlexboxTestActivity activity = mActivityRule.getActivity();
mActivityRule.runOnUiThread(new Runnable() {
@Override
public void run() {
activity.setContentView(R.layout.activity_maxheight_upper_bound_test);
}
});
// This test case verifies if the maxHeight attribute works as a upper bound
// when the view would expand more than the maxHeight if the maxHeight weren't set
FlexboxLayout flexboxLayout = (FlexboxLayout) activity.findViewById(R.id.flexbox_layout);
TextView textView1 = (TextView) activity.findViewById(R.id.text1);
TextView textView2 = (TextView) activity.findViewById(R.id.text2);
int maxHeight = ((FlexboxLayout.LayoutParams) textView1.getLayoutParams()).maxHeight;
onView(withId(R.id.text1)).check(hasHeight(maxHeight));
assertEquals(flexboxLayout.getHeight(), textView1.getHeight() + textView2.getHeight());
}
@Test @Test
@FlakyTest(tolerance = TOLERANCE) @FlakyTest(tolerance = TOLERANCE)
public void testView_visibility_gone() throws Throwable { public void testView_visibility_gone() throws Throwable {
......
<?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 android:id="@+id/flexbox_layout"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="400dp"
android:layout_height="400dp"
app:flexDirection="column">
<TextView
android:id="@+id/text1"
android:layout_width="wrap_content"
android:layout_height="150dp"
android:text="1"
app:layout_maxHeight="100dp" />
<TextView
android:id="@+id/text2"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:text="2"
app:layout_flexGrow="1" />
</com.google.android.flexbox.FlexboxLayout>
\ No newline at end of file
<?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 android:id="@+id/flexbox_layout"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="400dp"
android:layout_height="400dp"
app:flexDirection="column"
app:flexWrap="nowrap" >
<TextView
android:id="@+id/text1"
android:layout_width="wrap_content"
android:layout_height="100dp"
android:text="1"
app:layout_flexGrow="1"
app:layout_maxHeight="150dp" />
<TextView
android:id="@+id/text2"
android:layout_width="wrap_content"
android:layout_height="100dp"
app:layout_flexGrow="1"
android:text="2" />
</com.google.android.flexbox.FlexboxLayout>
\ No newline at end of file
<?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 android:id="@+id/flexbox_layout"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="400dp"
android:layout_height="400dp">
<TextView
android:id="@+id/text1"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:text="1"
app:layout_maxWidth="100dp" />
<TextView
android:id="@+id/text2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="2"
app:layout_flexGrow="1" />
</com.google.android.flexbox.FlexboxLayout>
\ No newline at end of file
<?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 android:id="@+id/flexbox_layout"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="400dp"
android:layout_height="400dp"
app:flexWrap="nowrap" >
<TextView
android:id="@+id/text1"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:text="1"
app:layout_flexGrow="1"
app:layout_maxWidth="150dp" />
<TextView
android:id="@+id/text2"
android:layout_width="100dp"
android:layout_height="wrap_content"
app:layout_flexGrow="1"
android:text="2" />
</com.google.android.flexbox.FlexboxLayout>
\ No newline at end of file
...@@ -59,6 +59,8 @@ import java.util.List; ...@@ -59,6 +59,8 @@ import java.util.List;
* <li>{@code layout_alignSelf}</li> * <li>{@code layout_alignSelf}</li>
* <li>{@code layout_minWidth}</li> * <li>{@code layout_minWidth}</li>
* <li>{@code layout_minHeight}</li> * <li>{@code layout_minHeight}</li>
* <li>{@code layout_maxWidth}</li>
* <li>{@code layout_maxHeight}</li>
* </ul> * </ul>
*/ */
public class FlexboxLayout extends ViewGroup { public class FlexboxLayout extends ViewGroup {
...@@ -482,6 +484,10 @@ public class FlexboxLayout extends ViewGroup { ...@@ -482,6 +484,10 @@ public class FlexboxLayout extends ViewGroup {
child.measure(MeasureSpec.makeMeasureSpec(lp.minWidth, MeasureSpec.EXACTLY), child.measure(MeasureSpec.makeMeasureSpec(lp.minWidth, MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(child.getMeasuredHeight(), MeasureSpec.makeMeasureSpec(child.getMeasuredHeight(),
MeasureSpec.EXACTLY)); MeasureSpec.EXACTLY));
} else if (child.getMeasuredWidth() > lp.maxWidth) {
child.measure(MeasureSpec.makeMeasureSpec(lp.maxWidth, MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(child.getMeasuredHeight(),
MeasureSpec.EXACTLY));
} }
childState = ViewCompat childState = ViewCompat
.combineMeasuredStates(childState, ViewCompat.getMeasuredState(child)); .combineMeasuredStates(childState, ViewCompat.getMeasuredState(child));
...@@ -633,6 +639,10 @@ public class FlexboxLayout extends ViewGroup { ...@@ -633,6 +639,10 @@ public class FlexboxLayout extends ViewGroup {
child.measure( child.measure(
MeasureSpec.makeMeasureSpec(child.getMeasuredWidth(), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(child.getMeasuredWidth(), MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(lp.minHeight, MeasureSpec.EXACTLY)); MeasureSpec.makeMeasureSpec(lp.minHeight, MeasureSpec.EXACTLY));
} else if (child.getMeasuredHeight() > lp.maxHeight) {
child.measure(
MeasureSpec.makeMeasureSpec(child.getMeasuredWidth(), MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(lp.maxHeight, MeasureSpec.EXACTLY));
} }
childState = ViewCompat childState = ViewCompat
.combineMeasuredStates(childState, ViewCompat.getMeasuredState(child)); .combineMeasuredStates(childState, ViewCompat.getMeasuredState(child));
...@@ -753,66 +763,106 @@ public class FlexboxLayout extends ViewGroup { ...@@ -753,66 +763,106 @@ public class FlexboxLayout extends ViewGroup {
*/ */
private int expandFlexItems(FlexLine flexLine, @FlexDirection int flexDirection, private int expandFlexItems(FlexLine flexLine, @FlexDirection int flexDirection,
int maxMainSize, int paddingAlongMainAxis, int startIndex) { int maxMainSize, int paddingAlongMainAxis, int startIndex) {
int childIndex = startIndex;
if (flexLine.totalFlexGrow <= 0 || maxMainSize < flexLine.mainSize) { if (flexLine.totalFlexGrow <= 0 || maxMainSize < flexLine.mainSize) {
startIndex += flexLine.itemCount; childIndex += flexLine.itemCount;
return startIndex; return childIndex;
} }
int sizeBeforeExpand = flexLine.mainSize;
boolean needsReexpand = false;
float unitSpace = (maxMainSize - flexLine.mainSize) / flexLine.totalFlexGrow; float unitSpace = (maxMainSize - flexLine.mainSize) / flexLine.totalFlexGrow;
flexLine.mainSize = paddingAlongMainAxis; flexLine.mainSize = paddingAlongMainAxis;
float accumulatedRoundError = 0; float accumulatedRoundError = 0;
for (int i = 0; i < flexLine.itemCount; i++) { for (int i = 0; i < flexLine.itemCount; i++) {
View child = getReorderedChildAt(startIndex); View child = getReorderedChildAt(childIndex);
if (child == null) { if (child == null) {
continue; continue;
} else if (child.getVisibility() == View.GONE) { } else if (child.getVisibility() == View.GONE) {
startIndex++; childIndex++;
continue; continue;
} }
LayoutParams lp = (LayoutParams) child.getLayoutParams(); LayoutParams lp = (LayoutParams) child.getLayoutParams();
if (flexDirection == FLEX_DIRECTION_ROW if (flexDirection == FLEX_DIRECTION_ROW
|| flexDirection == FLEX_DIRECTION_ROW_REVERSE) { || flexDirection == FLEX_DIRECTION_ROW_REVERSE) {
float rawCalculatedWidth = child.getMeasuredWidth() + unitSpace * lp.flexGrow; // The direction of the main axis is horizontal
if (i == flexLine.itemCount - 1) { if (!mChildrenFrozen[childIndex]) {
rawCalculatedWidth += accumulatedRoundError; float rawCalculatedWidth = child.getMeasuredWidth() + unitSpace * lp.flexGrow;
accumulatedRoundError = 0; if (i == flexLine.itemCount - 1) {
} rawCalculatedWidth += accumulatedRoundError;
int newWidth = Math.round(rawCalculatedWidth); accumulatedRoundError = 0;
accumulatedRoundError += (rawCalculatedWidth - newWidth); }
if (accumulatedRoundError > 1.0) { int newWidth = Math.round(rawCalculatedWidth);
newWidth += 1; if (newWidth > lp.maxWidth) {
accumulatedRoundError -= 1.0; // This means the child can't expand beyond the value of the maxWidth attribute.
} else if (accumulatedRoundError < -1.0) { // To adjust the flex line length to the size of maxMainSize, remaining
newWidth -= 1; // positive free space needs to be re-distributed to other flex items
accumulatedRoundError += 1.0; // (children views). In that case, invoke this method again with the same
// startIndex.
needsReexpand = true;
newWidth = lp.maxWidth;
mChildrenFrozen[childIndex] = true;
flexLine.totalFlexGrow -= lp.flexGrow;
} else {
accumulatedRoundError += (rawCalculatedWidth - newWidth);
if (accumulatedRoundError > 1.0) {
newWidth += 1;
accumulatedRoundError -= 1.0;
} else if (accumulatedRoundError < -1.0) {
newWidth -= 1;
accumulatedRoundError += 1.0;
}
}
child.measure(MeasureSpec.makeMeasureSpec(newWidth, MeasureSpec.EXACTLY),
MeasureSpec
.makeMeasureSpec(child.getMeasuredHeight(),
MeasureSpec.EXACTLY));
} }
child.measure(MeasureSpec.makeMeasureSpec(newWidth, MeasureSpec.EXACTLY),
MeasureSpec
.makeMeasureSpec(child.getMeasuredHeight(),
MeasureSpec.EXACTLY));
flexLine.mainSize += child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin; flexLine.mainSize += child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin;
} else { } else {
float rawCalculatedHeight = child.getMeasuredHeight() + unitSpace * lp.flexGrow; // The direction of the main axis is vertical
if (i == flexLine.itemCount - 1) { if (!mChildrenFrozen[childIndex]) {
rawCalculatedHeight += accumulatedRoundError; float rawCalculatedHeight = child.getMeasuredHeight() + unitSpace * lp.flexGrow;
accumulatedRoundError = 0; if (i == flexLine.itemCount - 1) {
} rawCalculatedHeight += accumulatedRoundError;
int newHeight = Math.round(rawCalculatedHeight); accumulatedRoundError = 0;
accumulatedRoundError += (rawCalculatedHeight - newHeight); }
if (accumulatedRoundError > 1.0) { int newHeight = Math.round(rawCalculatedHeight);
newHeight += 1; if (newHeight > lp.maxHeight) {
accumulatedRoundError -= 1.0; // This means the child can't expand beyond the value of the maxHeight
} else if (accumulatedRoundError < -1.0) { // attribute.
newHeight -= 1; // To adjust the flex line length to the size of maxMainSize, remaining
accumulatedRoundError += 1.0; // positive free space needs to be re-distributed to other flex items
// (children views). In that case, invoke this method again with the same
// startIndex.
needsReexpand = true;
newHeight = lp.maxHeight;
mChildrenFrozen[childIndex] = true;
flexLine.totalFlexGrow -= lp.flexGrow;
} else {
accumulatedRoundError += (rawCalculatedHeight - newHeight);
if (accumulatedRoundError > 1.0) {
newHeight += 1;
accumulatedRoundError -= 1.0;
} else if (accumulatedRoundError < -1.0) {
newHeight -= 1;
accumulatedRoundError += 1.0;
}
}
child.measure(MeasureSpec.makeMeasureSpec(child.getMeasuredWidth(),
MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(newHeight, MeasureSpec.EXACTLY));
} }
child.measure(MeasureSpec.makeMeasureSpec(child.getMeasuredWidth(),
MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(newHeight, MeasureSpec.EXACTLY));
flexLine.mainSize += child.getMeasuredHeight() + lp.topMargin + lp.bottomMargin; flexLine.mainSize += child.getMeasuredHeight() + lp.topMargin + lp.bottomMargin;
} }
startIndex++; childIndex++;
}
if (needsReexpand && sizeBeforeExpand != flexLine.mainSize) {
// Re-invoke the method with the same startIndex to distribute the positive free space
// that wasn't fully distributed (because of maximum length constraint)
expandFlexItems(flexLine, flexDirection, maxMainSize, paddingAlongMainAxis, startIndex);
} }
return startIndex; return childIndex;
} }
/** /**
...@@ -1885,6 +1935,16 @@ public class FlexboxLayout extends ViewGroup { ...@@ -1885,6 +1935,16 @@ public class FlexboxLayout extends ViewGroup {
*/ */
public int minHeight; public int minHeight;
/**
* This attribute determines the maximum width the child can expand to.
*/
public int maxWidth = Integer.MAX_VALUE;
/**
* This attribute determines the maximum height the child can expand to.
*/
public int maxHeight = Integer.MAX_VALUE;
public LayoutParams(Context context, AttributeSet attrs) { public LayoutParams(Context context, AttributeSet attrs) {
super(context, attrs); super(context, attrs);
...@@ -1903,6 +1963,10 @@ public class FlexboxLayout extends ViewGroup { ...@@ -1903,6 +1963,10 @@ public class FlexboxLayout extends ViewGroup {
minWidth = a.getDimensionPixelSize(R.styleable.FlexboxLayout_Layout_layout_minWidth, 0); minWidth = a.getDimensionPixelSize(R.styleable.FlexboxLayout_Layout_layout_minWidth, 0);
minHeight = a minHeight = a
.getDimensionPixelSize(R.styleable.FlexboxLayout_Layout_layout_minHeight, 0); .getDimensionPixelSize(R.styleable.FlexboxLayout_Layout_layout_minHeight, 0);
maxWidth = a.getDimensionPixelSize(R.styleable.FlexboxLayout_Layout_layout_maxWidth,
Integer.MAX_VALUE);
maxHeight = a.getDimensionPixelSize(R.styleable.FlexboxLayout_Layout_layout_maxHeight,
Integer.MAX_VALUE);
a.recycle(); a.recycle();
} }
......
...@@ -102,5 +102,7 @@ limitations under the License. ...@@ -102,5 +102,7 @@ limitations under the License.
<attr name="layout_minWidth" format="dimension" /> <attr name="layout_minWidth" format="dimension" />
<attr name="layout_minHeight" format="dimension" /> <attr name="layout_minHeight" format="dimension" />
<attr name="layout_maxWidth" format="dimension" />
<attr name="layout_maxHeight" format="dimension" />
</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.
先完成此消息的编辑!
想要评论请 注册