web-dev-qa-db-ja.com

Android:ビューにmaxHeightがないのはなぜですか?

ビューにはminHeightがあります ですが、何らかの理由でmaxHeightがありません:

私が達成しようとしているのは、いくつかのアイテム(ビュー)がScrollViewを満たすことです。 1..3アイテムがある場合、それらを直接表示したい。 ScrollViewの意味は、1、2、または3アイテムの高さです。

4つ以上のアイテムがある場合、ScrollViewの展開を停止し(したがってmaxHeight)、スクロールの提供を開始します。

ただし、残念ながらmaxHeightを設定する方法はありません。したがって、1..3アイテムがある場合はScrollViewの高さをプログラムでWRAP_CONTENTに設定し、4つ以上のアイテムがある場合は高さを3*sizeOf(View)に設定する必要があります。

すでにmaxHeightが存在する場合、minHeightが提供されない理由を誰でも説明できますか?

(ところで:ImageViewなどの一部のビューにはmaxHeightが実装されています。)

164
znq

これらのソリューションはどれも、wrap_contentに設定されたScrollViewであるが、特定のポイントの後に拡張を停止してスクロールを開始するmaxHeightを持っている必要なものには機能しませんでした。 ScrollViewのonMeasureメソッドを単にオーバーライドしました。

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    heightMeasureSpec = MeasureSpec.makeMeasureSpec(300, MeasureSpec.AT_MOST);
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}

これはすべての状況で機能するとは限りませんが、レイアウトに必要な結果が得られることは確かです。また、madhuによるコメントにも対応しています。

スクロールビューの下にレイアウトが存在する場合、このトリックは機能しません– madhu Mar 5 at 4:36

78
whizzle

MaxHeightでScrollViewまたはListViewを作成するには、maxHeightの高さを指定して、その周りにTransparent LinearLayoutを作成するだけです。次に、ScrollViewのHeightをwrap_contentに設定します。これにより、親のLinearLayoutと同じ高さになるまで拡大するように見えるScrollViewが作成されます。

68
JustinMorris

これは私にそれをxmlでカスタマイズ可能にするのに役立ちました:

MaxHeightScrollView.Java:

public class MaxHeightScrollView extends ScrollView {

private int maxHeight;
private final int defaultHeight = 200;

public MaxHeightScrollView(Context context) {
    super(context);
}

public MaxHeightScrollView(Context context, AttributeSet attrs) {
    super(context, attrs);
    if (!isInEditMode()) {
        init(context, attrs);
    }
}

public MaxHeightScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    if (!isInEditMode()) {
        init(context, attrs);
    }
}

@TargetApi(Build.VERSION_CODES.Lollipop)
public MaxHeightScrollView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
    super(context, attrs, defStyleAttr, defStyleRes);
    if (!isInEditMode()) {
        init(context, attrs);
    }
}

private void init(Context context, AttributeSet attrs) {
    if (attrs != null) {
        TypedArray styledAttrs = context.obtainStyledAttributes(attrs, R.styleable.MaxHeightScrollView);
        //200 is a defualt value
        maxHeight = styledAttrs.getDimensionPixelSize(R.styleable.MaxHeightScrollView_maxHeight, defaultHeight);

        styledAttrs.recycle();
    }
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    heightMeasureSpec = MeasureSpec.makeMeasureSpec(maxHeight, MeasureSpec.AT_MOST);
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}

attr.xml

<declare-styleable name="MaxHeightScrollView">
        <attr name="maxHeight" format="dimension" />
    </declare-styleable>

レイアウト例

<blah.blah.MaxHeightScrollView Android:layout_weight="1"
                app:maxHeight="90dp"
                Android:layout_width="fill_parent"
                Android:layout_height="wrap_content">
                <EditText Android:id="@+id/commentField"
                    Android:hint="Say Something"
                    Android:background="#FFFFFF"
                    Android:paddingLeft="8dp"
                    Android:paddingRight="8dp"
                    Android:gravity="center_vertical"
                    Android:maxLines="500"
                    Android:minHeight="36dp"
                    Android:layout_width="fill_parent"
                    Android:layout_height="wrap_content" />
            </blah.blah.MaxHeightScrollView>
