如何设置ViewGroup的最大宽度?我正在使用Theme.Dialog
活动,但是,当调整大屏幕时,这看起来不那么好,它也有点轻量级,我不希望它占用整个屏幕。
我试过this suggestion无济于事。此外,没有android:maxWidth
属性,如某些视图。
有没有办法限制根LinearLayout,以便它只(例如)640 dip?我愿意为此换到另一个ViewGroup。
有什么建议吗?
答案 0 :(得分:88)
我所做的一个选择是扩展LinearLayout并覆盖onMeasure函数。例如:
public class BoundedLinearLayout extends LinearLayout {
private final int mBoundedWidth;
private final int mBoundedHeight;
public BoundedLinearLayout(Context context) {
super(context);
mBoundedWidth = 0;
mBoundedHeight = 0;
}
public BoundedLinearLayout(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.BoundedView);
mBoundedWidth = a.getDimensionPixelSize(R.styleable.BoundedView_bounded_width, 0);
mBoundedHeight = a.getDimensionPixelSize(R.styleable.BoundedView_bounded_height, 0);
a.recycle();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// Adjust width as necessary
int measuredWidth = MeasureSpec.getSize(widthMeasureSpec);
if(mBoundedWidth > 0 && mBoundedWidth < measuredWidth) {
int measureMode = MeasureSpec.getMode(widthMeasureSpec);
widthMeasureSpec = MeasureSpec.makeMeasureSpec(mBoundedWidth, measureMode);
}
// Adjust height as necessary
int measuredHeight = MeasureSpec.getSize(heightMeasureSpec);
if(mBoundedHeight > 0 && mBoundedHeight < measuredHeight) {
int measureMode = MeasureSpec.getMode(heightMeasureSpec);
heightMeasureSpec = MeasureSpec.makeMeasureSpec(mBoundedHeight, measureMode);
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
然后您将使用自定义类:
<com.yourpackage.BoundedLinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
app:bounded_width="900dp">
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
</com.youpackage.BoundedLinearLayout>
attr.xml文件条目
<declare-styleable name="BoundedView">
<attr name="bounded_width" format="dimension" />
<attr name="bounded_height" format="dimension" />
</declare-styleable>
编辑:这是我现在使用的实际代码。这仍然不完整,但在大多数情况下都适用。
答案 1 :(得分:29)
在Chase(+1)的原始答案的基础上,我会做出一些改变(概述如下)。
我会通过自定义属性设置最大宽度(代码下面的xml)
我先调用super.measure()
,然后进行Math.min(*)
比较。使用原始答案代码时,如果MeasureSpec
中设置的传入尺寸为LayoutParams.WRAP_CONTENT
或LayoutParams.FILL_PARENT
,我们可能会遇到问题。由于这些有效常量的值分别为 -2 和 -1 ,原始Math.min(*)
变得无用,因为它会将这些值保留在最大值上,并说测量的WRAP_CONTENT
大于我们的最大尺寸,此检查无法捕获它。我想OP只考虑精确的暗淡(为此效果很好)
public class MaxWidthLinearLayout extends LinearLayout {
private int mMaxWidth = Integer.MAX_VALUE;
public MaxWidthLinearLayout(Context context) {
super(context);
}
public MaxWidthLinearLayout(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.MaxWidthLinearLayout);
mMaxWidth = a.getDimensionPixelSize(R.styleable.MaxWidthLinearLayout_maxWidth, Integer.MAX_VALUE);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//get measured height
if(getMeasuredWidth() > mMaxWidth){
setMeasuredDimension(mMaxWidth, getMeasuredHeight());
}
}
}
和xml attr
<!-- MaxWidthLinearLayout -->
<declare-styleable name="MaxWidthLinearLayout">
<attr name="maxWidth" format="dimension" />
</declare-styleable>
答案 2 :(得分:29)
这是Dori答案的更好代码。
在方法onMeasure
中,如果在方法中首先调用super.onMeasure(widthMeasureSpec, heightMeasureSpec);
,则布局中的所有对象宽度都不会更改。因为它们在设置布局(父级)宽度之前已初始化。
public class MaxWidthLinearLayout extends LinearLayout {
private final int mMaxWidth;
public MaxWidthLinearLayout(Context context) {
super(context);
mMaxWidth = 0;
}
public MaxWidthLinearLayout(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.MaxWidthLinearLayout);
mMaxWidth = a.getDimensionPixelSize(R.styleable.MaxWidthLinearLayout_maxWidth, Integer.MAX_VALUE);
a.recycle();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int measuredWidth = MeasureSpec.getSize(widthMeasureSpec);
if (mMaxWidth > 0 && mMaxWidth < measuredWidth) {
int measureMode = MeasureSpec.getMode(widthMeasureSpec);
widthMeasureSpec = MeasureSpec.makeMeasureSpec(mMaxWidth, measureMode);
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
这是一个使用xml attr的链接:
http://kevindion.com/2011/01/custom-xml-attributes-for-android-widgets/
感谢您提出这个问题和答案。你的回答对我有很大的帮助,我希望将来能帮助别人。
答案 3 :(得分:6)
现在android.support.constraint.ConstraintLayout
让它更容易。只需使用ConstraintLayout包装您的视图(任何类型),并将以下属性设置为视图:
android:layout_width="0dp"
app:layout_constraintWidth_default="spread"
app:layout_constraintWidth_max="640dp"
http://tools.android.com/recent/constraintlayoutbeta5isnowavailable
答案 4 :(得分:3)
将外部布局或Viewgroup图层添加到当前的布局文件中。此布局的高度和宽度将是最大高度/宽度。 现在,您的内部布局可以设置为包装内容,并受外部布局的限制。 E.g:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<!-- OuterLayout to set Max Height and Width -- Add this ViewGroup to your layout File -->
<LinearLayout
android:id="@+id/outerLayout"
android:layout_width="650dp"
android:layout_height="650dp"
android:orientation="vertical" >
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical" >
</LinearLayout>
</LinearLayout>
</LinearLayout>
答案 5 :(得分:-3)
这是一个简单的答案,
宽度/高度似乎总是必须设置在一起。这在我看来是有效的。
<Button
android:text="Center"
android:layout_width="100dp"
android:layout_height="fill_parent"
android:id="@+id/selectionCenterButton"
android:minWidth="50dp"
android:minHeight="50dp"
android:maxWidth="100dp"
android:maxHeight="50dp"
android:layout_weight="1" />
按钮的父级设置为包装内容,因此缩小,但最多400宽(4个按钮)。