четверг, 28 мая 2015 г.

TextView - отображение текста

Элемент TextView — самый простой и в то же время один из самых используемых в приложениях элементов. TextView служит для отображения текста без возможности его редактирования.

Кроме того, элемент TextView используется как элемент для отображения данных в контейнерных элементах-списках. От класса TextView наследуется множество других элементов: кнопки, флажки и переключатели — элементы управления, на которых может быть отображен текст. В будущих уроках, мы будем активно применять этот элемент для отображения состояния элементов при обработке событий.

Элемент TextView, так же как и объект View, от которого он наследуется, поддерживает собственное разнообразие XML-атрибутов. Некоторые атрибуты являются определенными только в объекте TextView, но эти атрибуты могут также наследоваться любыми объектами, которые расширяют этот класс.

Свойства для элемента TextView можно задавать как в файле компоновки, так и в программном коде. Например, для отображения текста в TextView в файле компоновки используется атрибут android:text, а в программном коде вызывается метод setText() этого класса.

В целом, XML-словарь элементов пользовательского интерфейса близок к структуре классов и методов этих элементов, где имя элемента соответствует имени класса, а атрибуты элемента — методам этого класса. Фактически, соответствие является часто настолько точным, что легко предположить без обращения к документации Android, какой XML-атрибут передает метод класса или, наоборот, какой метод класса соответствует конкретному XML-элементу. В таблице приведены для примера несколько свойств элемента TextView, чтобы вы могли оценить точность соответствия XML-атрибутов и методов класса TextView.

Соответствие XML-атрибутов и методов в классах представлений

Имя XML-атрибута Соответствующий метод в классе Java
android:text setText()
android:textColor setTextColor()
android:textSize setTextSize()
android:textColorHighlight setHighlightColor()

Однако обратите внимание на последнюю строку в таблице: не всегда XML-словарь идентичен структуре java-классов.

Некоторые атрибуты элемента TextView являются общими по отношению ко всем объектам View, потому что они унаследованы от корневого класса View. Такими атрибутами являются, например, id, layout_width, layout_height, с которыми вы уже познакомились в главе 4.

Если в программном коде мы работаем с данным элементом пользовательского интерфейса, в файле компоновки обязательно определяют идентификатор, например:
android:id="@+id/text1"

где символ @ в начале строки указывает, что синтаксический анализатор XML должен проанализировать и развернуть остальную часть строки идентификатора и определить это выражение как ресурс идентификатора. Символ + означает, что это новое имя ресурса, которое должно быть создано и добавлено к нашим ресурсам в файл R.java, автоматически генерируемый средой Android для проекта.

Требование к уникальности идентификаторов не распространяется на все дерево элементов, но они должны быть уникальны в пределах части дерева (которая нередко может быть и полным деревом, так что лучше создавать совершенно уникальные идентификаторы, если это возможно).

Если планируется создание приложения с многоязыковой поддержкой пользовательского интерфейса, вместо непосредственного задания текста в XML-компо­новке или в коде программы необходимо создать ссылку на текстовый XML-ресурс:

android:text="@string/text_hello"

где text_hello — имя ресурса.

В коде программы ссылка на XML-ресурс задается методом setText(), который принимает ссылку на идентификатор ресурса, определенного в файле R.java (автоматически сгенерированном средой разработки), например:

final TextView text = (TextView)findViewById(R.id.text4); 
        text4.setText(R.string.text_hello); 
У элемента TextView есть многочисленные методы и XML-атрибуты для работы с текстом. Например, основные XML-атрибуты, отображающие свойства элемента TextView:

  • android:textSize;
  • android:textStyle;
  • android:textColor.
Атрибут android:textSize задает размер текста. При этом используют несколько единиц измерения:

  • px (pixels) — пикселы;
  • dp (density-independent pixels) — независимые от плотности пикселы. Это абстрактная единица измерения, основанная на физической плотности экрана;
  • sp (scale-independent pixels) — независимые от масштабирования пикселы;
  • in (inches) — дюймы, базируются на физических размерах экрана;
  • pt (points) — 1/72 дюйма, базируются на физических размерах экрана;
  • mm (millimeters) — миллиметры, также базируются на физических размерах экрана.
Обычно при установке размера текста используются единицы измерения sp, которые наиболее корректно отображают шрифты, например:

