Androidでのリストビューの高さの制限


92

の下にボタンを表示したいListView。問題は、ListView拡張された場合(アイテムが追加された場合...)、ボタンが画面から押し出されることです。

私が試したLinearLayout(で提案されているよう重みを持つの:なぜ何のmaxHeightは、ビューのために存在しない?アンドロイド、私は重みが間違っていましたか、それは単に仕事をしませんでしたどちらか)。

また、を使用するためのヒントをどこかで見つけましたRelativeLayout。次にListViewandroid:layout_aboveparamを使用してボタンの上に設定します。

これの問題は、後でボタンを配置する方法がわからないことです。私が見つけた例では、の下のビューListViewはを使用して調整されましたがandroid:layout_alignParentBottom、ボタンを画面の下部に固定したくありません。

setHeightメソッドの使用と必要なスペースの計算以外のアイデアはありますか?


編集: 私は多くの有用な答えを得ました。

  • bigstoneとuser639183のソリューションはほぼ完全に機能しました。ただし、ボタンの下部に余分なパディング/マージンを追加する必要がありました。ボタンが画面の半分まで押し出されるためです(その後停止されます)。

  • 画面下部にボタンを固定したい場合は、相対レイアウトのみでのAdiniaの回答で問題ありません。それは私が意図したものではありませんが、それでも他の人に役立つかもしれません。

  • AngeloSのソリューションは、私が最後に選択したもので、私が望む効果を生み出しただけです。ただし、LinearLayoutボタンの周囲に2つの小さな変更を加えました。

    • まず、レイアウトに絶対値を入れたくなかったので、に変更android:layout_height="45px"しましたwrap_content。これも問題なく機能します。

    • 次に、ボタンを水平方向の中央に配置したいので、垂直方向のみでサポートされているためLinearLayout、android:orientation = "horizo​​ntal"を "vertical"に変更しました。

    AngeloSはまた、彼の最初の投稿android:layout_weight="0.1"で、LinearLayout周囲のparamがListView効果を持っているかどうかはわからないと述べました。私は試してみましたが実際にあります!なければ、ボタンは再び画面から押し出されます。


このように、内部相対レイアウトが画面よりも長く成長している場合、1つのステップでを追加できますandroid:layout_alignParentBottom="true"。しかし、明確にするために、アイテムが少ないときにボタンをListViewの下部に接続したままにしますか?はいの場合は、リッチの発言をご覧ください。
bigstones 2011年

はい、それが私が欲しいものです。
クラゲ

:年後、私たちは今ConstraintLayoutへの最大の高さのおかげで持ってstackoverflow.com/questions/42694355/...
user1506104

回答:


55

私はこの正確な問題を抱えていて、それを解決するためにとをそれぞれLinearLayouts収容するために2つの別個のものを作成しました。そこから両方を別の場所に置き、そのコンテナをに設定します。私はまたの重量設定に収納するのが、それがどんな効果を持っている場合、私は知りません。そこから、(ボタンのある)一番下のコンテナの高さを好きな高さに設定できます。ListViewButtonLinear Layoutandroid:orientationverticalLinearLayoutListView0.1

これが私が意味することを編集してください:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">

<LinearLayout
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_weight="0.1"
    android:orientation="horizontal">

    <ListView
        android:id="@+id/ListView01"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:dividerHeight="2px"></ListView>
</LinearLayout>

<LinearLayout
    android:layout_width="fill_parent"
    android:layout_height="45px"
    android:background="@drawable/drawable"
    android:orientation="horizontal">

    <Button
        android:id="@+id/moreButton"
        android:layout_width="wrap_content"
        android:layout_height="fill_parent"
        android:layout_alignParentRight="true"
        android:background="@drawable/btn_more2"
        android:paddingRight="20px" />

</LinearLayout>

上記の解決策は、画面の下部にあるボタンを修正します。


ボタンをリストの一番下にフロートさせるには、高さをListView01に変更しwrap_contentます。

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical">

<LinearLayout
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_weight="0.1"
    android:orientation="horizontal">

    <ListView
        android:id="@+id/ListView01"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:dividerHeight="2px"></ListView>
</LinearLayout>

<LinearLayout
    android:layout_width="fill_parent"
    android:layout_height="45px"
    android:background="@drawable/drawable"
    android:orientation="horizontal">

    <Button
        android:id="@+id/moreButton"
        android:layout_width="wrap_content"
        android:layout_height="fill_parent"
        android:layout_alignParentRight="true"
        android:background="@drawable/btn_more2"
        android:paddingRight="20px" />
