web-dev-qa-db-ja.com

ViewGroupに最大幅を設定する

ViewGroupの最大幅を設定するにはどうすればよいですか?私はTheme.Dialogアクティビティを使用していますが、これは大きな画面にサイズ変更するとあまり良く見えません。また、それは一種の軽量であり、画面全体を占めたくありません。

私は この提案 を試してみました。また、一部のビューのようなAndroid:maxWidthプロパティはありません。

ルートのLinearLayoutを制限して(たとえば)640ディップのみにする方法はありますか?このために別のViewGroupに変更したいと思います。

助言がありますか?

58
zsniperx

私がしたことの1つのオプションは、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);
    }
}

次に、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>

そして、attr.xmlファイルのエントリ

<declare-styleable name="BoundedView">
    <attr name="bounded_width" format="dimension" />
    <attr name="bounded_height" format="dimension" />
</declare-styleable>

編集:これは私が現在使用している実際のコードです。これはまだ完全ではありませんが、ほとんどの場合に機能します。

88
Chase

Chase(+1)による元の答えの上に構築することで、いくつかの変更を行います(以下に概説します)。

  1. カスタム属性を介して最大幅を設定します(コードの下のxml)

  2. 最初に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>
_
29
Dori

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/

この質問と回答をありがとう。あなたの答えは私を大いに助けてくれましたし、将来的に他の誰かにも役立つことを願っています。

29
Jonypoins

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

7

現在のレイアウトファイルに外部レイアウトまたはビューグループレイヤーを追加します。このレイアウトの高さと幅は、最大の高さ/幅になります。これで、内部レイアウトはコンテンツをラップするように設定でき、外部レイアウトによって制限されます。例えば:

<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>
3
AmeyaB