Исходные коды программ и игр

Программирование - работа и хобби

TableLayout в приложении Android

Язык программирования C#

Исходник приложения для Android

Приложение книга для Android Исходник выполнен в виде полноценного приложения для операционной системы Android, в виде книги для чтения. Компоновка элементов построена на контейнере TableLayout. Комбинирование различных типов дочерних объектов внутри TableLayout обеспечило возможность объединения ячеек как по строкам, так и по столбцам. В качестве текстов, загружаемых на экран выбраны басни Ивана Андреевича Крылова. Весьма интересные и поучительные истории. При прикосновении (ассоциация с кликом кнопки мыши OnClick) к радиокнопке с названием басни, в визуальный элемент TextView загружается соответствующий текст. При кликах на радиокнопках настроек можно изменять цвет фона и размер шрифта. Долгое прикосновение к столбцу с текстом скрывает или показывает столбец настроек.

Макет TableLayout

Интерфейс приложения построен на макете Android TableLayout. Данный макет удобен для создания интерфейса приложения на основе строгих ячеек, образуемых строками TableRow. Столбцы макета существуют только в пределах строки и не могут быть объединены по вертикали с ячейками других строк. TableLayout напоминает отдаленно таблицу html с тегом table. Но веб таблица допускает объединение ячеек по строкам и по столбцам. Tablelayout же допускает объединение ячеек только внутри строки. Строки объединять, возможно пока, нельзя. Но есть и достоинство этих свойств макета TableLayout: внутри строки ячейки могут быть любой желаемой ширины. Кроме того, для обхода невозможности объединения строк возможно применение в качестве ячеек таблицы сам же макет Tablelayout и другие контейнеры.

Элементы TableLayout

Интерфейс на макете TableLayout AndroidДля определения строки в макете TableLayout стандартно предназначены объекты TableRow. В TableRow можно добавлять любые визуальные и контейнерные элементы. Пространство между дочерними элементами распределяется абсолютными и относительными величинами. Абсолютными непосредственно указывается ширина и высота, относительные распределяют пространство на основе весов layout_weight. Комбинируя эти параметры, достигается желаемая компоновка строк и ячеек. В TableLayout, минуя вставку TableRow, в качестве строк можно добавлять любой вид и контейнер, например: TextView, RadioGroup и даже сам контейнер TableLayout. Но только TableRow формируют ячейки внутри строки. Любые другие виды элементов создают ячейку на всю ширину материнского контейнера. Добавляя последующие виды, все они будут занимать всю доступную ширину.

Компоновка элементов исходника

Компоновка элементов исходника Первая строка TableLayout в XML интерфейсе исходника приложения это TextView в качестве заголовка. Ниже добавлен объект TableRow дающий возможность сформировать две ячейки. Для обеспечения гарантированного просмотра всего содержания экрана приложения этими ячейками являются элементы прокрутки ScrollView. Правый столбец сложной компоновки и содержит множество визуальных элементов. Так как в ScrollView можно добавить только один дочерний элемент, то второй столбец построен на контейнере TableLayout. И в данном контейнере уже размещается необходимое количество элементов управления, состоящее из TextView и множества RadioButtons управления.

Листинг XML файла дизайна приложения

<TableLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:p4="http://xamarin.com/mono/android/designer"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#ffffff"
    android:id="@+id/tableLayoutMain">
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Заголовок"
        android:textAlignment="center"
        android:textSize="22dp"
        android:id="@+id/textViewHeader" />
    <TableRow
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:id="@+id/tableRowContent">
        <ScrollView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:fillViewport="true"
            android:id="@+id/scrollViewBody" >
            <TextView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:text="Body"
                android:padding="10dp"
                android:textSize="14dp"
                android:id="@+id/textViewBody" />
        </ScrollView>
        <ScrollView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:paddingRight="10dp">
        <TableLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:id="@+id/tableLayout3">
            <RadioGroup
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:id="@+id/radioGroupSelect">
                <RadioButton
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:checked="true"
                    android:text="RadioButton"
                    android:id="@+id/radioButton1" />
                <RadioButton
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="RadioButton"
                    android:id="@+id/radioButton2" />
                <RadioButton
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="RadioButton"
                    android:id="@+id/radioButton3" />
            </RadioGroup>
            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="20dp"
                android:text="Настройки"
                android:textAppearance="?android:attr/textAppearanceMedium"
                android:id="@+id/textViewHeadSetting" />
            <RadioGroup
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:id="@+id/radioGroupBGColor">
                <RadioButton
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:checked="true"
                    android:text="День"
                    android:id="@+id/radioButtonDay" />
                <RadioButton
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="Ночь"
                    android:id="@+id/radioButtonNight" />
            </RadioGroup>
            <RadioGroup
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:layout_marginTop="20dp"
                    android:id="@+id/radioGroupScaleFont">
                <RadioButton
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="Шрифт +"
                    android:id="@+id/radioButtonFontLarge" />
                <RadioButton
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="Шрифт -"
                    android:id="@+id/radioButtonFontNormal" />
            </RadioGroup>
        </TableLayout>
        </ScrollView>
    </TableRow>
</TableLayout>

Создание дизайна приложения

Приложение исходника имеет один вид экрана, одно Activity (окно с интерфейсом для пользователя). Класс Activity определяет события связанные с жизненным циклом приложения и интерактивностью интерфейса. Внешний вид приложения создается частично в дизайнере XML и частично программным способом. Дизайнер XML удобен тем, что позволяет визуально сформировать компоновку приложения. Без программного способа не обойтись, когда компоновка приложения формируется динамически на основе информации, полученной из базы данных. Комбинирование дизайнерского и программного способа позволяет создавать динамичные интерфейсы приложений для операционной системы Android.