android:textSize="48sp";
Атрибут android:textStyle представляет стиль текста (нормальный, полужирный, наклонный). Для задания стиля текста используются только следующие константы:

  • normal;
  • bold;
  • italic.
Вот пример установки стиля через атрибуты в файле компоновки:

android:textStyle="bold";
Атрибут android:textColor задает цвет текста. Для задания цвета используются четыре формата в шестнадцатеричной кодировке:

  • #RGB;
  • #ARGB;
  • #RRGGBB;
  • #AARRGGBB,
где R, G, B — соответствующий цвет, А — альфа-канал (alpha-channel), который определяет прозрачность. Значение A, установленное в 0, означает прозрачность 100%. Значение по умолчанию без указания значения A равно 1, т. е. непрозрачно.

Для всех перечисленных ранее атрибутов в классе TextView есть соответствующие методы для чтения или задания соответствующих свойств.

Сейчас мы создадим простое приложение с элементом TextView, в котором рассмотрим различные способы задания его свойств — через атрибуты в файле компоновки и программно, в коде класса, реализующего окно приложения. Для этого создайте новый проект. Для файла компоновки в уроках будет имя main.xml, так, на мой взгляд, удобнее main.xml, а ему соответствует java-класс MainActivity но, если хотите используйте имя по умолчанию  — activity_main.xml). Откройте файл компоновки добавьте компоновку LinearLayout и в ней четыре элемента TextView с идентификаторами text1, text2, text3, text4.
Для text1 задайте текст непосредственно в XML-коде. Для элемента text2 текст задайте через ссылку на строковый ресурс. Можно также задать различный размер, цвет и стиль форматирования текста для элементов text3 и text4. Полный код файла компоновки:

Файл компоновки main.xml
<?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:id="@+id/text1"  
        android:layout_width="wrap_content"  
        android:layout_height="wrap_content"   
        android:text="Text from res/layout/main.xml"/> 
    <TextView  
        android:id="@+id/text2"  
        android:layout_width="wrap_content"  
        android:layout_height="wrap_content"   
        android:text="@string/text_hello" 
        android:textStyle="bold"/> 
    <TextView  
        android:id="@+id/text3"  
        android:layout_width="wrap_content"  
        android:layout_height="wrap_content"  
        android:textSize="24sp"  
        android:textStyle="bold"  
        android:textColor="#ABABAB"/> 
    <TextView  
        android:id="@+id/text4"  
        android:layout_width="wrap_content"  
        android:layout_height="wrap_content"  
        android:textSize="36sp"  
        android:textStyle="italic"/> 
         
</LinearLayout> 
В файле ресурсов strings.xml добавьте после ресурса app_name новый строковый ресурс "Hello, Android!" (листинг 2).

Файл ресурсов strings.xml
<?xml version="1.0" encoding="utf-8"?> 
<resources> 
    <string name="app_name">TextView Sample</string> 
    <string name="text_hello">Text from res/values/string.xml</string> 
    <string name="action_settings">Settings</string> 
</resources>
В классе MainActivity инициализируйте TextView-объекты text3, text4 и методом setText() задайте для них текст. Полный код класса окна приложения:

Файл класса окна приложения MainActivity.java
package com.example.textview; 
 
import android.app.Activity; 
import android.os.Bundle; 
import android.widget.TextView; 
 
public class MainActivity extends Activity { 
     
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 
        setContentView(R.layout.main); 
         
        final TextView text3 = (TextView)findViewById(R.id.text3); 
        text3.setText("Text from Activity"); 
         
        final TextView text4 = (TextView)findViewById(R.id.text4); 
        text4.setText(R.string.text_hello); 
    } 
}

Результат должен получиться такой, как на рисунке. Для первого поля текст задается прямо в файле компоновки, для второго — в файле компоновки из строковых ресурсов strings.xml, для третьего — в коде, для четвертого поля — читается в java-коде из файла ресурсов.

Приложение с элементами TextView

В следующем уроке мы рассмотрим работу с элементом ImageView.


понедельник, 26 января 2015 г.

Компоновка RelativeLayout

