2013-08-18 4 views
6

Я полагаю, что это должно быть довольно легко ответить, если вы понимаете XML-макеты лучше, чем я. Кажется, я не понимаю, что я думал, когда должен использовать match_parent layout_height.match_parent не работает должным образом

У меня есть LinearLayout корневой элемент с Android: ориентация = "вертикальный". Внутри этого LinearLayout я хочу три элемента: - TextView - ListView - TextView

Для обоих TextViews я установить андроид: layout_height = «wrap_content» так, что они будут только как высокий, как это необходимо, чтобы отобразить их содержание. Дело в том, что я хочу, чтобы один TextView сидел в верхней части формы, а другой - в нижней части формы, в то время как ListView заполняет все пространство, доступное в форме. Так вот, что мой макет XML выглядит следующим образом:

<TextView 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:textSize="30sp" 
    android:text="Top TextView" /> 

<ListView 
    android:id="@+id/listView_Species" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" /> 

<TextView 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:textSize="30sp" 
    android:text="Bottom TextView" /> 

Но это не работает. Вот что я получаю. Я выбрал ListView так, чтобы он был выделен. Обратите внимание на то, как он распространяется до самого конца формы, выталкивая нижний TextView из формы. XML Layout 1

Когда я изменяю свойство layout_height ListView на некоторое фиксированное значение, например 180dp, это выглядит так. Я просто публикую это, чтобы доказать, что нижний TextView есть, но я до сих пор не знаю, как заставить его фиксироваться в нижней части экрана, в то время как ListView занимает все пространство, но между двумя TextView.

XML Layout 2

Спасибо заранее.

ответ

7

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

Во-первых, как работают представления в LinearLayout? Давайте рассмотрим процесс рисования LinearLayout, используя для этого простоту orientation="vertical".

  1. Изучите высоту первого ребенка LinearLayout (для краткости LL). Если высота match_parent или fill_parent (старое название для одного и того же предмета), тогда высота представления растягивается, чтобы заполнить всю область просмотра. Если высота равна wrap_content, измерьте вертикальное пространство, которое занимает вид, и используйте это пространство для представления. Если высота - это ненулевое число, используйте ровно столько пикселей для высоты представления (возможно, зажим, если он слишком мал). Если высота равна 0, см. Ниже.
  2. Оставьте следующий вид ниже вид в 1. Проверьте его высоту и действуйте соответствующим образом.
  3. Продолжение для всех видов. Если представление сдвинуто вниз, продолжайте и прекратите вычисление, потому что никто не увидит его или какие-либо последующие представления (если не считать ScrollView).
  4. Если высота представления равна 0, проверьте его gravity. Это требует второго прохода, сохраняя гравитацию всех видов, а затем пропорционально распределяя их высоты. Как вы можете догадаться, второй проход удваивает макет времени, что не существенно для простых макетов.

Объяснение вашего примера: Первый ребенок из LL (первая TextView) измеряется и принимает определенное количество пикселей. Затем ваш ListView занимает все оставшееся пространство (через match_parent). И тогда ваш второй TextView не нарисован вообще, поскольку он находится в нижней части экрана. Это в значительной степени то, что вы наблюдали, но теперь вы понимаете, почему.

Решение: Использовать RelativeLayout. В этом случае отлично работает.

<RelativeLayout 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content"> 

    <TextView 
     android:id="@+id/top_tv" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:layout_alignParentTop="true" 
     android:textSize="30sp" 
     android:text="Top TextView" /> 

    <TextView 
     android:id="@+id/bottom_tv" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:layout_alignParentBottom="true" 
     android:textSize="30sp" 
     android:text="Bottom TextView" /> 

    <ListView 
     android:id="@+id/listView_Species" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:layout_below="@id/top_tv" 
     android:layout_above="@id/bottom_tv" 
     /> 
</RelativeLayout> 

RelativeLayout рассказывает макет Inflater сделать первый TextView в верхней части, а затем сделать второй TextView в нижней части, а затем заполнить оставшуюся часть пространства с ListView. Я считаю, что это именно то, что вы хотите.

Добро пожаловать на Android. Вы будете использовать этот шаблон LOT!

3

использовать android: layout_weight, чтобы определить весы для ваших виджетов внутри самого внешнего макета. Объявите их высоту как 0dp, а затем определите android:layout_weight каждому из них. Общая сумма взвешивания трех из них должна быть 1. В соответствии с вашей потребностью вы можете определить вес 0.1 как для верхнего, так и для нижнего текста и определить 0.8 в ListView.

<TextView 
    android:layout_width="match_parent" 
    android:layout_height="0dp" 
    android:layout_weight = "0.1" 
    android:textSize="30sp" 
    android:text="Top TextView" /> 

<ListView 
    android:id="@+id/listView_Species" 
    android:layout_width="match_parent" 
    android:layout_weight = "0.8" 
    android:layout_height="0dp" /> 

<TextView 
    android:layout_width="match_parent" 
    android:layout_height="0dp" 
    android:textSize="30sp" 
    android:layout_weight = "0.1" 
    android:text="Bottom TextView" /> 
+0

Я поддерживаю ваш ответ, но он не дает мне то, что я хотел. Это заставляет TextViews также растягиваться на определенный процент от размера экрана. Я хочу, чтобы они были исправлены, пока только ListView растягивается, чтобы заняться оставшимся пространством. Royi выше, разместил решение для этого. –

11

Изменение ListView высота 0dp и добавить weight=1
т.е.

<TextView 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:textSize="30sp" 
    android:text="Top TextView" /> 

<ListView 
    android:id="@+id/listView_Species" 
    android:layout_width="match_parent" 
    android:layout_height="0dp" 
    android:layout_weight="1" /> 

<TextView 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:textSize="30sp" 
    android:text="Bottom TextView" /> 
+0

Так много для объяснения. Вздох. –