Android. Различия в разметках FrameLayout, RelativeLayout, LinearLayout и TableLayout

февраля
07
2012
Метки: android layout

Рассмотрим принципиальные отличительные черты четырех типов разметки в Android: FrameLayout, RelativeLayout, LinearLayout и TableLayout.

FrameLayout

FrameLayout - самый простой тип разметки. Может содержать только один дочерний элемент типа View или ViewGroup, который будет выравниваться по верхней левой границе. При добавлении последующих элементов они будут перекрывать друг друга. Пример:

FrameLayout

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >
  
    <Button android:text="@string/button_text"
        android:id="@+id/btn1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</FrameLayout>

LinearLayout

LinearLayout в отличие от FrameLayout может содержать больше одного элемента. Как следует из названия, LinearLayout является линейной разметкой, дочерние элементы которой размещаются друг за другом. Может размещать элементы как горизонтально, так и вертикально. При вертикальном размещении каждый элемент занимает отдельную строку, а при горизонтальном - элементы размещаются в одной строке, причем высота строки является высотой самого высокого дочернего элемента. Пример LinearLayout разметки с вертикальной ориентацией:

LinearLayout (horizontal)

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

    <Button android:text="I'm first button"
        android:id="@+id/btn1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="I'm text" />
    
    <Button android:text="I'm second button"
        android:id="@+id/btn2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</LinearLayout>

Рис 1. LinearLayout. Вертикальная ориентация
Рис 1. LinearLayout. Вертикальная ориентация

Чтобы получить горизонтальное размещение, достаточно изменить атрибут android:orientation, присвоив ему значение horizontal:

Рис 2. LinearLayout. Горизонтальная ориентация
Рис 2. LinearLayout. Горизонтальная ориентация

Если Вы хотите, чтобы последний элемент "заливал" оставшееся на строке пространство, необходимо изменить его атрибут android:layout_width, присвоив значение: fill_parent:

Horizontal LinearLayout с использованием fill_parent

...
    <Button android:text="Second"
        android:id="@+id/btn2"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" />
...

Результат выполнения этого примера показан на рис. 3:

Рис 3. LinearLayout. Горизонтальная ориентация с использованием fill_parent
Рис 3. LinearLayout. Горизонтальная ориентация с использованием fill_parent

Рассмотрим еще одно широко используемое свойство - layout_weight ("вес размещения") на следующем примере:

Horizontal LinearLayout с использованием layout_weight

<?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="horizontal" >

    <Button android:text="Button1"
        android:id="@+id/btn1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1" />
    
    <Button android:text="Button2"
        android:id="@+id/btn2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="2" />
    
    <Button android:text="Button3"
        android:id="@+id/btn2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="0" />

</LinearLayout>

Рис 4. LinearLayout. Горизонтальная ориентация с использованием layout_weight
Рис 4. LinearLayout. Горизонтальная ориентация с использованием layout_weight

Как видно с Рис. 4, наибольшее пространство занимает Button2 из-за того, что имеет самый высокий layout_weight="2" среди остальных элементов. Button1 имеет вес 1 и поэтому занимает немного меньше пространства, чем Button2. Кнопка с самым низким весом, Button3, занимает меньше всего пространства.

Если бы кнопки Button1 и Button2 имели одинаковый вес, то занимали бы одинаковое пространство. А вот так располагаются кнопки в случае одинакового значения layout_weight:

Рис 5. LinearLayout. Горизонтальная ориентация с одинаковым layout_weight
Рис 5. LinearLayout. Горизонтальная ориентация с одинаковым layout_weight

TableLayout

TableLayout позволяет создавать разметку по подобию таблицы в html. Строка таблицы, TableRow, может не иметь ячеек или иметь несколько ячеек. Допускается также ячейки типа ViewGroup. То есть, ячейка может быть другим типом разметки, в том числе и TableLayout. Пример TableLayout:

TableLayout

<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >

    <TableRow
        android:id="@+id/row1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" >

        <Button
            android:id="@+id/btn1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="1" />

        <Button
            android:id="@+id/btn2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="2" />

        <Button
            android:id="@+id/btn3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="3" />
    </TableRow>

    <TableRow
        android:id="@+id/row2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" >

        <Button
            android:id="@+id/btn4"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="4" />

        <Button
            android:id="@+id/btn5"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="5" />

        <Button
            android:id="@+id/btn6"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="6" />
    </TableRow>

    <TableRow
        android:id="@+id/row3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" >

        <Button
            android:id="@+id/btn7"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="7" />

        <Button
            android:id="@+id/btn8"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="8" />

        <Button
            android:id="@+id/btn9"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="9" />
    </TableRow>