Компоновка RelativeLayout  позволяет дочерним объектам определять свою позицию относительно родительского объекта или относительно соседних дочерних элементов (по идентификатору элемента).
В RelativeLayout дочерние элементы расположены так, что если первый элемент расположен по центру экрана, другие элементы, выровненные относительно первого элемента, будут выровнены относительно центра экрана. При таком расположении, при объявлении компоновки в XML-файле, элемент, на который будут ссылаться для позиционирования другие объекты, должен быть объявлен раньше, чем другие элементы, которые обращаются к нему по его идентификатору.
Если в программном коде мы не работаем с некоторыми элементами пользовательского интерфейса, создавать идентификаторы для них необязательно, однако определение идентификаторов для объектов важно при создании RelativeLayout. В компоновке RelativeLayout расположение элемента может определяться относительно другого элемента, на который ссылаются через его уникальный идентификатор:
android:layout_toLeftOf="@id/TextView1"
Давайте теперь создадим пример окна с корневой компоновкой RelativeLayout,
в котором будут семь элементов Button. В файле компоновки activity_main.xml напишите следующий код:
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_height="fill_parent" 
    android:layout_width="fill_parent"> 
 
    <Button 
        android:id="@+id/button_center" 
        android:text="Center" 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:layout_centerVertical="true" 
        android:layout_centerInParent="true"/> 
    <Button 
        android:id="@+id/button_bottom" 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:text="Bottom" 
        android:layout_centerHorizontal="true" 
        android:layout_alignParentBottom="true"/> 
    <Button 
        android:id="@+id/button_top" 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:text="Top" 
        android:layout_alignParentTop="true" 
        android:layout_centerHorizontal="true"/> 
    <Button 
        android:id="@+id/button_left" 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:text="Left" 
        android:layout_alignParentLeft="true" 
        android:layout_centerVertical="true"/> 
    <Button 
        android:id="@+id/button_right" 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:text="Right" 
        android:layout_alignParentRight="true" 
        android:layout_centerVertical="true"/> 
    <Button 
        android:id="@+id/button_rel_right" 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:layout_toLeftOf="@id/button_right" 
        android:layout_alignTop="@id/button_right" 
        android:text="RelRight"/> 
    <Button 
        android:id="@+id/button_rel_left" 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:layout_toRightOf="@id/button_left" 
        android:layout_alignTop="@id/button_left" 
        android:text="RelLeft"/> 
 
</RelativeLayout>
Кстати, обратите внимание, что атрибуты, которые обращаются к идентификаторам относительных элементов (например, layout_toLeftOf), используют синтаксис относительного ресурса @id/id. Внешний вид экрана с компоновкой RelativeLayout должен получиться таким:

Тип компоновки RelativeLayout применяется не так часто, как, например, LinearLayout, несмотря на то, что мастер создания проекта ее использует ее в качестве компоновки по умолчанию . Тем более что такое задание расположения элементов зависит от разрешения и ориентации экрана мобильного устройства. Если вы будете использовать RelativeLayout в собственных приложениях, всегда проверяйте внешний вид окна для различных разрешений и ориентации экрана, поскольку возможно наложение элементов друг на друга. В нашем случае, например, в вертикальной ориентации экрана кнопки Center и RelRight немного накладываются друг на друга:




Компоновка GridLayout

Компоновка GridLayout (сетка) — это относительно новая компоновка, появилась в версии 4.0 (API Level 14). Она похожа на TableLayout, но позволяет более гибко работать с  размерами ячеек и их расположением. В отличие от TableLayout, она не фиксирует дочерние элементы в TableRow, а использует атрибуты android:columnCount и android:rowCount для задания количества дочерних элементов соответственно в столбце или в строке сетки. Кроме того, в GridLayout можно объединять ячейки по горизонтали, используя атрибут android:layout_columnSpan, задавая им количество ячеек, которые должны быть объединены.
Для примера используем уже созданный набор кнопок из предыдущего урока, только поместим их в GridLayout и уберем элементы TableRow. Для кнопки "0" зададим атрибут android:layout_columnSpan="3", а для кнопки "*" — android:layout_columnSpan="2".
activity_main.xml
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:layout_gravity="center" 
    android:columnCount="3" > 
    <Button 
        android:id="@+id/Button01" 
        android:layout_height="wrap_content" 
        android:layout_width="50dp" 
        android:text="1"/> 
    <Button 
        android:id="@+id/Button02" 
        android:layout_height="wrap_content" 
        android:layout_width="50dp" 
        android:text="2"/> 
    <Button 
        android:id="@+id/Button03" 
        android:layout_height="wrap_content" 
        android:layout_width="50dp" 
        android:text="3"/> 
    <Button 
        android:id="@+id/Button04" 
        android:layout_height="wrap_content" 
        android:layout_width="50dp" 
        android:text="4"/> 
    <Button 
        android:id="@+id/Button05" 
        android:layout_height="wrap_content" 
        android:layout_width="50dp" 
        android:text="5"/> 
    <Button 
        android:id="@+id/Button06" 
        android:layout_height="wrap_content" 
        android:layout_width="50dp" 
        android:text="6"/> 
    <Button 
        android:id="@+id/Button07" 
        android:layout_height="wrap_content" 
        android:layout_width="50dp" 
        android:text="7"/> 
    <Button 
        android:id="@+id/Button08" 
        android:layout_height="wrap_content" 
        android:layout_width="50dp" 
        android:text="8"/> 
    <Button 
        android:id="@+id/Button09" 
        android:layout_height="wrap_content" 
        android:layout_width="50dp" 
        android:text="9"/> 
    <Button 
        android:id="@+id/Button11" 
        android:layout_height="wrap_content" 
        android:layout_width="150dp" 
        android:layout_columnSpan="3" 
        android:text="0"/> 
    <Button 
        android:id="@+id/Button10" 
        android:layout_height="wrap_content" 
        android:layout_width="50dp" 
        android:layout_columnSpan="2" 
        android:text="*"/> 
    <Button 
        android:id="@+id/Button12" 
        android:layout_height="wrap_content" 
        android:layout_width="50dp" 
        android:text="#"/> 
