限制Android上ListView的高度


92

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

我尝试了LinearLayout权重(如Android中的建议:为什么视图没有maxHeight?),但是我权重错误或者根本不起作用。

另外,我在某处找到了使用的提示RelativeLayout。在ListView随后将被与按钮上方设置android:layout_abovePARAM。

问题是我不知道以后如何放置按钮。在我发现的示例中,下方的“视图” ListView已使用进行了调整android:layout_alignParentBottom,但我不希望按钮紧贴屏幕底部。

除了使用setHeight方法和所需空间的一些计算外,还有其他想法吗?


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

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

  • 如果要将按钮固定在屏幕底部,则只有相对布局的Adinia答案就可以了。这不是我想要的,但对于其他人可能仍然有用。

  • 我最终选择了AngeloS的解决方案,因为它只是创建了我想要的效果。但是,我LinearLayout对按钮周围的做了两个小的更改:

    • 首先,因为我不希望在我的布局任何绝对值,我换android:layout_height="45px"wrap_content,其工作也很不错。

    • 其次,由于我希望按钮在水平方向居中(仅垂直支持)LinearLayout,因此将android:orientation =“ horizo​​ntal”更改为“ vertical”。

    AngeloS在最初的帖子中还说过,他不确定周围的android:layout_weight="0.1"参数是否有效果;我只是试过,实际上确实如此!没有,按钮再次被推出屏幕。LinearLayoutListView


这样,内部相对布局的生长时间比屏幕长,可以增加一个步骤android:layout_alignParentBottom="true"。但是要明确一点,当项目很少时,您是否希望按钮保持连接到ListView的底部?如果是,请参阅Rich所说的。
bigstones 2011年

是的,这就是我想要的。
水母

多年之后,由于ConstraintLayout,我们现在有了最大的高度:stackoverflow.com/questions/42694355/…–
user1506104

Answers:


55

我遇到了这个确切的问题,为了解决这个问题,我创建了两个单独的空间LinearLayouts来分别容纳ListViewButton。从那里,我将两者都放入另一个Linear Layout容器中,并将其设置android:orientationvertical。我还设置了LinearLayout放置ListView到的的权重,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: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>

上述解决方案会将按钮固定在屏幕底部。


要使按钮浮动在列表的底部,请将的高度更改ListView01wrap_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年

关于开销,与您使用相对布局所做的操作没有太大不同..现在您有一个外包装,而您要嵌套另一个..im建议您再嵌套一个并拆分列表视图然后将按钮放入两个容器,以垂直线性布局创建堆叠效果。我不能太强调这是一个可行的解决方案。
AngeloS 2011年

1
是!这可行!重要的是要注意,您的第一个和第二个解决方案之间的唯一区别是linearlayout需要wrap_content,所以我最终建立了一个初始类型:imgur.com/c9L1Z。与其他人发现这一点:加权很重要,但是可以取任何值。
山姆

2
无需包装所有此类视图-查看@Sparkle的解决方案
Richard Le Mesurier 2014年

是否需要为按钮布局放置45px或确切的值?我需要改用wrap_content
Mario Velasco

65

我在代码中解决了此问题,仅在其中包含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倍,因此用户将确定要进行一些滚动操作!:)


1
好答案。使用该代码,我可以发现物品的高度,现在可以设置列表的大小,以显示我想要的数量。谢谢。
Derzu

3
这是最好的答案。当您可以用5行代码解决问题时,为什么还要编写50行嵌套的XML?
格雷格·恩尼斯

谢谢@shaylh。工作完美。
Anju 2014年

尽管我很好地清理了XML解决方案,但最终还是在我的最终产品中使用了这个想法。
理查德·勒·马修里尔

1
@JayR进行评论永远不会太晚
Manza

21

在最后一次编辑时,您只需要添加android:layout_above="@+id/butt1"ListView代码。

为了向您(以及每个在此之前尝试过答案的人)证明您确实不需要使用多个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
谢谢!这是完美的!
Guicara 2014年

