在ViewGroup上设置最大宽度

zsn*_*erx 58 android view width android-linearlayout

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

我试过这个建议无济于事.此外,没有android:maxWidth像一些观点的属性.

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

有什么建议?

Cha*_*ase 89

我做的一个选择是扩展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);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后您将使用XML自定义类:

<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>
Run Code Online (Sandbox Code Playgroud)

和attr.xml文件条目

<declare-styleable name="BoundedView">
    <attr name="bounded_width" format="dimension" />
    <attr name="bounded_height" format="dimension" />
</declare-styleable>
Run Code Online (Sandbox Code Playgroud)

编辑:这是我现在使用的实际代码.这仍然不完整,但在大多数情况下都适用.

  • 令人难以置信的是,Google没有包含"maxWidth"开箱即用,而是我们必须继承:-( (4认同)
  • 你是绝对正确的.他们实际上是众包平台:] (2认同)

Jon*_*ins 30

这是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);
    }
}
Run Code Online (Sandbox Code Playgroud)

这里有一个使用xml attr的链接:http:
 //kevindion.com/2011/01/custom-xml-attributes-for-android-widgets/

感谢您提出这个问题和答案.你的回答给了我很多帮助,我希望它在未来能够帮助别人.


Dor*_*ori 29

在Chase(+1)的原始答案的基础上,我会做出一些改变(概述如下).

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

  2. super.measure()先打电话再做Math.min(*)比较.使用原始答案代码,我们可能会遇到问题,当设置的传入大小MeasureSpecLayoutParams.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());
        }
    }
    }
    
    Run Code Online (Sandbox Code Playgroud)

和xml attr

    <!-- MaxWidthLinearLayout -->
    <declare-styleable name="MaxWidthLinearLayout">
        <attr name="maxWidth" format="dimension" />
    </declare-styleable>
Run Code Online (Sandbox Code Playgroud)

  • 此代码无法按预期工作.调整宽度时,包含元素仍然可以使用原始宽度.因此内容被截断.Jonypoins回答有效. (4认同)

Zbi*_*ski 7

现在android.support.constraint.ConstraintLayout让它更容易.只需使用ConstraintLayout包装您的视图(任何类型),并将以下属性设置为视图:

android:layout_width="0dp"
app:layout_constraintWidth_default="spread"
app:layout_constraintWidth_max="640dp"
Run Code Online (Sandbox Code Playgroud)

http://tools.android.com/recent/constraintlayoutbeta5isnowavailable