ListView выталкивает другие виды с экрана - PullRequest
9 голосов
/ 09 марта 2012

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

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

Визуальный результат

Когда ListView не нужно прокручивать (это правильно):

when the ListView doesn't need to scroll

Когда необходимо прокрутить ListView, нижний колонтитул и серый прямоугольник отодвигаются от экрана (неправильно):

when the ListView needs to scroll

Компоновка

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="fill_parent"
              android:layout_height="fill_parent"
              android:orientation="vertical">
    <TextView
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="header"
            android:padding="20dp"
            android:textSize="18sp"
            android:background="@color/red"/>
    <ListView android:layout_width="fill_parent"
              android:layout_height="wrap_content"
              android:id="@android:id/list" />
    <TextView
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="this should be directly below the ListView, but not pushed off screen when the ListView needs to scroll"
            android:padding="5dp"
            android:background="@color/light_gray"
            android:textColor="@color/black"/>
    <!-- Used to push the footer to the bottom -->
    <View android:layout_width="0dp" android:layout_height="0dp" android:layout_weight="1"/>
    <TextView
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="footer"
            android:padding="20dp"
            android:textSize="18sp"
            android:background="@color/blue"/>
</LinearLayout>

Тестовое задание

public class TestActivity extends ListActivity
{
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        ArrayList<String> items = new ArrayList<String>();
        items.add("one");
        items.add("two");
        items.add("three");
        items.add("four");
        items.add("five");
        items.add("six");
        items.add("seven");
        items.add("eight");
        items.add("nine");
        items.add("ten");
        setListAdapter(new ArrayAdapter<String>(this, R.layout.simple_list_item_1, items));
        setContentView(com.myproject.android.R.layout.test);
    }
}

Я пробовал несколько разных подходов, например, дал ListView layout_weight="1" и удалил пробел View, который я использую, чтобы сдвинуть нижний колонтитул вниз. Это почти то, что я хочу, он сохраняет нижний колонтитул и метку видимыми, когда ListView прокручивается, но когда в нем только 1 или 2 элемента, мне нужен серый прямоугольник прямо под ListView. Я также попытался использовать RelativeLayout, но безуспешно. Полагаю, я совершенно неправильно понимаю вещи.

EDIT

Вот моя попытка с RelativeLayout, которая все еще не верна.

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                android:layout_width="fill_parent"
                android:layout_height="fill_parent">
    <TextView
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="header"
            android:padding="20dp"
            android:textSize="18sp"
            android:background="@color/red"
            android:id="@+id/header"
            />
    <ListView android:layout_width="fill_parent"
              android:layout_height="wrap_content"
              android:id="@android:id/list"
              android:layout_below="@id/header"/>
    <TextView
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="this should be directly below the ListView, but not pushed off screen when the ListView needs to scroll"
            android:padding="5dp"
            android:background="@color/light_gray"
            android:textColor="@color/black"
            android:layout_below="@android:id/list"/>

    <TextView
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="footer"
            android:padding="20dp"
            android:textSize="18sp"
            android:background="@color/blue"
            android:layout_alignParentBottom="true"
            android:id="@+id/footer"/>
</RelativeLayout>

Относительное расположение (все еще неправильно):

relative layout attempt

Ответы [ 5 ]

9 голосов
/ 09 марта 2012

Добавить android:layout_weight="1" в список просмотра.Это сделает его самым большим элементом в LinearLayout, не отталкивая другие от экрана.

7 голосов
/ 09 марта 2012

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

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent">
<TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="header"
        android:padding="20dp"
        android:textSize="18sp"
        android:background="@color/red"
        android:id="@+id/header"
        />
<TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="footer"
        android:padding="20dp"
        android:textSize="18sp"
        android:background="@color/blue"
        android:layout_alignParentBottom="true"
        android:id="@+id/footer"/>
<ListView android:layout_width="fill_parent"
          android:layout_height="fill_parent"
          android:id="@android:id/list"
          android:layout_below="@id/header"
          android:layout_above="@id/footer"/>


</RelativeLayout>