</GridLayout>
Внешний вид компоновки на смартфоне:


Обратите внимание, что объединение ячеек автоматически не растягивает элемент, находящийся в них, как в случае с кнопкой "*". Размеры элемента в ячейке надо задавать отдельно. Для кнопки "0", которая растянута на 3 ячейки, кроме атрибута android:
layout_columnSpan мы изменили ширину кнопки
.

Компоновка TableLayout

Компоновка TableLayout позиционирует свои дочерние элементы в строки и столбцы. TableLayout не отображает линии обрамления для их строк, столбцов или ячеек. Кроме того, TableLayout может иметь строки с разным количеством ячеек. При формировании компоновки таблицы некоторые ячейки при необходимости можно оставлять пустыми.
При создании компоновки для строк используются объекты TableRow, которые являются дочерними классами TableLayout (каждый TableRow определяет единственную строку
в таблице). Строка может совсем не иметь ячеек или иметь одну и более ячеек, которые
являются контейнерами для других объектов View или ViewGroup. Ячейка может также быть объектом ViewGroup (например, допускается вложить другой TableLayout или LinearLayout как ячейку).
Для примера с использованием компоновки TableLayout можно создать окно, похожее на наборную панель телефона с 12 кнопками. В окне Layout Editor создайте TableLayout c четырьмя дочерними TableRow и двенадцатью кнопками, по три кнопки в каждой строке.
Для каждого элемента TableRow на вкладке Properties задайте свойства:

  • Layout height — wrap_content;
  • Layout width — wrap_content;
  • Gravity — center.

Свойство gravity задает выравнивание дочерних элементов в контейнере, в данном случае — по центру.
Для каждой кнопки на вкладке Properties задайте свойства:

  • Layout height — wrap_content;
  • Layout width — 70dp. Это фиксированная ширина элемента в dp (density-independent pixels) — независимые от плотности экрана пиксели. Подробнее о них поговорим в следующих уроках.

