限制Android上ListView的高度

我想在ListView下显示一个button。 问题是,如果ListView得到扩展(项目添加…),button被推出屏幕。

我尝试了一个带权重的LinearLayout (在Android中build议:为什么没有maxHeight的视图? ),但是我得到的权重错了,或者根本不起作用。

另外,我在某处发现了使用RelativeLayout的提示。 然后ListView将被设置在android:layout_above参数的buttonandroid:layout_above

问题是我不知道如何定位button。 在我发现的例子中, ListView下面的View使用android:layout_alignParentBottom进行了调整,但是我不希望我的button粘在屏幕的底部。

任何想法,除了使用setHeight方法和一些计算所需的空间?


编辑: 我有很多有用的答案。

  • bigstone的&user639183的解决scheme几乎完美的工作。 但是,我不得不在button的底部添加一个额外的填充/边距,因为它仍然会被挤出屏幕的一半(但是随后停止)

  • 如果你想把button固定在屏幕的底部,Adinia的回答只有相对的布局。 这不是我的意图,但仍然可能对其他人有用。

  • AngeloS的解决scheme是我最终select的解决scheme,因为它创造了我想要的效果。 不过,我对button周围的LinearLayout做了两处小小的修改:

    • 首先,因为我不想在我的布局中有任何绝对值,所以我将android:layout_height="45px"更改为wrap_content ,这也很好。

    • 其次,因为我想要水平居中的button,只有垂直的LinearLayout支持,我改变了android:orientation =“horizo​​ntal”为“vertical”。

    AngeloS还在他的初始文章中表示,他不确定在ListView周围的LinearLayoutandroid:layout_weight="0.1"参数是否有任何影响; 我只是尝试,实际上呢! 没有,button被再次推出屏幕。

我有这个确切的问题,并解决它我创build了两个独立的LinearLayouts分别放置ListViewButton 。 从那里我把两个在另一个Linear Layout ,并将该容器的android:orientationvertical 。 我也将ListViewLinearLayout的权重设置为0.1但我不知道是否有任何影响。 从那里,你可以将底部容器(有你的button)的高度设置为你想要的任何高度。

编辑这是我的意思是:

 <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:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="0.1" > <ListView android:id="@+id/ListView01" android:layout_height="fill_parent" android:layout_width="fill_parent" android:dividerHeight="2px"> </ListView> </LinearLayout> <LinearLayout android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="45px" android:background="@drawable/drawable" > <Button android:background="@drawable/btn_more2" android:id="@+id/moreButton" android:layout_width="wrap_content" android:layout_height="fill_parent" android:layout_alignParentRight="true" android:paddingRight="20px" /> </LinearLayout> </LinearLayout> 

上述解决scheme将固定在屏幕底部的button。


要使button浮动在列表底部,请将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:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="0.1" > <ListView android:id="@+id/ListView01" android:layout_height="wrap_content" android:layout_width="fill_parent" android:dividerHeight="2px"> </ListView> </LinearLayout> <LinearLayout android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="45px" android:background="@drawable/drawable" > <Button android:background="@drawable/btn_more2" android:id="@+id/moreButton" android:layout_width="wrap_content" android:layout_height="fill_parent" android:layout_alignParentRight="true" android:paddingRight="20px" /> </LinearLayout> </LinearLayout> 

我在代码中解决了这个问题,只有当它有5个以上的项目时才设置listview的高度:

 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倍,因此用户将确定有一些滚动操作! 🙂

在上次编辑时,您只需在ListView代码中添加android:layout_above="@+id/butt1"

为了向您展示(以及之前尝试过答案的所有人),您确实不需要使用多个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> 

结果 ,使用一些随机列表:
在这里输入图像说明

使用LinearLayout ,将ListViewButton的高度设置为wrap_content ,并向ListView添加weight = 1。 这应该如你所愿。
是的,将Buttonlayout_gravity设置为bottom

RelativeLayout是一个解决scheme,如果你不希望button保持太接近底部,你可以添加边距(填充button会打破它,因为它使用9补丁的背景,并设置自己的填充)。

如果你使用LinearLayout话,这将是相同的:实现你想要的方法是将ListView设置为height = 0和weight = 1,对于buttonheight = wrap_content和weight = 0。 (设置都wrap_content,因为user639183说,不会限制ListView的高度)。

从AngeloS的解决scheme中得到灵感,find了一种不使用嵌套容器的方法。

我使用了一个垂直方向的LinearLayout ,它有一个ListView和一个button。 我为ListView设置了android:layout_weight="0.1"

它设法让button坚持总是在列表的底部。 当列表增长时,button不会从屏幕上被推下。

 <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" /> 

你可以使用嵌套容器来完成这个工作。 您可能需要将Button包装到第二个(内部)容器中,以便占用更多空间,并将Buttonalignment到内部容器的顶部。

可能是这样的:

的RelativeLayout

– 列表显示

– RelativeLayout

—-button

在两个容器上使用不同的alignment选项,你应该能够得到这个工作。

这是最干净的方法:

 <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的解决scheme类似,但是你不需要包装ListView的线性布局。 你也可以使用一个比LinearLayout更轻的FrameLayout来包装button。

这个想法在以下非常好的解决scheme中概述:

  • 安吉洛
  • 火花

他们似乎至less在v4.4.3上完美工作。

我仍然需要花一些时间编写testing代码来检查并确认每种方法。 以下是自包含的,所需的最小testing代码。


布局是基于Sparkle的解决scheme,因为它包含更less的嵌套布局。 也被更新以反映当前的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> 

Activity提供样板代码来为您自己testing解决scheme。

 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); } }); } } 

随意添加或改进,因为这是“社区维基”。

尝试使用RelativeLayout和底部的button。 将布局的高度设置为“wrap_content”。 我没有尝试过。 只是想法

在LinearLayout中,只需将android:layout_weight="1"到ListView

以下是为我工作…

  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的时候…

以线性布局包装内容

在列表视图中添加:android:layout_weight =“1”

在你的button设置固定的高度

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

如果您希望列表视图下方的内容随着元素添加到列表而向下移动,请尝试以下解决scheme:

将正面填充添加到列表视图的底部,将负填充添加到“页脚”的顶部。 这将工作在线性布局或相对布局。

 <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"/> 

由于没有MaxHeight属性,最好的方法是将ListView的高度设置为一个设置值,或者使用wrap_content

我通过将ListView放在ScrollView中解决了这个问题。 林特不喜欢它,但通过添加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>