Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Программирование мобильных устройств. Ч.1. Учебно-методическое пособие

.pdf
Скачиваний:
0
Добавлен:
09.08.2026
Размер:
462 Кб
Скачать

результатTextView.text = результат.toString()

Предусмотрите обработку возможных ошибок, таких как деление на ноль или неверный ввод от пользователя.

Проверьте работоспособность приложения, вводя различные значения и выполняя различные операции

3.1.Дополнительные теоретические сведения

Впроцессе выполнения лабораторной работы будут полезные

некоторые теоретические сведения, представленные ниже.

3.1.1. ProgressBar – Индикатор прогресса. Элемент управления

ProgressBar (Индикатор прогресса) показывает пользователю выполнение программой некоторой продолжительной работы. Помогает понять, что программа не зависла. Этот элемент находится в папке Form Widgets.

Типы ProgressBar (Android предлагает несколько видов индикаторов):

A)ProgressBar (Large)

B)ProgressBar (Normal)

C)ProgressBar (Small)

D)ProgressBar (Horizontal)

Стандартным является второй индикатор (Normal). Остальные являются модификациями, и их отличия определены в стилях с использованием XMLописания виджетов.

Методы для работы с ProgressBar:

1)setProgress(value: Int) устанавливает заданное значение индикатора прогресса;

2)getProgress(): Int возвращает текущее значение индикатора прогресса;

3)incrementProgressBy(increment: Int)` устанавливает величину дискретизации приращения значения индикатора;

4)setMax(max: Int)` устанавливает максимальное значение величины прогресса.

Примеры использования:

- Круговые индикаторы Normal и Large могут быть размещены на экране без дополнительного кода и будут бесконечно выводить анимацию вращения.

- Горизонтальный индикатор обычно используется для демонстрации индикатора в действии. При длительной операции пользователь видит, как полоска индикатора постоянно увеличивается.

3.1.2. Единицы Измерения. Исторически разработчики использовали пиксели (px) при создании компьютерных интерфейсов. Однако с развитием технологий и появлением высоких разрешений, этот подход стал проблематичным. Android поддерживает несколько стандартных единиц измерения:

- px (pixels): Пиксели, минимальные единицы измерения;

11

-dp (density-independent pixels): Независимые от плотности пиксели, абстрактная единица, основанная на физической плотности экрана с разрешением 160 dpi;

-sp (scale-independent pixels): Независимые от масштабирования пиксели, используемые для размеров шрифтов, позволяющие настройку размеров пользователем;

-in (inches): Дюймы, базируются на физических размерах экрана;

-mm (millimeters): Миллиметры, также базируются на физических размерах экрана;

-pt (points): 1/72 дюйма, также базируются на физических размерах экрана.

3.1.3. Настройка Шрифтов. Android предоставляет возможность настройки размеров шрифтов в четырех вариантах: Мелкий, Обычный, Крупный, Огромный, которые можно установить в настройках устройства. Для установки размера шрифта в XML файле используйте атрибут `android:textSize` с указанием размера в `sp` или `dp`.

Пример использования `sp`:

<TextView

android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Текст с размером 26sp" android:textSize="26sp" />

Использование системных размеров шрифтов:

<TextView

android:id="@+id/textView3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Пример текста. textAppearanceSmall"

android:textAppearance="?android:attr/textAppearanceSmall" />

3.1.4. TextView в Android: Отображение Текста и Настройки. Виджет

TextView предназначен для отображения текста без возможности редактирования, часто используется для представления описательного текста. Находится в папке Form Widgets под четырьмя вариантами: TextView, Large Text,

Medium Text, Small Text.

Для отображения текста в TextView в XML файле используйте атрибут `android:text`. Рекомендуется использовать текстовые ресурсы:

android:text="@string/hello"

Текст можно устанавливать программно с использованием метода

`setText()`:

12

TextView text = findViewById(R.id.text1); text.setText("Hello, Android!");

3.1.5. Обработка Событий Нажатия на Кнопку в Android. Если у вас есть кнопка на экране, нажатие на которую должно вызвать определенное действие, существует несколько способов обработки этого события:

1. Атрибут `onClick`

Пример использования в XML-разметке:

android:onClick="onMyButtonClick"

Пример реализации в коде:

public void onMyButtonClick(View view) { // Ваш код обработки нажатия

Toast.makeText(this, "Зачем вы нажали?", Toast.LENGTH_SHORT).show();

}

При использовании этого метода не нужно явно объявлять кнопку в коде, Android автоматически обработает нажатие.

2. Анонимный обработчик Этот способ позволяет более явно контролировать обработку событий и

применим для различных видов элементов.

Button myButton = findViewById(R.id.button1); myButton.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View view) { // Ваш код обработки нажатия

Toast.makeText(MainActivity.this, "Еще один способ!", Toast.LENGTH_SHORT).show();

}

});