</LinearLayout>


私はそれを<divHTMLのタグに似たものだと考えています。それは単なるラッパーであり、このソリューションは確実に機能します。
AngeloS 2011年

オーバーヘッドに関しては、相対レイアウトで何をしているのかとそれほど変わりません..現在、1つの外部ラッパーがあり、もう1つをネストしています..もう1つだけネストし、リストビューを分割することをお勧めしますボタンを2つのコンテナーに配置すると、垂直線形レイアウトでスタック効果が作成されます。これが実用的なソリューションであることを強調することはできません。
AngeloS 2011年

1
はい!これは機能します!重要なことに、最初のソリューションと2番目のソリューションの唯一の違いは、linearlayoutがwrap_contentを必要とすることです。そのため、最終的に開始タイプimgur.com/c9L1Zが設定されました。これを見つけた他の誰にでも:重み付けは重要ですが、任意の値を取ることができます。
Sam

2
そのようなすべてのビューをラップする必要はありません- @Sparkleのソリューションを
Richard Le Mesurier

ボタンのレイアウトに45pxまたは正確な値を入力する必要がありますか?代わりにwrap_contentを配置する必要があります
Mario Velasco 14

65

この問題をコードで解決し、リストビューの高さを設定しました。

if(adapter.getCount() > 5){
        View item = adapter.getView(0, null, listView);
        item.measure(0, 0);         
        ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(LayoutParams.MATCH_PARENT, (int) (5.5 * item.getMeasuredHeight()));
        listView.setLayoutParams(params);
}

最大の高さを単一のアイテムの高さの5.5倍に設定したことに注意してください。そうすることで、ユーザーはスクロールする必要があることが確実にわかります。:)


1
素敵な答え。このコードを使用して、アイテムの高さを検出します。次に、リストのサイズを設定して、必要なアイテムの数を表示できます。ありがとう。
Derzu 2012

3
これが最良の答えです。5行のコードで問題を解決できるのに、なぜ50行のネストされたXMLを書くのですか?
グレッグエニス2013

@shaylhありがとうございます。完璧に働きました。
Anju

私はXMLソリューションを適切にクリーンアップしましたが、最終的にはこのアイデアを最終製品で使用することになりました。
Richard Le Mesurier 2014年

1
@JayRコメントするには遅すぎることはありません
万座

21

最後の編集でandroid:layout_above="@+id/butt1"は、ListViewコードも追加する必要があります。

そして、あなたは本当に1以上を使用する必要がないことを、あなた(とそれ以前の回答を試してみました、ここで皆を)示すためにRelativeLayoutここで、あなたの修正コード

   <RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="@drawable/bkg">
    <TextView
        android:id="@+id/textView1"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="TextView1"
        android:layout_alignParentTop="true">
    </TextView>
    <TextView
        android:id="@+id/textView2"
        android:layout_below="@+id/textView1"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="TextView2"
        android:layout_centerHorizontal="true">
    </TextView>
    <Button
        android:id="@+id/butt1"
        android:text="string/string3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_alignParentBottom="true">
    </Button>
    <ListView
        android:id="@+id/android:list"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="2dip"
        android:layout_marginBottom="2dip"
        android:drawSelectorOnTop="false"
        android:visibility="visible"
        android:layout_below="@+id/textView2"
        android:layout_above="@+id/butt1" />
    </RelativeLayout>

そしてその結果、いくつかのランダムなリストを使用します:
ここに画像の説明を入力してください


1
どうもありがとうございましたが、ボタンを画面下部に固定することは、私が意図したものではありませんでした。ListViewの下部にあるはずです。
クラゲ