Листинг программной инициализации

private void Init()
{
    // Получение текстовой информации из базы данных.
    Stream xmlDB = Assets.Open("stories.xml", Android.Content.Res.Access.Streaming);

    // Для облегчения обработки базу данных загружаем в структурированный XML документ.
    XmlDocument xmlDocument = new XmlDocument();
    xmlDocument.Load(xmlDB);
    xmlDB.Close();

    // Получаем все названия рассказов.
    XmlNodeList xmlNodeList = xmlDocument.DocumentElement.SelectNodes("story/name");

    // В дизайнере кнопки этой радиогруппы только 
    // для визуального построения макета приложения.
    // Очистим радиогруппу для размещения рабочих RadioButtons.
    RadioGroup radioGroup = this.FindViewById(Resource.Id.radioGroupSelect);
    radioGroup.RemoveAllViews();

     // Создаем новые радиокнопки с названиями аналогично 
     // названиям элементов в файле XML.
     // Подключаем событие прикосновения к каждой кнопке.
     foreach (XmlNode item in xmlNodeList)
     {
         RadioButton rb = new RadioButton(this);
         rb.Click += RadioGroupSelect_Click;
         rb.Text = item.InnerText;
         radioGroup.AddView(rb);
    }

    // Подключаем события для RadioButtons 
    // цветовых настроек фона и шрифта книги.
    RadioGroup radioGroupBGColor = this.FindViewById(Resource.Id.radioGroupBGColor);
    for (int i = 0; i < radioGroupBGColor.ChildCount; i++)
    {
        RadioButton rb = (RadioButton)radioGroupBGColor.GetChildAt(i);
        rb.Click += RadioButtonsSetting_Click;
    }

    // Подключаем события к группе радиокнопок изменения размера шрифта книги.
    // У всех радиокнопок настроек события обрабатывает один и тот же метод.
    RadioGroup radioGroupScaleFont = this.FindViewById(Resource.Id.radioGroupScaleFont);
    for (int i = 0; i < radioGroupScaleFont.ChildCount; i++)
    {
        RadioButton rb = (RadioButton)radioGroupScaleFont.GetChildAt(i);
        rb.Click += RadioButtonsSetting_Click;
    }

    // Подключаем к текстовому полю событие долгого прикосновения.
    // При этом будет скрывается боковой столбец настроек.
    var textView = this.FindViewById(Resource.Id.textViewBody);
    textView.LongClick += TextView_LongClick;
}

База данных приложения

В качестве базы данных выступает файл XML, славящийся своей структурированностью и удобной возможностью прямого редактирования. Файл состоит из элементов Story которые в свою очередь имеют элементы названия и текста рассказа, соответственно Name и Body. Программный код считывает все элементы Story/Name и автоматически создает объекты RadioButtons с соответствующим названием. Это название рассказа и является ключом вывода текста на экран Android устройства. Файл stories.xml находится в каталоге Assets. Папка Assets специально предназначена для дополнительных ресурсов приложения и эти ресурсы доступны через сервис Android AssetManager.

Программный код загрузки текста по названию

private void RadioGroupSelect_Click(object sender, System.EventArgs e)
{
    RadioButton rb = (RadioButton)sender;

    // Заголовок и тело текстового поля.
    TextView textViewHeader = this.FindViewById(Resource.Id.textViewHeader);
    TextView textViewBody = this.FindViewById(Resource.Id.textViewBody);

    // Получаем ресурс текстовой информации книги.
    Stream xmlDB = Assets.Open("stories.xml", Android.Content.Res.Access.Streaming);

    // Для удобства работы текстовый ресурс загружаем в XML документ.
    XmlDocument xmlDocument = new XmlDocument();
    xmlDocument.Load(xmlDB);
    xmlDB.Close();

    // По тексту нажатой радиокнопки загружаем соответствующий рассказ
    // и название присваиваем заголовку приложения.
    XmlNodeList xmlNodeList = xmlDocument.DocumentElement.SelectNodes("story");
    foreach (XmlNode item in xmlNodeList)
    {
        if (rb.Text == item.SelectSingleNode("name").InnerText)
        {
            textViewBody.Text = item.SelectSingleNode("body").InnerText;
            textViewHeader.Text = item.SelectSingleNode("name").InnerText;
        }
    }
}

Платформа исходника

Исходник написан на базе каркаса Xamarin.Android для .NET. Xamarin.Android расширяет платформу .NET добавляя возможность создавать приложения для Andriod на языке C#, F# и предоставляет полный доступ к нативному(родному) Android SDK. Среда программирования MS Visual Studio 2019. Целевая платформа API 26 (Android 8.0). Приложение тестировалось на смартфонах и планшетах с Android 9.0 и Android 8.0 версии.

Этапы создания исходника приложения:
  1. Выбор шаблона «Приложение для Android(Xamarin)». Шаблоны проектов приложений для Android на телефонах и планшетах на платформе Xamarin.
  2. Выбор версии Android.
  3. Выбор шаблона «Пустое приложение».
  4. Создание дизайна и компоновки приложения.
  5. Написание программного кода функциональности приложения.
  6. Тестирование на Android устройствах.

В состав скачиваемого файла входят исходные коды приложения.

Файл загрузки Размер Кол-во загрузок
AndroidTableLayout.zip 💾 1352Кбайт 68