6

使用LinearLayout,设置你的高度ListView,并Buttonwrap_content和添加权重= 1 ListView。这应该可以根据需要工作。
是的,设定layout_gravityButtonbottom


6

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

2
不,只需尝试一下,该按钮就位于屏幕底部,而不是位于列表底部。:(
阿迪尼亚

@Adinia至少在4.4.3上可以完美工作。不错的解决方案,Sparkle,应该有更多票。
理查德·勒·马修里尔

嗯..也许您的布局中还有其他设置?我刚刚在带有4.4.3的Nexus 4上再次进行了测试,该按钮位于布局的底部,而不是列表的底部,它不停留在列表的底部。
2014年

2
@Richard Le Mesurier的确, android:layout_height="wrap_content" 对于LinearLayout,在您的解决方案中,它运行良好,不仅在4.4.3上有效,而且由于Sparkle没有提到它,因此我match_parent之前尝试过。
2014年

在Pie上工作。+1
Zubair Younas

5

RelativeLayout 是一种解决方案,如果您不希望按钮离底部太近,可以添加边距(对按钮进行填充会打断它,因为它使用的是9色补丁背景,并且设置了自己的填充)。

如果使用LinearLayout:,则实现相同效果的方法是将设置ListView为height = 0和weight = 1,并为按钮height = wrap_content和weight = 0。(如user639183所述,将两者都设置为wrap_content不会限制ListView的高度)。


是的,这将限制其ListView高度
ernazm 2011年

@ user639183刚刚尝试过,您是对的,对不起,我对此非常确定。
bigstones 2011年

我按照建议的那样更改了权重(之前,我的ListView权重= 2,按钮权重= 1,想知道为什么这不起作用吗?)效果非常有趣:按钮现在仅被推到屏幕的中间。实际上,通过添加一些“ android:layout_marginBottom”,我可以将其保留在所需位置。但是,我也可以尝试使用Maxims方法,看看是否也可行。
水母

@jellyfish:我不知道,我的确定性已由@ user639183拆除。这个想法是整个高度将由两个视图共享。他们获得的份额数量由他们的权重决定,因此1-0->分配给第一个的所有内容(2-1会给第二个提供1/3的空间)。我认为在滚动视图上设置wrap_content会使它和它的内容一样高。但是..您是否将外部布局设置为fill_parent?
bigstones 2011年

嵌套的RelativeLayout(由Maxim建议)不起作用真的很奇怪。我可能只是在上面贴上它,因为我感觉自己只是错过了一些东西……
水母

2

您可能可以使用嵌套容器来完成这项工作。您可能需要将Button包裹在第二个(内部)容器中,以便占用更多空间,然后将Button对准内部容器的顶部。

可能是这样的:

相对布局

- 列表显示

-RelativeLayout

----按钮

在两个容器上使用不同的对齐选项,您应该能够使它工作。


我认为使用relativeLayout是最好的解决方案,但是例如android:layout_marginTop="30dip" ,如果您想要在List和Button之间留出更多空间,那么我真的不明白为什么要使用嵌套容器,因为您只能对Button 使用类似的东西。
阿迪尼亚2011年

在问题中,OP表示如果他严格进行按钮相对于ListView的定位,则一旦ListView变得足够高,它就会从屏幕上消失。在这种情况下,您必须对嵌套容器感到棘手
Rich

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”。我还没试过 只是想法


我真的以为这应该工作,但似乎没有。布局将填充剩余的所有空间,就像将height设置为match_parent一样。不过没有道理。
水母

1

在LinearLayout中,只需将其添加android:layout_weight="1"到您的ListView中


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

-1

由于没有MaxHeight属性,因此最好的选择是将ListView的高度设置为设置值,或者使用wrap_content


-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中。但是有了这个“ hack”,就有可能... stackoverflow.com/a/14577399/1255990
Leonardo Cardoso
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.