35
SlickDev

(私はこれが質問に直接答えないことを知っていますが、maxHeight機能を探している他の人には役立つかもしれません)

ConstraintLayoutは、

app:layout_constraintHeight_max="300dp"
app:layout_constrainedHeight="true" 

または

app:layout_constraintWidth_max="300dp"
app:layout_constrainedWidth="true" 

サンプルの使用法 ここ

12
user1506104

できればウィズルの答えにコメントしていましたが、Android Nのマルチウィンドウモードのコンテキストでこの問題を解決するには、コードを変更する必要があることに注意するのが便利だと思いましたこれに少し:

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    if(MeasureSpec.getSize(heightMeasureSpec) > maxHeight) {
        heightMeasureSpec = MeasureSpec.makeMeasureSpec(maxHeight, MeasureSpec.AT_MOST);
    }
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}

これにより、レイアウトのサイズを最大の高さよりも小さくすることができますが、最大の高さよりも大きくなることもできません。これを使用して、RelativeLayoutをオーバーライドするレイアウトクラスを使用しました。これにより、ScrollViewの子としてMaxHeightRelativeLayoutを含むカスタムダイアログを作成し、画面の全高を拡張せず、また、Android Nのマルチウィンドウで最小のWidowサイズに収まるように縮小します。

7
J. P. Krause

MaxHeightを設定する方法はありません。ただし、高さは設定できます。

そのためには、scrollViewの各アイテムの高さを発見する必要があります。その後、scrollViewの高さをnumberOfItens * heightOfItemに設定するだけです。

アイテムの高さを発見するには、次のようにします。

View item = adapter.getView(0, null, scrollView);
item.measure(0, 0);
int heightOfItem = item.getMeasuredHeight();

高さを設定するには、次のようにします。

// if the scrollView already has a layoutParams:
scrollView.getLayoutParams().height = heightOfItem * numberOfItens;
// or
// if the layoutParams is null, then create a new one.
scrollView.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, heightOfItem * numberOfItens));
4
Derzu

マイMaxHeightScrollViewカスタムビュー

public class MaxHeightScrollView extends ScrollView {
    private int maxHeight;

    public MaxHeightScrollView(Context context) {
        this(context, null);
    }

    public MaxHeightScrollView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public MaxHeightScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs);
    }

    private void init(Context context, AttributeSet attrs) {
        TypedArray styledAttrs =
                context.obtainStyledAttributes(attrs, R.styleable.MaxHeightScrollView);
        try {
            maxHeight = styledAttrs.getDimensionPixelSize(R.styleable.MaxHeightScrollView_mhs_maxHeight, 0);
        } finally {
            styledAttrs.recycle();
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        if (maxHeight > 0) {
            heightMeasureSpec = MeasureSpec.makeMeasureSpec(maxHeight, MeasureSpec.AT_MOST);
        }
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }
}

style.xml

<declare-styleable name="MaxHeightScrollView">
    <attr name="mhs_maxHeight" format="dimension" />
</declare-styleable>

使用

<....MaxHeightScrollView
    Android:layout_width="wrap_content"
    Android:layout_height="wrap_content"
    app:mhs_maxHeight="100dp"
    >

    ...

</....MaxHeightScrollView>
3
Phan Van Linh

layout_weight value を使用してみましたか? 0より大きい値に設定すると、使用可能な残りのスペースにそのビューが拡大されます。

ストレッチが必要なビューが複数ある場合、値はそれらの間の重みになります。

したがって、2つのビューが両方ともlayout_weight値1に設定されている場合、それらは両方とも空間を埋めるためにストレッチしますが、両方とも同じ量のスペースにストレッチします。それらの1つを値2に設定すると、他のビューの2倍に伸びます。

リニアレイアウトの下にリストされている詳細情報

1
Bryan Denny

Layout_height = "max_height"でScrollViewをplainLinearLayoutで包むと、これは完璧な仕事をします。実際、このコードは過去5年間に問題なく生産されています。

