Предельная высота ListView на Android


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

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

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

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

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


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

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

  • Adinia с относительной макет только в порядке, если вы хотите, чтобы кнопка крепится к нижней части экрана. Это не то, что я намеревался, но все же может быть полезно для других.
  • решение Ангелоса было тем, что я выбрал в конце, как он просто создал эффекты, которые я хотел. Тем не менее, я сделал два незначительных изменения в LinearLayout вокруг кнопки:

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

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

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

16 85

16 ответов:

у меня был этот точный вопрос и для его решения я создал два отдельных LinearLayouts в доме ListView и Button соответственно. Оттуда я положил оба в другой Linear Layout и установите этот контейнер android:orientation до vertical. Мне тоже набор веса у LinearLayout, где находился ListView до 0.1 но я не знаю, если это имеет какой-то эффект. Оттуда вы можете установить высоту нижнего контейнера (у которого есть ваша кнопка) на любую высоту, которую вы хотели бы как.

EDIT вот что я имею в виду:

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

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

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

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

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

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

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

я использовал LinearLayout с вертикальной ориентацией, который имеет ListView и кнопки. Я установил android:layout_weight="0.1" на ListView.

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

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

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

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

RelativeLayout

-- ListView

-- RelativeLayout

---- кнопка

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

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

<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, чтобы обернуть кнопку.

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

Они оба, кажется, отлично работают, по крайней мере, на v4.4.3.

мне все равно пришлось потратить некоторое время на написание тестового кода, чтобы проверить его и подтвердить каждый метод. Ниже приведен автономный, минимальный тестовый код требуется.


макет основан на решении Sparkle, так как он содержит меньше вложенных макетов. Также был обновлен, чтобы отразить текущие проверки корпии.

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

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

попробуйте использовать RelativeLayout с кнопкой в нижней части. Установите высоту макета как "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);


                }

Примечание : параметры.ширина.= .. Необходимо также установить...

приведенный выше пример - это когда вы используете TableRow и ListView внутри TableRow...

обернуть содержимое в линейный макет

в виде списка добавить: 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>

Если вы хотите, чтобы содержимое под списком перемещалось вниз по мере добавления элементов в список, попробуйте следующее решение:

добавить положительное заполнение в нижней части списка и отрицательное заполнение в верхней части "нижнего колонтитула". Это будет работать в линейной компоновке или относительной компоновке.

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