Надписи на кнопках сделайте так, как на телефонной клавиатуре (1, 2, 3, 4, 5, 6, 7, 8, 9, *, 0, #).
Файл компоновки должен получиться таким:
activity_main.xml
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/TableLayout01" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:gravity="center"> 
    <TableRow 
        android:id="@+id/TableRow01" 
        android:layout_height="wrap_content" 
        android:layout_width="wrap_content" 
        android:gravity="center"> 
        <Button 
            android:id="@+id/Button01" 
            android:layout_height="wrap_content" 
            android:text="1" 
            android:layout_width="70dp"/> 
        <Button 
            android:id="@+id/Button02" 
            android:layout_height="wrap_content" 
            android:text="2" 
            android:layout_width="70dp"/> 
        <Button 
            android:id="@+id/Button03" 
            android:layout_height="wrap_content" 
            android:text="3" 
            android:layout_width="70dp"/> 
    </TableRow> 
    <TableRow 
        android:id="@+id/TableRow02" 
        android:layout_height="wrap_content" 
        android:layout_width="wrap_content" 
        android:gravity="center"> 
        <Button 
            android:id="@+id/Button04" 
            android:layout_height="wrap_content" 
            android:layout_width="70dp" 
            android:text="4"/> 
        <Button 
            android:id="@+id/Button05" 
            android:layout_height="wrap_content" 
            android:layout_width="70dp" 
            android:text="5"/> 
        <Button 
            android:id="@+id/Button06" 
            android:layout_height="wrap_content" 
            android:layout_width="70dp" 
            android:text="6"/> 
    </TableRow> 
    <TableRow 
        android:id="@+id/TableRow03" 
        android:layout_height="wrap_content" 
        android:layout_width="wrap_content" 
        android:gravity="center"> 
        <Button 
            android:id="@+id/Button07" 
            android:layout_height="wrap_content" 
            android:layout_width="70dp" 
            android:text="7"/> 
        <Button 
            android:id="@+id/Button08" 
            android:layout_height="wrap_content" 
            android:layout_width="70dp" 
            android:text="8"/> 
        <Button 
            android:id="@+id/Button09" 
            android:layout_height="wrap_content" 
            android:layout_width="70dp" 
            android:text="9"/> 
    </TableRow> 
    <TableRow 
        android:id="@+id/TableRow04" 
        android:layout_height="wrap_content" 
        android:layout_width="wrap_content" 
        android:gravity="center"> 
        <Button 
            android:id="@+id/Button10" 
            android:layout_height="wrap_content" 
            android:layout_width="70dp" 
            android:text="*"/> 
        <Button 
            android:id="@+id/Button11" 
            android:layout_height="wrap_content" 
            android:layout_width="70dp" 
            android:text="0"/> 
        <Button 
            android:id="@+id/Button12" 
            android:layout_height="wrap_content" 
            android:layout_width="70dp" 
            android:text="#"/> 
    </TableRow> 
</TableLayout>
В результате внешний вид экрана должен получиться в виде телефонной клавиатуры:

Компоновка TableLayout на практике применяется довольно редко, обычно вместо нее используют сочетание компоновок LinearLayout или GridLayout, которая будет рассмотрена далее. Компоновку TableLayout удобно использовать, если расположение элементов представлено в виде "таблицы", как в нашем примере. Кроме того, существует компоновка GridLayout, которая внешне аналогична TableLayout, но имеет дополнительные возможности. Ее мы рассмотрим в следующем уроке.

Компоновка FrameLayout

Компоновка FrameLayout является самым простой. Это в основном пустое пространство на экране, которое можно заполнить только единственным дочерним объектом View или ViewGroup. Все дочерние элементы FrameLayout прикрепляются к левому верхнему углу экрана и будут накладываться друг на друга.
Вот пример простейшей компоновки FrameLayout с одним дочерним элементом Button:
activity_main.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_height="wrap_content" 
    android:layout_width="fill_parent"> 
 
    <Button 
        android:text="Button1" 
        android:id="@+id/Button1" 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content"/> 
 
</FrameLayout>

Внешний вид экрана с компоновкой FrameLayout должен получиться таким:

В компоновке FrameLayout нельзя определить различное местоположение для дочернего объекта View. Последующие дочерние объекты View будут просто рисоваться поверх предыдущих, частично или полностью затеняя их, если находящийся сверху объект непрозрачен, поэтому единственный дочерний элемент для FrameLayout обычно растянут до размеров родительского контейнера и имеет атрибуты layout_width="fill_parent" и layout_height="fill_parent".
Добавим в файл activity_main еще один элемент Button:.
activity_main.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent"> 
 
    <Button 
        android:text="Button1" 
        android:id="@+id/Button1" 
        android:layout_width="fill_parent" 
        android:layout_height="fill_parent"/> 
    <Button  
        android:text="Button2" 
        android:id="@+id/Button2" 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content"/> 
     
</FrameLayout>

Вторая кнопка будет прорисована поверх первой и будет затенять ее:

Компоновка FrameLayout применяется довольно редко, т. к. не позволяет создавать сложные окна с множеством элементов. В практических приложениях эту компоновку обычно используют для создания оверлеев. Например, если у вас в окне выводится изображение, занимающее весь экран (это может быть  карта, загруженная с сервиса Google Map, или картинка с видеокамеры), можно сверху на изображении расположить элементы управления (в дочернем контейнере, если их несколько), скажем, кнопки для управления камерой и рамку видоискателя, а также выводить индикацию времени съемки и другую полезную информацию.

Компоновка LinearLayout

Компоновка LinearLayout наиболее простая в использовании и применяется чаще всего. Это компоновка с последовательным линейным расположением дочерних элементов. Несмотря на то, что мастер по умолчанию создает шаблон с относительной компоновкой RelativeLayout, во многих случаях при создании пользовательского интерфейса лучше использовать LinearLayout.

Ориентация дочерних компонентов


Компоновка LinearLayout выравнивает все дочерние объекты View в одном направлении — вертикально или горизонтально, в зависимости от того, как определен атрибут ориентации android:orientation:
android:orientation="horizontal"
или
android:orientation="vertical"
Все дочерние элементы помещаются в стек один за другим, так что вертикальный список объектов View будет иметь только один дочерний элемент в строке независимо от того, насколько широким он является. Горизонтальное расположение списка обеспечивает размещение элементов в одну строку с высотой, равной высоте самого высокого дочернего элемента списка.
Поменяйте код в файле res/layout/activity_main.xml: создайте корневой элемент LinearLayout c тремя дочерними кнопками:
activity_main.xml
<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:id="@+id/button1" 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:text="Button1"/> 
    <Button 
        android:id="@+id/button2" 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:text="Button2"/> 
    <Button 
        android:id="@+id/button3" 
        android:layout_height="wrap_content" 
        android:layout_width="fill_parent" 
        android:text="Button3"/> 
 
</LinearLayout>
Обратите внимание, что у первых двух кнопок атрибуту android:layout_width присвоено значение wrap_content, а у третьей кнопки — fill_parent, т. е. последняя кнопка заполнит оставшееся свободное пространство в компоновке.

В результате получится линейное горизонтальное размещение дочерних элементов. Если изменить в корневом элементе значение атрибута android:layout_height:
android:orientation="vertical" элементы в контейнере расположатся вертикально. Внешний вид экрана для компоновки LinearLayout с горизонтальной и вертикальной ориентациями элементов:


Вес элементов


Компоновка LinearLayout также поддерживает атрибут android:layout_weight, который назначает индивидуальный вес для дочернего элемента. Данный атрибут определяет "важность" объекта View и позволяет этому элементу расширяться, чтобы заполнить любое оставшееся пространство в родительском объекте View. Заданный по умолчанию вес является нулевым.
Например, если есть три текстовых поля, и двум из них объявлен вес со значением 1,
в то время как другому не дается никакого веса (0), третье текстовое поле без веса не будет расширяться и займет область, определяемую размером текста, отображаемого этим полем. Другие два расширятся одинаково, чтобы заполнить остаток пространства, не занятого третьим полем. Если третьему полю присвоить вес 2 (вместо 0), это поле будет объявлено как "более важное", чем два других, так что третье поле получит 50% общего пространства, в то время как первые два получат по 25% общего пространства.
Далее в файле res/layout/main.xml создайте корневой элемент LinearLayout c тремя дочерними элементами Button:
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:orientation="horizontal" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent"> 
 
    <Button 
        android:id="@+id/button1" 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:text="B1" 
        android:layout_weight="0"/> 
    <Button 
        android:id="@+id/button2" 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:text="B2" 
        android:layout_weight="1"/> 
    <Button 
        android:id="@+id/button3" 
        android:layout_height="wrap_content" 
        android:layout_width="wrap_content" 
        android:text="B3" 
        android:layout_weight="2"/> 
</LinearLayout>
Внешний вид экрана и влияние атрибута android:layout_weight будет следующим:

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

Вложенные компоновки


Компоновки могут быть и вложенными. При проектировании окон с многочисленными элементами управления для заданного расположения элементов часто задаются вложенные компоновки, которые являются контейнерами для элементов управления. Например, для корневой компоновки LinearLayout с атрибутом orientation="vertical" мы можем задать простой дочерний элемент Button и еще два контейнера LinearLayout
с атрибутом orientation="horizontal", которые, в свою очередь, содержат дочерние элементы управления. В редакторе внешний вид будет таким:

Код файла main.xml в результате должен получиться таким:
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:orientation="vertical" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent"> 
 
    <Button 
        android:text="Button1" 
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content"/> 
 
    <LinearLayout 
        android:orientation="horizontal" 
        android:layout_height="wrap_content" 
        android:layout_width="match_parent"> 
        <Button 
            android:text="Button2" 
            android:layout_width="wrap_content" 
            android:layout_weight="1" 
            android:layout_height="wrap_content"/> 
        <Button android:text="Button3" 
            android:id="@+id/button3" 
            android:layout_weight="1" 
            android:layout_width="wrap_content" 
            android:layout_height="wrap_content"/> 
    </LinearLayout> 
 
    <LinearLayout 
        android:orientation="horizontal" 
        android:layout_height="wrap_content" 
        android:layout_width="match_parent"> 
        <Button 
            android:text="Button4" 
            android:layout_weight="1" 
            android:layout_width="wrap_content" 
            android:layout_height="wrap_content"/> 
        <Button 
            android:text="Button5" 
            android:layout_weight="1" 
            android:layout_height="wrap_content" 
            android:layout_width="wrap_content"/> 
        <Button 
            android:text="Button6" 
            android:layout_weight="1" 
            android:layout_height="wrap_content" 
            android:layout_width="wrap_content"/> 
    </LinearLayout> 
</LinearLayout>
Внешний вид экрана с вложенными компоновками будет следующим:

Такое применение вложенных компоновок позволяет строить гибкие и легко перенастраиваемые окна и является самым распространенным способом при создании пользовательского интерфейса для Android-приложений.


воскресенье, 25 января 2015 г.

Компоновка элементов в Activity

Компоновка — это архитектура расположения элементов интерфейса пользователя для конкретного окна, представляющего Activity. Компоновка определяет структуру расположения элементов в окне и содержит все элементы, которые отображаются пользователю программы.
Это довольно важная тема в разработке мобильных приложений, поскольку проектирование пользовательского интерфейса для мобильных телефонов и планшетов сложнее, чем для настольных систем или для веб-страниц. Экраны мобильных телефонов имеют гораздо меньшие размеры, чем обычные мониторы. Кроме того, существует много разновидностей дисплеев для мобильных телефонов, отличающихся размерами, разрешением и плотностью пикселов.
Необходимо также учесть, что большинство экранов для мобильных телефонов сенсорные, причем они могут быть разного типа. Например, емкостный экран реагирует на касание пальцем, а для взаимодействия с резистивным экраном используется стилус. Поэтому важно правильно задавать компоновку и размеры элементов управления, чтобы пользователю было удобно управлять вашим приложением независимо от типа экрана.

Формирование графического интерфейса пользователя

В Android-приложении графический интерфейс пользователя формируется с использованием объектов View и ViewGroup.
Объекты View — это основные модули для создания графического интерфейса пользователя на платформе Android. Класс View служит базовым для классов элементов управления, называемых виджетами, — текстовых полей, кнопок и т. д. Объект View является структурой, свойства которой сохраняют параметры компоновки и содержание для определенной прямоугольной области экрана. В графическом интерфейсе пользователя объект View является точкой взаимодействия пользователя и программы.
Класс ViewGroup представляет собой контейнер, который служит ядром для подклассов, называемых компоновками (layouts). Эти классы формируют расположение элементов пользовательского интерфейса на форме и содержат дочерние элементы View или ViewGroup.
При разработке пользовательского интерфейса для Android необходимо определить компоновку для каждого Activity в виде дерева, используя иерархии узлов View и ViewGroup.

Прорисовка графического интерфейса на экране

При запуске программы система Android получает ссылку на корневой узел дерева компоновки и использует ее для прорисовки графического интерфейса на экране мобильного устройства. Система также анализирует элементы дерева от вершины дерева иерархии, прорисовывая дочерние объекты View и ViewGroup и добавляя их родительским элементам. Для этого в методе onCreate() необходимо вызвать метод setContentView(), передав ему в качестве параметра ссылку на ресурс компоновки в следующем виде:
R.layout.layout_file_name
Например, если компоновка находится в файле activity_main.xml, ее загрузка в методе onCreate() происходит так:
@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main);
}
Прорисовка элементов дерева компоновки всегда начинается с корневого узла. Затем последовательно прорисовываются дочерние объекты дерева компоновки. Это означает, что родители будут прорисовываться раньше, чем их дочерние объекты, т. е. по окончании процесса прорисовки элементов на экране родители будут находиться на заднем плане по отношению к дочерним узлам.