<LinearLayout
        Android:id="@+id/subsParent"
        Android:layout_width="match_parent"
        Android:layout_height="150dp"
        Android:gravity="bottom|center_horizontal"
        Android:orientation="vertical">

        <ScrollView
            Android:id="@+id/subsScroll"
            Android:layout_width="wrap_content"
            Android:layout_height="wrap_content"
            Android:layout_marginBottom="10dp"
            Android:layout_marginEnd="15dp"
            Android:layout_marginStart="15dp">

            <TextView
                Android:id="@+id/subsTv"
                Android:layout_width="wrap_content"
                Android:layout_height="wrap_content"
                Android:text="@string/longText"
                Android:visibility="visible" />

        </ScrollView>
    </LinearLayout>
1
Sai Kiran

誰かがLayoutParamsに正確な値を使用することを検討している場合.

setLayoutParams(new LayoutParams(Y, X );

デバイスディスプレイの密度を考慮することを忘れないでください。そうしないと、異なるデバイスで非常に奇妙な動作をする可能性があります。例えば:

Display display = getWindowManager().getDefaultDisplay();
DisplayMetrics d = new DisplayMetrics();
display.getMetrics(d);
setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, (int)(50*d.density) ));

ご存知のとおり、Androidを実行しているデバイスは、さまざまな画面サイズを持つことができます。さらに知っているように、ビューは動的に調整し、適切なスペースになる必要があります。

最大の高さを設定した場合、十分なスペースを確保しないように、またはスペースを少なくするようにビューを強制することができます。私は時々、実際には最大の高さを設定するように思われることを知っています。しかし、解像度が劇的に変化し、変化する場合、最大の高さを持つビューは適切に見えません。

必要なレイアウトを正確に実行する適切な方法はないと思います。レイアウトマネージャーと関連するメカニズムを使用して、レイアウトを検討することをお勧めします。あなたが何を達成しようとしているのかわかりませんが、リストには3つのアイテムしか表示されず、ユーザーはスクロールする必要があるというのは少し奇妙に聞こえます。

ところで。 minHeightは保証されていません(おそらく存在しないはずです)。アイテムを強制的に表示し、他の関連アイテムを小さくすると、いくつかの利点があります。

1
Diego Frehner

最初にアイテムの高さをピクセル単位で取得します

View rowItem = adapter.getView(0, null, scrollView);   
rowItem.measure(0, 0);    
int heightOfItem = rowItem.getMeasuredHeight();

その後、単に

Display display = getWindowManager().getDefaultDisplay();    
DisplayMetrics displayMetrics = new DisplayMetrics();    
display.getMetrics(displayMetrics);    
scrollView.getLayoutParams().height = (int)((heightOfItem * 3)*displayMetrics .density);
0
Ibrahim Khaled

scrollView.setHeight(200px)、2つのアイテムscrollView.setheight(400px)の3つ以上のscrollView.setHeight(600px)だけで、1つのアイテムの実行時に高さを設定できると思います

0
Yayo28

オーバーフロー以外のスクロールビューまたはリストビューを作成したい場合は、RelativeLayoutでトップビューとボトムビューを上下に配置してください:

<ScrollView
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content"
    Android:layout_above="@+id/topview"
    Android:layout_below="@+id/bottomview" >
0

私はここに答えがあります:

https://stackoverflow.com/a/29178364/1148784

ScrollViewを拡張する新しいクラスを作成し、onMeasureメソッドをオーバーライドするだけです。

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        if (maxHeight > 0){
            int hSize = MeasureSpec.getSize(heightMeasureSpec);
            int hMode = MeasureSpec.getMode(heightMeasureSpec);

            switch (hMode){
                case MeasureSpec.AT_MOST:
                    heightMeasureSpec = MeasureSpec.makeMeasureSpec(Math.min(hSize, maxHeight), MeasureSpec.AT_MOST);
                    break;
                case MeasureSpec.UNSPECIFIED:
                    heightMeasureSpec = MeasureSpec.makeMeasureSpec(maxHeight, MeasureSpec.AT_MOST);
                    break;
                case MeasureSpec.EXACTLY:
                    heightMeasureSpec = MeasureSpec.makeMeasureSpec(Math.min(hSize, maxHeight), MeasureSpec.EXACTLY);
                    break;
            }
        }

        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }
0
babay