Хорошо.Этот XML решает проблему отсутствующего нижнего колонтитула.Теперь мы должны добавить серый квадрат в конце списка.Я думаю, что есть два способа сделать это:

1 голос
/ 18 ноября 2014

Два года спустя, чтобы ответить на вопрос, но я оставлю свое решение, чтобы оно могло помочь кому-то с той же проблемой. Я решаю эту проблему, используя 2 вложенных LinearLayouts и используя layout_weigth. Возможно, не самый лучший перфоманс, но он достигает желаемого эффекта.

Вам необходимо расположить макет следующим образом:

  1. Ваш ListView будет иметь высоту wrap_content, чтобы занимать только необходимое пространство, когда не заполняет весь экран.
  2. Ваш ListView будет находиться внутри макета с высотой, используя layout_weight, поэтому список будет занимать только необходимое пространство, если он не заполняет весь экран, и занимать только ограниченное пространство экрана, когда его размер увеличен для выталкивания представлений экран.
  3. Вид серого прямоугольника, который должен находиться непосредственно под списком, будет иметь высоту wrap_content и будет представлять собой макет шага 2.
  4. Этот макет и серый прямоугольник будут внутри второго макета с высотой wrap_content, чтобы они могли оставаться вместе.
  5. Теперь у вас есть макет со списком и серым видом, и список не вытеснит другие виды из экрана, если он станет слишком большим; вам нужно только переместить нижний колонтитул в нижнюю часть экрана.

    5a. Если вы используете RelativeLayout в качестве корневого макета, вы можете сделать так, как сказал sgallego, и использовать android: layout_alignParentBottom.

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

Вот пример с комментариями.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <!-- Header -->
    <TextView
        android:id="@+id/RecordStudy_StudyLabel"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/RecordStudy_StudyLabel"
        android:textSize="@dimen/text_large" />

    <!-- Body -->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:orientation="vertical" >

        <!--
        This layout encapsules the list and the button that must be immediately
        below the list with a wrap_content height, so the list plus the button
        fills only as much space as they need (if the list is not big enouth to
        fill the entire screen).
        -->
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical" >

            <!--
            Layout with varaible size with a list inside.
            Using layout_weight tells android that this layout should not grow
            greater then the screen, but uses only the free space. 
             -->
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="0dp"
                android:layout_weight="1"
                android:orientation="vertical" >

                <!--
                Inside this limited height layout, there is a list with height
                wrap_content so it can grow as much as it needs INSIDE the
                layout (through scrolling).
                -->
                <ListView
                    android:id="@+id/RecordStudy_StudyList"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content" />

            </LinearLayout>

            <!-- Button immediately below the list -->
            <Button
                android:id="@+id/RecordStudy_AddStudy"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="@string/RecordStudy_AddStudy" />

        </LinearLayout>

        <!-- Space between the list and the footer -->
        <View
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1" />

    </LinearLayout>

    <!-- Footer -->
    <Button
        android:id="@+id/RecordStudy_ConfirmButton"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/RecordStudy_ConfirmButton" />

</LinearLayout>
0 голосов
/ 22 ноября 2016

Решение, которое работало для меня, состояло в том, чтобы добавить положительный отступ в конец списка и отрицательный отступ в верхнюю часть «нижнего колонтитула».Это будет работать в линейном или относительном макете.

<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"/>
0 голосов
/ 03 сентября 2014

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

Примерно так:

<TextView
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="header"
            android:padding="20dp"
            android:textSize="18sp"
            android:background="@color/red"
            android:id="@+id/header"
            />

<LinearLayout
    android:layout_width="fill_parent"
    android:layout_height="150dip" //assume 150dip height is sufficient

    <ListView android:layout_width="fill_parent"
              android:layout_height="wrap_content"
              android:id="@android:id/list"
              android:layout_below="@id/header"/>
</LinearLayout>

    <TextView
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="this should be directly below the ListView, but not pushed off screen when the ListView needs to scroll"
            android:padding="5dp"
            android:background="@color/light_gray"
            android:textColor="@color/black"
            android:layout_below="@android:id/list"/>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...