Layout Editor

Android Studio для разработки интерфейса предлагает визуальный редактор компоновки Layout Editor, применяемый для создания и предварительного просмотра создаваемых файлов компоновки, которые находятся в каталоге res/layout/ проекта:

Например, можно создавать XML-компоновки для различных ориентаций экрана мобильного устройства (portrait, landscape), размеров экрана, версии SDK и языков интерфейса.
В разделе Outline отображается компоновка в виде дерева. Объекты View — листья дерева, объекты ViewGroup — ветви. В разделе Properties можно задавать свойства для элементов интерфейса.

Создание компоновки

Компоновку можно создавать двумя способами:

  • объявить элементы пользовательского интерфейса в XML-файле. Android обеспечивает прямой XML-словарь, который соответствует классам View и ViewGroup;
  • создать компоновку для окна в коде программы во время выполнения — инициализировать объекты Layout и дочерние объекты ViewViewGroup и управлять их свойствами программно.

При разработке пользовательского интерфейса можно применять каждый из этих методов в отдельности или оба сразу для объявления и управления пользовательским интерфейсом в приложении. Например, можно объявить заданную по умолчанию компоновку окна вашего приложения в XML-файле, включая экранные элементы, которые появятся в них, и их свойства, а затем добавить код в приложение, который во время выполнения изменит состояние объектов на экране, включая объявленные в XML-файле.
Обычно, если интерфейс статический, используется XML-файлы. Преимущество объявления пользовательского интерфейса в XML-файле состоит в том, что это дает возможность отделить дизайн приложения от программного кода, который управляет поведением приложения. Ваше описание пользовательского интерфейса является внешним по отношению к программному коду. Это означает, что вы можете изменять пользовательский интерфейс в файле компоновки без необходимости изменения вашего программного кода.
Используя XML-компоновку, можно быстро проектировать пользовательский интерфейс тем же самым способом, которым вы создаете веб-страницы в HTML, — с рядом вложенных элементов.
Каждый файл компоновки должен содержать только один корневой элемент, который должен быть объектом View или ViewGroup. К корневому элементу, вы можете добавить дополнительные объекты компоновки как дочерние элементы.
Например, вот этот XML-файл компоновки приложения нашего тестового приложения:
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:paddingLeft="@dimen/activity_horizontal_margin" 
    android:paddingRight="@dimen/activity_horizontal_margin" 
    android:paddingTop="@dimen/activity_vertical_margin" 
    android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity"> 
 
    <TextView 
        android:text="@string/hello_world" 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" /> 
 