3. Имплементация `View.OnClickListener`

Наиболее удачный вариант, если ваша activity обрабатывает события для нескольких элементов.

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

@Override

protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main);

Button myButton = findViewById(R.id.button1);

13

myButton.setOnClickListener(this);

}

@Override

public void onClick(View view) { // Ваш код обработки нажатия

Toast.makeText(this, "Еще один способ!", Toast.LENGTH_SHORT).show();

}

}

4. Абстрактные классы и интерфейсы Абстрактный класс представляет собой общий шаблон поведения для

группы классов. Он содержит как абстрактные, так и конкретные методы. Абстрактные классы определяют общие методы и свойства для группы

классов, запрещено создавать экземпляры таких классов.

abstract class Shape {

// Общие методы и свойства

abstract fun calculateArea(): Double // Абстрактный метод

open fun printName() {

// Конкретный метод с реализацией

println("This is a shape.")

 

}

 

}

 

Интерфейс определяет условия для класса, указывая, какие методы должны быть реализованы. Методы интерфейса могут быть как абстрактными, так и иметь реализацию по умолчанию.

interface Drawable {

// Методы и свойства интерфейса

fun draw()

// Абстрактный метод

fun show() {

// Метод с реализацией по умолчанию

println("Showing drawable.")

}

}

Для более глубокого понимания далее приведем небольшой сравнительный анализ интерфейса и абстрактного класса по некоторым параметрам.

Параметры

Интерфейс

Абстрактный класс

Скорость

Медленный

Быстрый

 

Наследование

Реализация нескольких

Только

один

 

интерфейсов

абстрактный класс

 

Структура

Абстрактные методы

Абстрактные

и

 

 

конкретные методы

 

 

14

 

 

Когда использовать

Будущие улучшения

Избежание

 

 

 

 

независимости

 

Реализация

Класс

может

Класс

может

 

реализовать

несколько

наследовать только один

 

интерфейсов

 

абстрактный класс

Методы доступа

Интерфейс

не имеет

Абстрактный

класс

 

модификаторов доступа

может

иметь

 

 

 

модификаторы доступа

15

4. Создание приложения «Вкладки»

Целью занятия является реализация приложения, состоящего из трех вкладок. Интерфейс каждой вкладки задается отдельным xml файлом. Первая вкладка содержит изображение и надпись. Вторая вкладка содержит элемент ListView с произвольным интерфейсом. Третья вкладка содержит программно создаваемый TableLayout.

Создайте новый проект в Android Studio с использованием Kotlin. Откройте макет (layout) для вашей активности с использованием `TabLayout` и `ViewPager`, которые будут использоваться для управления вкладками.

Примечание. "ViewPager" и "TabLayout" используются для создания интерфейса с вкладками в Android. "ViewPager" предоставляет прокрутку между фрагментами, а "TabLayout" – переключение между вкладками. "Fragment" в Android представляют собой модули, которые можно использовать для построения многокомпонентных пользовательских интерфейсов внутри одной активности. "PagerAdapter" это адаптер, который предоставляет фрагменты для `ViewPager`. Он определяет, какой фрагмент должен отображаться на какой позиции.

Создайте отдельные макеты для каждой вкладки, как описано в задании:

1)Первая вкладка с изображением и надписью;

2)Вторая вкладка с `ListView`;

3)Третья вкладка с программно созданным `TableLayout`.

