在ViewGroup上设置最大宽度

时间:2011-05-03 21:23:43

标签: android view width android-linearlayout

如何设置ViewGroup的最大宽度?我正在使用Theme.Dialog活动,但是,当调整大屏幕时,这看起来不那么好,它也有点轻量级,我不希望它占用整个屏幕。

我试过this suggestion无济于事。此外,没有android:maxWidth属性,如某些视图。

有没有办法限制根LinearLayout,以便它只(例如)640 dip?我愿意为此换到另一个ViewGroup。

有什么建议吗?

6 个答案:

答案 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)的原始答案的基础上,我会做出一些改变(概述如下)。

  1. 我会通过自定义属性设置最大宽度(代码下面的xml)

  2. 我先调用super.measure(),然后进行Math.min(*)比较。使用原始答案代码时,如果MeasureSpec中设置的传入尺寸为LayoutParams.WRAP_CONTENTLayoutParams.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());
        }
    }
    }
    
  3. 和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个按钮)。