</TableLayout>

Рис 6. TableLayout
Рис 6. TableLayout

Для дочерних элементов так же как и в LinearLayout может использоваться свойство layout_weight. Изменим следующим образом пример: установим атрибут android:layout_weight="1" для элементов btn4, btn5 и btn6:

Рис 7. TableLayout с использованием layout_weight
Рис 7. TableLayout с использованием layout_weight

Чтобы выровнять таблицу вертикально по центру, необходимо добавить атрибут android:gravity="center" в TableLayout:

Рис 8. TableLayout с gravity=center
Рис 8. TableLayout с gravity=center

А чтобы выровнять по центру каждую строчку достаточно добавить атрибут android:gravity="center" во все три TableRow:

Рис 9. TableLayout с атрибутом gravity в TableRow
Рис 9. TableLayout с атрибутом gravity в TableRow

Исходный код получившейся разметки представлен ниже:

TableLayout. Эксперименты с gravity и layout_weight

<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:gravity="center" >

    <TableRow
        android:id="@+id/row1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
    	android:gravity="center" >

        <Button
            android:id="@+id/btn1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="1" />

        <Button
            android:id="@+id/btn2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="2" />

        <Button
            android:id="@+id/btn3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="3" />
    </TableRow>

    <TableRow
        android:id="@+id/row2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
    	android:gravity="center" >

        <Button
            android:id="@+id/btn4"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="4" 
            android:layout_weight="1" />

        <Button
            android:id="@+id/btn5"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="5" 
            android:layout_weight="1" />

        <Button
            android:id="@+id/btn6"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="6" 
            android:layout_weight="1" />
    </TableRow>

    <TableRow
        android:id="@+id/row3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
    	android:gravity="center" >

        <Button
            android:id="@+id/btn7"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="7" />

        <Button
            android:id="@+id/btn8"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="8" />

        <Button
            android:id="@+id/btn9"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="9" />
    </TableRow>

</TableLayout>

RelativeLayout

RelativeLayout - элементы этого способа разметки могут располагаться относительно друг друга, не следуя принципам поведения LinearLayout и TableLayout. Пример:

RelativeLayout. toLeftOf и toRightOf

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

    <Button
        android:id="@+id/btn1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:text="1" />

    <Button
        android:id="@+id/btn2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toLeftOf="@id/btn1"
        android:text="2" />

    <Button
        android:id="@+id/btn3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@id/btn1"
        android:text="3" />
</RelativeLayout>

Первым элементом в списке размещения является кнопка с идентификатором btn1, однако фактически она будет второй слева. Это произойдет потому что слева от нее будет располагаться кнопка btn2, следуя инструкции layout_toLeftOf="@id/btn1" (переводится как "слева от btn1"). А кнопка btn3 будет всегда располагаться справа от btn1, следуя инструкции layout_toRightOf="@id/btn1" (переводится как "справа от btn1"). Горизонтальное расположение btn1 по центру достигается благодаря атрибуту layout_centerHorizontal="true". Результат выполнения этого кода представлен на Рис. 10.

Рис 10. RelativeLayout. toLeftOf и toRightOf
Рис 10. RelativeLayout. toLeftOf и toRightOf

Рассмотрим еще 2 атрибута, которые могут быть использованы в RelativeLayout: layout_above и layout_below. Атрибут layout_above означает, что элемент будет располагаться над элементом, указанным в атрибуте. В свою очередь, атрибут layout_below означает, что элемент будет располагаться под указанным в атрибуте элементом. Пример:

RelativeLayout. layout_above и layout_below

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

    <Button
        android:id="@+id/btn_center"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:text="Center" />

    <Button
        android:id="@+id/btn_left"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:layout_toLeftOf="@id/btn_center"
        android:text="Left" />

    <Button
        android:id="@+id/btn_right"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:layout_toRightOf="@id/btn_center"
        android:text="Right" />
    
    <Button
        android:id="@+id/btn_top"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:layout_above="@id/btn_center"
        android:text="Top" />
    
    <Button
        android:id="@+id/btn_bottom"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:layout_below="@id/btn_center"
        android:text="Bottom" />
    
</RelativeLayout>

Результат выполнения этого кода представлен на Рис.11.

Рис 11. RelativeLayout. layout_above и layout_below
Рис 11. RelativeLayout. layout_above и layout_below

Напишите первое сообщение!

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