確かに、今回はLinearLayoutsがあなたが望むもののための唯一のソリューションであるかもしれないようです。私はRelativeLayoutsとのさまざまな組み合わせを試してみた、とどれも本当に:(働いていない...しかし、私はあなたの答えを見つけることがうれしいです。
Adinia

1
ありがとうございました!それは完璧だ!
ギカラ2014年

6

使用してLinearLayout、あなたの高さに設定ListViewしてButtonのをwrap_contentしてまで体重= 1を追加しますListView。これはあなたが望むように動作するはずです。
そして、はい、設定layout_gravityButtonしますbottom


6

AngeloSのソリューションから着想を得て、ネストされたコンテナを使用せずにこれを行う方法を見つけました。

LinearLayoutListViewとボタンがある垂直方向のを使用しました。をに設定しandroid:layout_weight="0.1"ましたListView

それは常にボタンをリストの一番下に貼り付けることに成功しています。また、リストが大きくなっても、ボタンは画面から押し出されません。

<ListView
    android:id="@+id/notes_list"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_weight="0.1"        
    />

<Button
    android:id="@+id/create_note_btn"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"        
    android:onClick="onCreateButtonClicked"
    android:text="@string/create_notes"
    />

2
いいえ、試してみたところ、ボタンは画面の下部にあり、リストの下部にはありません。:(
アディニア2013

@Adiniaこれは少なくとも4.4.3で完全に動作します。素敵なソリューション、スパークルはもっと投票すべきです。
Richard Le Mesurier 2014年

うーん..レイアウトに他の設定があるかもしれませんか?4.4.3を搭載したNexus 4でもう一度テストしたところ、ボタンはリストではなくレイアウトの下部にとどまり、リストに固定されません。
Adinia 2014年

2
@Richard Le Mesurier確かに、 android:layout_height="wrap_content" あなたのソリューションのように、LinearLayoutの場合、それは4.4.3だけでなく、完全に機能していますが、Sparkleはそれを言及しなかったので、match_parent以前に試しました。
Adinia 14年

パイにも取り組んでいます。+1
Zubair Younas

5

RelativeLayout 解決策です。ボタンを下部に近づけすぎないようにするには、マージンを追加できます(ボタンにパディングすると、9パッチの背景を使用し、独自のパディングを設定するため、ボタンが壊れます)。

aを使用した場合も同じです。必要LinearLayoutなことを達成するにはListView、をheight = 0およびweight = 1に設定し、ボタンの高さ= wrap_contentおよびweight = 0に設定します。(user639183が言ったように、両方をwrap_contentに設定しても、ListViewの高さは制限されません)。


はい、それはListViewの高さを制限します
ernazm '30年

@ user639183試してみましたが、あなたは正しいと思います。
bigstones 2011年

提案されたように重みを変更しました(以前は、ListViewの重み= 2とボタンの重み= 1でしたが、なぜこれが機能しないのでしょうか?)効果は非常に興味深いです。実際、「android:layout_marginBottom」を追加することで、必要な場所にとどまらせることができます。ただし、マキシムのアプローチを試してみて、それが機能するかどうかを確認することもあります。
クラゲ

@jellyfish:わかりません。私の確信は@ user639183によって破壊されました。高さ全体が2つのビューで共有されるという考えです。彼らが獲得するシェアの量は重みによって与えられるので、1-0->すべてを最初に(2-1は2番目に1/3のスペースを与えます)。スクロールビューにwrap_contentを設定すると、コンテンツと同じ高さになると思いました。しかし、外側のレイアウトをfill_parentに設定しましたか?
bigstones 2011年

ネストされたRelativeLayout(マキシムによって提案されている)が機能しないのは本当に奇妙です。私は何かを逃したという感覚を持っているので、私は上にそれを投稿するかもしれません...
クラゲ

2

おそらくネストされたコンテナを使用してこれを機能させることができます。Buttonを2番目の(内部)コンテナーでラップしてより多くのスペースを占めるようにし、Buttonを内部コンテナーの上部に揃える必要がある場合があります。

このような可能性のあるもの:

RelativeLayout

- リストビュー

-RelativeLayout

----ボタン

2つのコンテナーで異なる配置オプションを使用すると、これを機能させることができるはずです。


relativeLayoutを使用するのが最善の解決策だと思いますがandroid:layout_marginTop="30dip" 、たとえばListとButtonの間にスペースを増やしたい場合など、Buttonのようなものを使用できるのに、ネストされたコンテナを使用する理由は本当にわかりません。
Adinia、2011年

質問では、OPは、ListViewに対するボタンの配置を厳密に行うと、ListViewが十分に高くなると、画面から消えると述べています。例これらの種類では、ネストされたコンテナにトリッキー取得する必要があります
リッチ

2

これはそれを行うための最もクリーンな方法です:

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">
  <ListView
      android:id="@+id/ListView01"
      android:layout_width="fill_parent"
      android:layout_height="0dp"
      android:layout_weight="1"
      android:dividerHeight="2px">
  </ListView>
  <FrameLayout
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
      android:background="@drawable/drawable"
      >
    <Button android:background="@drawable/btn_more2"
        android:id="@+id/moreButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:paddingRight="20px"
        />    
  </LinearLayout>
</LinearLayout>

Angelosのソリューションに似ていますが、ListViewをラップするlinearlayoutは必要ありません。また、LinearLayoutに比べて軽いFrameLayoutを使用して、Buttonをラップすることもできます。


2

このアイデアは、次のような非常に優れたソリューションで概説されています。

どちらも少なくともv4.4.3では完全に機能するようです。

それをチェックアウトして各メソッドを確認するために、テストコードを作成するのにしばらく時間を費やす必要がありました。以下は、必要な自己完結型の最小限のテストコードです。


レイアウトはネストされたレイアウトが少ないため、Sparkleのソリューションに基づいています。また、現在のLINTチェックを反映するように更新されました。

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    tools:context="MainActivity" >

    <ListView
        android:id="@+id/listview"
        android:layout_width="fill_parent"
        android:layout_height="0dp"
        android:layout_weight="1" />

    <Button
        android:id="@+id/btn"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Grow List"
        tools:ignore="HardcodedText" />

</LinearLayout>

アクティビティは、ソリューションを自分でテストするためのボイラープレートコードを提供します。

public class MainActivity extends Activity
{
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        final ListView listview = (ListView)findViewById(R.id.listview);
        final ArrayAdapter<String> adapter = 
                new ArrayAdapter<String>(this,
                                         android.R.layout.simple_list_item_1,
                                         new ArrayList<String>());
        adapter.setNotifyOnChange(true);
        listview.setAdapter(adapter);

        findViewById(R.id.btn).setOnClickListener(new View.OnClickListener()
        {

            @Override
            public void onClick(View v)
            {
                int count = adapter.getCount();
                adapter.add(String.valueOf(count));
                listview.setSelection(count);
            }
        });
    }
}

これは「コミュニティーwiki」なので、自由に追加または改善してください。


1

下部のボタンでRelativeLayoutを使用してみてください。レイアウトの高さを「wrap_content」に設定します。私はそれを試していません。ただのアイデア


これは本当にうまくいくと思っていましたが、うまくいかないようです。レイアウトは、高さがmatch_parentに設定されているかのように、残っているすべてのスペースを埋めます。しかし、意味がありません。
クラゲ


0

以下は私のために働いたものです...

 if(adapter.getCount() > 3){
                    View item = adapter.getView(0, null, impDateListView);
                    item.measure(0, 0);         
                    LayoutParams params = impDateListView.getLayoutParams();
                    params.width = LayoutParams.MATCH_PARENT;
                    params.height = 3 * item.getMeasuredHeight();
                    impDateListView.setLayoutParams(params);


                }

注:params.width = ...も設定する必要があります...

上記の例は、TableRow内でTableRowおよびListViewを使用する場合です...


0

線形レイアウトでコンテンツをラップする

リストビューに追加:android:layout_weight = "1"

ボタンセットの固定高さ

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="wrap_content"
              android:orientation="vertical">

<ListView
    android:id="@+id/my_list"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_weight="1">
</ListView>

 <Button
    android:text="Button"
    android:layout_width="match_parent"
    android:layout_height="50dp"/>

</LinearLayout>

0

要素がリストに追加されたときにリストビューの下のコンテンツを下に移動する場合は、次の解決策を試してください。

リストビューの下部に正のパディングを追加し、「フッター」の上部に負のパディングを追加します。これは、線形レイアウトまたは相対レイアウトで機能します。

<ListView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:paddingBottom="50dp"/>

<TextView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginTop="-50dp"/>


-2

これを解決するには、ListViewをScrollView内に配置します。Lintは気に入らなかったのですが、minHeightを追加してfillViewportをtrueに設定することで、良い結果が得られます。

    <ScrollView 
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="1dp"
        android:layout_marginRight="1dp"
        android:minHeight="100dp"
        android:fillViewport="true"
        android:fadeScrollbars="false"
        android:paddingTop="2dp" 
        android:orientation="vertical"
        android:scrollbarAlwaysDrawVerticalTrack="true" >

        <ListView
            android:id="@+id/workoutAElistRoutines"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="fill_vertical"
            android:background="@drawable/dialog_inner_border_tan"
            android:choiceMode="singleChoice"
            android:orientation="vertical"
            android:paddingLeft="3dp"
            android:paddingRight="3dp" >

        </ListView>
    </ScrollView>        

私はこのアプローチを試しましたが、それでもリストビューのサイズが制限されていても、リストビューをスクロールできないので、面倒です。なぜなのかご存知ですか?
エドゥアルド

7
ListViewをScrollView内に配置しないでください。
jenzz 2012年

はい、ListViewをScrollView内に配置しないでください。しかし、この「ハック」でそれは可能です... stackoverflow.com/a/14577399/1255990
Leonardo Cardoso
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.