在Android上限制ListView的高度

时间:2011-03-30 14:17:15

标签: android listview layout android-layout

我想在ListView下显示一个按钮。问题是,如果ListView被扩展(项目已添加...),则按钮被推出屏幕。

我尝试使用权重LinearLayout(如Android: why is there no maxHeight for a View?中所述),但要么我的权重错误,要么根本不起作用。

另外,我发现某处提示使用RelativeLayout。然后ListView将设置在具有android:layout_above参数的按钮上方。

问题在于我不知道如何在按钮后放置按钮。在我找到的示例中,使用ListView调整了android:layout_alignParentBottom下方的视图,但我不希望我的按钮依赖于屏幕底部。

除了使用setHeight-method和计算所需空间之外的任何想法?


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

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

  • 如果您希望按钮固定在屏幕底部,Adinia对相对布局的回答很好。这不是我的意图,但仍可能对其他人有用。

  • AngeloS的解决方案是我最后选择的解决方案,因为它创造了我想要的效果。但是,我对按钮周围的LinearLayout进行了两处小修改:

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

    • 其次,因为我希望按钮水平居中,只有垂直LinearLayout支持,我将android:orientation =“horizo​​ntal”改为“vertical”。

    AngeloS在他的帖子中也说过,他不确定android:layout_weight="0.1"周围LinearLayout的{​​{1}}参数是否有效;我刚试过,它确实做到了!没有,按钮会再次被推出屏幕。

15 个答案:

答案 0 :(得分:61)

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

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 :(得分:51)

我有这个确切的问题,为了解决这个问题,我创建了两个单独的LinearLayouts来分别容纳ListViewButton。从那里我将两者放在另一个Linear Layout中,并将该容器的android:orientation设置为vertical。我还设置了LinearLayoutListView的{​​{1}}的权重,但我不知道这是否有效。从那里,您可以将底部容器(具有您的按钮)的高度设置为您想要的任何高度。

编辑这就是我的意思:

0.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: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> 的高度更改为ListView01

wrap_content

答案 2 :(得分:21)

在上次编辑时,您只需在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>

结果,使用一些随机列表:
enter image description here

答案 3 :(得分:6)

使用LinearLayout,将ListViewButton的高度设置为wrap_content,并将权重= 1添加到ListView。这应该可以随意使用。
是的,将layout_gravity的{​​{1}}设置为Button

答案 4 :(得分:5)

RelativeLayout是一个解决方案,如果您不希望按钮太靠近底部,您可以添加边距(填充按钮会破坏它,因为它使用9补丁背景,并设置它自己的填充物。)

如果您使用LinearLayout,情况就会一样:实现您想要的方法是将ListView设置为高度= 0且权重= 1,并且按钮高度= wrap_content和weight = 0。 (设置为wrap_content,如user639183所说,不会限制ListView的高度。)

答案 5 :(得分:5)

在AngeloS的解决方案的启发下,找到了一种不使用嵌套容器的方法。

我使用了一个垂直方向的LinearLayout,它有一个ListView和一个按钮。我为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"
    />

答案 6 :(得分:2)

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

可能是这样的:

RelativeLayout的

- ListView

- RelativeLayout

----按钮

使用两个容器上的不同对齐选项,您应该可以使其工作。

答案 7 :(得分: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。你也可以使用一个FrameLayout,它比一个LinearLayout更轻,以包裹Button。

答案 8 :(得分: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>

Activity提供样板代码以自行测试解决方案。

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

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

答案 9 :(得分:1)

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

答案 10 :(得分: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 ...

答案 11 :(得分:0)

以线性布局包装内容

列表视图中的

添加: 机器人: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>

答案 12 :(得分: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"/>

答案 13 :(得分:-1)

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

答案 14 :(得分:-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>