Предельная высота ListView на Android - PullRequest
86 голосов
/ 30 марта 2011

Я хочу показать кнопку под ListView. Проблема в том, что если ListView будет расширен (элементы добавлены ...), кнопка будет выдвинута за пределы экрана.

Я пробовал LinearLayout с весами (как предложено в Android: почему нет maxHeight для View? ), но либо я неправильно понял вес, либо он просто не работал.

Также я нашел где-то подсказку, чтобы использовать RelativeLayout. ListView будет затем установлен над кнопкой с параметром android:layout_above.

Проблема в том, что я не знаю, как потом расположить кнопку. В найденном мной примере вид под ListView был настроен с помощью android:layout_alignParentBottom, но я не хочу, чтобы моя кнопка цеплялась за нижнюю часть экрана.

Есть ли какие-либо идеи, кроме использования метода setHeight и некоторого вычисления требуемого пространства?


Edit: Я получил много полезных ответов.

  • bigstone & user639183 почти работало отлично. Тем не менее, мне пришлось добавить дополнительный отступ / отступ к нижней части кнопки, так как он все еще будет выталкиваться на полпути из экрана (но затем останавливаться)

  • Ответ Adinia с относительной разметкой подходит только для кнопки, закрепленной в нижней части экрана. Это не то, что я намеревался, но все же может быть полезно для других.

  • Решение AngeloS было тем, которое я выбрал в конце, поскольку оно только создавало эффекты, которые я хотел. Однако я сделал два небольших изменения в LinearLayout вокруг кнопки:

    • Во-первых, поскольку я не хотел, чтобы в моем макете были абсолютные значения, я изменил android:layout_height="45px" на wrap_content, что также прекрасно работает.

    • Во-вторых, так как я хотел, чтобы кнопка располагалась по центру по горизонтали, что поддерживается только по вертикали LinearLayout, я изменил Android: ориентация = "горизонтальная" на "вертикальная".

    AngeloS также заявил в своем первоначальном посте, что он не был уверен, имел ли какой-либо параметр android:layout_weight="0.1" в LinearLayout вокруг ListView какое-либо влияние; Я только попробовал, и это действительно делает! Без этого кнопка снова выходит за пределы экрана.

Ответы [ 16 ]

61 голосов
/ 10 апреля 2012

Я решил эту проблему в коде, установив высоту списка, только если в нем более 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 раз больше высоты одного элемента, чтобы пользователь наверняка знал, что есть какая-то прокрутка! :)

51 голосов
/ 30 марта 2011

У меня была именно эта проблема, и для ее решения я создал два отдельных LinearLayouts для размещения ListView и Button соответственно.Оттуда я помещаю оба в другой Linear Layout и устанавливаю для этого контейнера android:orientation в vertical.Я также установил вес 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: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:

<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>
21 голосов
/ 31 марта 2011

При последнем редактировании вам просто нужно добавить 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>

и результат , используя некоторый случайный список:
enter image description here

6 голосов
/ 30 марта 2011

Используя LinearLayout, установите высоту ваших ListView и Button на wrap_content и добавьте вес = 1 к ListView. Это должно работать, как вы хотите.
И да, установите layout_gravity из Button в bottom

5 голосов
/ 22 июня 2013

Нашел способ сделать это без использования вложенных контейнеров, вдохновленный решением 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"
    />
5 голосов
/ 30 марта 2011

RelativeLayout - это решение, если вы не хотите, чтобы кнопка оставалась слишком близко к основанию, вы можете добавить поля (заполнение кнопки может сломать ее, потому что она использует фон из 9 патчей и устанавливает свой собственный). дополнение).

Было бы то же самое, если бы вы использовали LinearLayout: способ достижения того, что вы хотите, это установить для ListView значение высоты = 0 и веса = 1, а для кнопки высоты = wrap_content и weight = 0. (установка обоих значений на wrap_content, как сказал пользователь 639183, не ограничит высоту ListView).

2 голосов
/ 18 июня 2014

Идея изложена в очень хороших решениях:

Похоже, что они оба прекрасно работают, по крайней мере, в версии 4.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);
            }
        });
    }
}

Не стесняйтесь добавлять или улучшать, так как это "сообщество вики".

2 голосов
/ 15 ноября 2013

Это самый чистый способ сделать это:

<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, но вам не нужен linearlayout, который оборачивает ListView.Также вы можете использовать FrameLayout, который легче по сравнению с LinearLayout, чтобы обернуть кнопку.

2 голосов
/ 30 марта 2011

Вы, вероятно, можете сделать это, используя вложенные контейнеры.Возможно, вам понадобится обернуть кнопку во второй (внутренний) контейнер, чтобы она занимала больше места, и просто выровнять кнопку по верхней части внутреннего контейнера.

Возможно что-то вроде этого:

RelativeLayout

- ListView

- RelativeLayout

---- Кнопка

Использование различных параметров выравнивания в двух контейнерах, вы должны быть в состоянии заставить это работать.

1 голос
/ 19 сентября 2015

в LinearLayout, просто добавьте android:layout_weight="1" к вам ListView

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...