Создайте адаптер для `ViewPager, который будет управлять фрагментами для каждой вкладки.

class PagerAdapter(fm: FragmentManager) : FragmentPagerAdapter(fm) { override fun getItem(position: Int): Fragment {

return when (position) {

0 -> FirstTabFragment()

1 -> SecondTabFragment()

2 -> ThirdTabFragment()

else -> throw IllegalArgumentException("Invalid position")

}

}

override fun getCount(): Int { return 3

}

override fun getPageTitle(position: Int): CharSequence? { return when (position) {

0 -> "Вкладка 1"

1 -> "Вкладка 2"

2 -> "Вкладка 3"

16

else -> null

}

}

}

Для создания `TableLayout` программно вы можете создать экземпляр `TableLayout`, добавить строки (`TableRow`) и ячейки (`TextView` или другие элементы) в соответствующем порядке.

val tableLayout = TableLayout(context) val tableRow = TableRow(context)

val textView = TextView(context) tableRow.addView(textView) tableLayout.addView(tableRow)

Свяжите `ViewPager` с `TabLayout`, чтобы они взаимодействовали и обеспечивали переключение между вкладками.

val viewPager: ViewPager = findViewById(R.id.viewPager) val tabs: TabLayout = findViewById(R.id.tabs) viewPager.adapter = PagerAdapter(supportFragmentManager) tabs.setupWithViewPager(viewPager)

`ListView` используется для отображения списка элементов. Для связывания данных с `ListView` создайте адаптер, например, `ArrayAdapter` или собственный адаптер.

val listView: ListView = findViewById(R.id.listView)

val данные = arrayOf("Элемент 1", "Элемент 2", "Элемент 3")

val адаптер = ArrayAdapter(this, android.R.layout.simple_list_item_1,

данные)

listView.adapter = адаптер

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

class FirstTabFragment : Fragment() {

//Реализация для первой вкладки

}

class SecondTabFragment : Fragment() {

//Реализация для второй вкладки

}

class ThirdTabFragment : Fragment() {

// Реализация для третьей вкладки

}

17

4.1.Дополнительные теоретические сведения

Впроцессе выполнения лабораторной работы будут полезные некоторые теоретические сведения, представленные ниже.

4.1.1.Исключения в Kotlin: краткий обзор с примерами

1) Все исключения в Kotlin являются наследниками класса `Throwable`.

У каждого исключения есть сообщение, трассировка стека и, опционально, причина возникновения. Исключение можно вызвать явным образом с использованием оператора `throw`:

throw Exception("Hi There!")

Для перехвата исключений используется выражение `try...catch`:

try {

//некоторый код

}catch (e: SomeException) {

//обработчик

}finally {

//опциональный блок finally

2)Try в Kotlin является выражением и может иметь возвращаемое значение.

Возвращаемым значением является последнее выражение в блоке `try` или последнее выражение в блоках `catch`. Блок `finally` не влияет на результат `try`- выражения.

val a: Int? = try { input.toInt() } catch (e: NumberFormatException) { null }

3) Проверяемые исключения

В Kotlin нет проверяемых исключений, что избавляет от необходимости обрабатывать их в каждом месте использования. Это сделано для того, чтобы упростить код и избежать его бесполезного оборачивания в блоки `try...catch`.

4)Тип `Nothing`

Выражение `throw` в Kotlin является выражением и имеет тип `Nothing`. Используется для обозначения кода, который не может быть достигнут.

Пример использования `Nothing` в функции, которая всегда вызывает исключение:

fun fail(message: String): Nothing { throw IllegalArgumentException(message)

}

18

4.1.2. Геттеры и сеттеры

Доступ к свойствам класса осуществляется через методы геттера (getter) и сеттера (setter). Они позволяют контролировать доступ к свойствам и выполнить дополнительные действия при чтении или записи значений.

Геттеры – это специальные методы, которые вызываются при чтении значения свойства объекта. Они определяют, какое значение будет возвращено при обращении к свойству.

class Person {

val fullName: String

get() = "$firstName $lastName"

var age: Int = 0 get() {

println("Геттер вызван") return field

}

}

Здесь `fullName` представляет собой свойство, которое состоит из `firstName` и `lastName`, а `age` – просто целочисленное свойство. Обратите внимание, что `field` – это специальное ключевое слово, которое представляет собой текущее значение поля.

Сеттеры – это методы, вызываемые при записи нового значения в свойство объекта. Они позволяют контролировать и проверять новые значения перед их назначением. Ниже мы определяем сеттер для свойства `age`, который проверяет, что новый возраст неотрицательный, и только в этом случае устанавливает его.

class Person { var age: Int = 0

set(value) {

if (value >= 0) { field = value

} else {

println("Недопустимый возраст")

}

}

}

Здесь мы создаем объект `Person` и используем геттер для получения полного имени и сеттер для установки возраста. Обратите внимание, что вызов сеттера и геттера выглядит как обычное обращение к свойству.

fun main() {

val person = Person()

19

println(person.fullName) // Используется геттер person.age = 30 // Используется сеттер println(person.age) // Используется геттер

}

Иногда в сеттере или геттере может потребоваться обратиться к фактическому полю, которое они представляют. В Kotlin для этого используется ключевое слово `field`. В Kotlin можно определить пользовательские геттеры и сеттеры для свойств, позволяя выполнять дополнительные операции при доступе к ним.

class Person { var age: Int = 0

get() {

println("Геттер вызван") return field

}

set(value) { println("Сеттер вызван") field = value

}

}

Таким образом, геттеры и сеттеры обеспечивают гибкость и контроль над доступом к свойствам объектов, что делает их очень мощным инструментом при проектировании классов и работы с данными.

4.1.3. Свойства

Свойства в классах Kotlin могут быть объявлены как изменяемые (mutable) и неизменяемые (read-only) var и val соответственно.

class Address {

var name: String = "Holmes, Sherlock" var street: String = "Baker"

var city: String = "London" var state: String? = null var zip: String = "123456"

}

Строго говоря, полный синтаксис объявления свойства выглядит следующим образом:

var <propertyName>[: <PropertyType>] [= <property_initializer>] [<getter>]

[<setter>]

20

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]