Освой программирование играючи
/* Моя кошка замечательно разбирается в программировании. Стоит мне объяснить проблему ей - и все становится ясно. */
John Robbins, Debugging Applications, Microsoft Press, 2000
ReiativeLayout (относительная разметка) находится в разделе Layouts и позволяет дочерним компонентам определять свою позицию относительно родительского компонента или относительно соседних дочерних элементов (по идентификатору элемента). В RelativeLayout дочерние элементы расположены так, что если первый элемент расположен по центру экрана, другие элементы, выровненные относительно первого элемента, будут выровнены относительно центра экрана. При таком расположении, при объявлении разметки в XML-файле, элемент, на который будут ссылаться для позиционирования другие объекты представления, должен быть объявлен раньше, чем другие элементы, которые обращаются к нему по его идентификатору.
Важные атрибуты, которые связаны с родителем.
Некоторые атрибуты можно использовать вместе, чтобы добиться нужного эффекта, например, разместить компонент в верхнем правом углу.
Компонент можно размещать не только относительно родителя, но и относительно других компонентов. Для этого все компоненты должны иметь свой идентификатор, по которому их можно будет отличать друг от друга. В этом случае вы можете задействовать другие атрибуты.
Чтобы компоненты "не прилипали" друг к другу, используются атрибуты, добавляющие пространство между ними.
Рассмотрим простой пример. Допустим, мы хотим поместить на экран элементы EditText и Button. Кнопка должна находиться справа от текстового поля. Текстовое поле при этом должно быть выравнено слева относительно родительского элемента (компоновки) и слева относительно кнопки. В свою очередь кнопка должна быть выравнена справа относительно шаблона компоновки.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<EditText
android:id="@+id/editText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_toLeftOf="@+id/button"
android:hint="Введите имя кота..." >
</EditText>
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:text="Нажми нежно!" >
</Button>
</RelativeLayout>
Во многих случаях грамотная относительная компоновка хорошо смотрится в альбомной и портретной ориентации.
Если вам понадобится динамически создавать относительную разметку в коде, то делается это следующим образом:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// setContentView(R.layout.activity_main);
EditText editText = new EditText(this);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.WRAP_CONTENT);
params.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
// use same id as defined when adding the button
params.addRule(RelativeLayout.LEFT_OF, 1001);
editText.setLayoutParams(params);
editText.setHint("Введите имя кота....");
Button button = new Button(this);
RelativeLayout.LayoutParams params2 = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT);
params2.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
button.setLayoutParams(params2);
button.setText("Нажми нежно!");
// give the button an id that we know
button.setId(1001);
RelativeLayout layout = new RelativeLayout(this);
layout.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
layout.addView(editText);
layout.addView(button);
setContentView(layout);
}
Создавать компоновку для относительной разметки чуть сложнее, чем для линейной компоновки. Рассмотрим ещё один пример. Предположим, нам нужен такой экран
Шаг 1: В XML-файле задаем относительную компоновку.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</RelativeLayout>
Шаг 2: Определяем дочерние элементы. В нашем случае мы имеем семь текстовых меток разного цвета. Каждому элементу присваиваем необходимые свойства: текст, цвет, размер символов и так далее.
Шаг 3: Определяем правила относительной разметки.
Красная метка должна находиться в правом верхнем углу родительского элемента.
Оранжевая метка должна располагаться по центру по горизонтали относительно родительского элемент.
Желтая метка выравнивается по правой части родительского элемента.
Зелёная метка выравнивается по центру (по вертикали) и выводится слева от синей метки.
Синяя метка выравнивается по центру (по вертикали и горизонтали) относительно родительского элемента, т.е. точно по центру.
Метка цвета индиго выравнивается по центру (по вертикали) и выводится справа от синей метки.
Фиолетовая метка выводится в нижней части родительского элемента и занимает всю её ширину.
Код разметки:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="@+id/TextView01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#f00"
android:gravity="center"
android:padding="25dp"
android:text="RED"
android:textColor="#000" >
</TextView>
<TextView
android:id="@+id/TextView02"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:background="#ffa500"
android:gravity="center"
android:padding="25dp"
android:text="ORANGE"
android:textColor="#000" >
</TextView>
<TextView
android:id="@+id/TextView03"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:background="#ffff00"
android:gravity="center"
android:padding="25dp"
android:text="YELLOW"
android:textColor="#000" >
</TextView>
<TextView
android:id="@+id/TextView04"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toLeftOf="@+id/TextView05"
android:background="#0f0"
android:gravity="center"
android:padding="25dp"
android:text="GREEN"
android:textColor="#000" >
</TextView>
<TextView
android:id="@+id/TextView05"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_margin="10dp"
android:background="#00f"
android:gravity="center"
android:padding="25dp"
android:text="BLUE"
android:textColor="#fff" >
</TextView>
<TextView
android:id="@+id/TextView06"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toRightOf="@+id/TextView05"
android:background="#4b0082"
android:gravity="center"
android:padding="25dp"
android:text="INDIGO"
android:textColor="#fff" >
</TextView>
<TextView
android:id="@+id/TextView07"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="#ee82ee"
android:gravity="center"
android:padding="25dp"
android:text="VIOLET"
android:textColor="#000" >
</TextView>
</RelativeLayout>
При разработке макета с относительной разметкой следите, чтобы элементы не налезали друг на друга (можете получить сообщение об ошибке). Старайтесь не усложнять макет и не забывайте присваивать уникальный идентификатор каждому элементу. Проверяйте макет в разных режимах ориентации.
С помощью RelativeLayout можно создать неподвижную полоску внизу экрана, которая не будет прокручиваться вместе со списком. Для этого используется атрибут android:layout_alignParentBottom и родственные ему атрибуты для верхней части. Вот простой пример со списком.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ListView
android:id="@+id/listView1"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<LinearLayout
android:id="@+id/layout_bottom_bar"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="#222222"
android:clickable="true"
android:gravity="center"
android:orientation="horizontal"
android:padding="5dip" >
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#000000"
android:gravity="center"
android:padding="5dip"
android:text="Неподвижная часть"
android:textColor="#FFFFFF" />
</LinearLayout>
</RelativeLayout>
И простой код для создания прокручиваемого списка, чтобы увидеть эффект неподвижной полоски с кнопкой.
package ru.alexanderklimov.relativelayout;
import android.app.Activity;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.ListView;
public class RelativeLayoutActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView listView = (ListView) findViewById(R.id.listView1);
// определяем массив типа String
final String[] catnames = new String[] { "Рыжик", "Барсик", "Мурзик",
"Мурка", "Васька", "Томасина", "Кристина", "Пушок", "Дымка",
"Кузя", "Китти", "Масяня", "Симба" };
// используем адаптер данных
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, catnames);
listView.setAdapter(adapter);
}
}
Запускаем проект и любуемся своей работой: