Ограничение высоты ListView на Android
Я хочу показать кнопку под ListView
. Проблема в том, что если расширение ListView
расширяется (элементы добавлены...), кнопка выталкивается из экрана.
Я попробовал a LinearLayout
с весами (как было предложено в Android: почему нет maxHeight для просмотра?), но либо я получил неправильные веса, либо это просто не сработало.
Кроме того, я нашел где-то подсказку использовать RelativeLayout
. ListView
затем будет установлен над кнопкой с параметром android:layout_above
.
Проблема в том, что я не знаю, как позиционировать кнопку после этого. В приведенном примере представление ниже ListView
было отредактировано с помощью android:layout_alignParentBottom
, но я не хочу, чтобы моя кнопка цеплялась за нижнюю часть экрана.
Любые идеи, кроме использования метода setHeight и некоторого вычисления требуемого пространства?
Изменить:
Я получил много полезных ответов.
-
Решение bigstone и user639183 почти отлично работало. Тем не менее, мне пришлось добавить дополнительное дополнение/маркер к нижней части кнопки, поскольку оно все равно будет вытолкнуто наполовину из экрана (но затем остановлено).
-
Ответ Adinia с относительной компоновкой подходит, если вы хотите, чтобы кнопка была зафиксирована в нижней части экрана. Это не то, что я намеревался, но все же может быть полезным для других.
-
Решение AngeloS было тем, что я выбрал в конце, поскольку он только что создал эффекты, которые я хотел. Тем не менее, я сделал два незначительных изменения в LinearLayout
вокруг кнопки:
-
Во-первых, поскольку я не хотел иметь каких-либо абсолютных значений в своем макете, я изменил android:layout_height="45px"
на wrap_content
, что тоже отлично работает.
-
Во-вторых, так как я хотел, чтобы кнопка была центрирована по горизонтали, которая поддерживается только вертикальной LinearLayout
, я изменил андроид: ориентация = "горизонтальная" на "вертикальная".
AngeloS также заявил в своем первоначальном сообщении, что он не был уверен, что параметр android:layout_weight="0.1"
в LinearLayout
вокруг ListView
имел какой-либо эффект; Я просто попробовал, и это действительно так! Без кнопки кнопка снова выталкивается из экрана.
Ответы
Ответ 1
У меня была эта точная проблема, и для ее решения я создал два отдельных 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>
Ответ 2
Я решил эту проблему в коде, установив высоту 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 раза больше высоты одного элемента, поэтому пользователь точно знает, что есть прокрутка!:)
Ответ 3
В последнем редакторе вам просто нужно добавить 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]()
Ответ 4
Используя LinearLayout
, установите высоту ваших ListView
и Button
на wrap_content
и добавьте вес = 1 в ListView
. Это должно работать так, как вы хотите.
И да, установите layout_gravity
в Button
на bottom
Ответ 5
RelativeLayout
- это решение, если вы не хотите, чтобы кнопка оставалась слишком близко к основанию, вы можете добавлять поля (добавление кнопки приведет к ее разрыву, поскольку использует фон с 9 патчами и устанавливает собственные обивка).
Было бы одинаково, если бы вы использовали LinearLayout
: способ достичь того, что вы хотите, - установить ListView
на высоту = 0 и вес = 1, а для высоты кнопки = wrap_content и weight = 0. (установка как wrap_content, так и user639183, не ограничивает высоту ListView
).
Ответ 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"
/>
Ответ 7
Возможно, вы можете сделать эту работу с помощью вложенных контейнеров. Возможно, вам понадобится обернуть кнопку во втором (внутреннем) контейнере, чтобы она занимала больше места и просто выровняла кнопку в верхней части внутреннего контейнера.
Возможно что-то вроде этого:
RelativeLayout
- ListView
- RelativeLayout
---- Кнопка
Используя различные параметры выравнивания в двух контейнерах, вы сможете заставить это работать.
Ответ 8
Это самый чистый способ сделать это:
<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, чтобы обернуть кнопку.
Ответ 9
Идея изложена в очень хороших решениях:
Оба они, кажется, работают отлично, по крайней мере, на 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);
}
});
}
}
Не стесняйтесь добавлять или улучшать, так как это "вики сообщества".
Ответ 10
Попробуйте использовать RelativeLayout с кнопкой внизу. Задайте высоту макета как "wrap_content".
Я не пробовал. Просто идея
Ответ 11
в LinearLayout, просто добавьте android:layout_weight="1"
к вам ListView
Ответ 12
Следующее - то, что сработало для меня...
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 и ListView внутри TableRow...
Ответ 13
обернуть содержимое в линейном макете
в списке просмотра добавить:
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>
Ответ 14
Если вы хотите, чтобы содержимое, расположенное ниже списка, перемещалось вниз по мере добавления элементов в список, попробуйте это решение:
Добавьте положительное дополнение к нижней части списка и отрицательное дополнение к верхней части "нижнего колонтитула". Это будет работать в линейной компоновке или относительной компоновке.
<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"/>
Ответ 15
Поскольку нет атрибута MaxHeight, лучше всего либо установить высоту списка ListView в заданное значение, либо использовать wrap_content
.
Ответ 16
Я решил это, поставив 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>