</RelativeLayout> 

В этой XML-компоновке есть корневой элемент <RelativeLayout> и только один дочерний элемент TextView (текстовое поле), которые имеют следующие атрибуты:

  • xmlns:android — объявление пространства имен XML, которое сообщает среде Android, что вы ссылаетесь на общие атрибуты, определенные в пространстве имен Android. В каждом файле компоновки у корневого элемента должен быть этот атрибут со значением "http://schemas.android.com/apk/res/android";
  • android:layout_width — атрибут определяет, сколько из доступной ширины экрана должен использовать этот объект View (или ViewGroup). В нашем случае он — единственный объект, таким образом, можно растянуть его на весь экран, которому в данном случае соответствует значение fill_parent;
  • android:layout_height — аналогичен атрибуту android:layout_width за исключением того, что он ссылается на доступную высоту экрана.
  • группа 
  • android:padding... — задают отступы вложенных элементов от границ контейнера.
Элементы управления в Android могут иметь множество различных атрибутов, которые определяют внешний вид и поведение данного элемента и различаются в зависимости от типа элемента. Мы их будем постепенно изучать при рассмотрении элементов управления в следующих статьях.

Типы компоновок

Для создания окон существует несколько стандартных типов компоновок, которые вы можете использовать в разрабатываемых приложениях:

  • FrameLayout;
  • LinearLayout;
  • TableLayout;
  • GridLayout;
  • RelativeLayout.

Каждый из этих типов компоновки предлагает уникальный набор параметров, которые используются, чтобы определить позиции дочерних элементов и структуру компоновки на экране. В зависимости от требований, предъявляемых к пользовательскому интерфейсу, выбирается наиболее подходящий тип компоновки. В следующих уроках мы рассмотрим все варианты компоновок и их использование:

Компоновка LinearLayout
Компоновка FrameLayout
Компоновка TableLayout
Компоновка GridLayout
Компоновка RelativeLayout