Добавил:
ivanov666
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Разработка мобильных приложений в среде Android Studio. Учебное пособие
.pdf
2.4. Переход между Activity
41
2.4.1.1. Добавления строки в Intent
Добавление строки с использованием Intent выглядит следующим об-
разом:
Intent myIntent = new Intent(ctx, Main2Activity.class);
myIntent.putExtra("myKey", "myValue");
startActivity(myIntent);
Добавление строки с использованием Bundle:
Intent myIntent = new Intent(ctx, Main2Activity.class);
Bundle myBundle = new Bundle();
myBundle.putString("myBundleKey", "myBundleValue");
myIntent.putExtra("myIntentKey", myBundle);
startActivity(myIntent);
После открытия второго Activity переданные данные можно получить
в методе onCreate с использованием метода getIntent(). Данный метод возвращает Intent, если таковой передан в Activity, либо null - если такового
нет. Получить данные из Intent можно по заданному ключу.
Получение данных из Intent:
Intent myIntent = getIntent();
if(myIntent != null){
String myValue = myIntent.getStringExtra("myKey");
}
Или при использовании Bundle:
Intent myIntent = getIntent();
if(myIntent != null){
Bundle myBundleValue = myIntent.getBundleExtra("myIntentKey");
String myValue = myBundleValue.getString("myBundleKey");
}
Далее полученные значения можно использовать по необходимости.

2. Интерфейс мобильного приложения (Activity)
42
2.5. Фрагменты
Fragment – модульная часть activity, у которой свой жизненный цикл
и свои обработчики различных событий. С помощью данного элемента
можно сделать гибкий пользовательский интерфейс, с возможностью адаптации под большие экраны (планшеты). Несомненным плюсом использования фрагментов является их модульность – один и тот же фрагмент с одинаковым функционалом и макетом можно использовать несколько раз в
разных частях приложения. Activity такое сделать не позволит [18].
Фрагменты зависят от Activity, без него фрагмент существовать не
может. Также фрагменты имеют собственный жизненный цикл, перекликающийся и зависящий от жизненного цикла Activity, что необходимо учитывать при обработке многопоточных операций внутри фрагмента.
Для полноценной работы с фрагментом используется три основных
класса:
Fragment – класс фрагмент, который привязывает макет к логике и
от которого будут наследоваться все новые фрагменты.
FragmentManager – класс, который контролирует все взаимодей-
ствие между фрагментами и между фрагментом и Activity;
FragmentTransaction – класс, с помощью которого происходит взаимодействие между фрагментами – удаление, добавление, замена и т. д.
2.5.1. Создание фрагмента
Первый шаг в создании фрагмента – создание макета с помощью любой xml-разметки. Пример xml-разметки фрагмента представлен ниже:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/myTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"

2.5. Фрагменты
43
android:text="TextView" />
</LinearLayout>
Второй шаг – создание класса фрагмента. Фрагмент должен наследоваться от класса Fragment. Единственным обязательным для переопределения методом является onCreateView(). Данный метод является аналогом
метода setContentView() в Activity и возвращает View, созданный в этом
фрагменте. Фрагмент также имеет метод onCreate(), но в нем еще нет доступа к элементам интерфейса, обращение к ним вызовет исключение.
Пример созданного класса фрагмента с его методами представлен
ниже:
public class MyFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup contain-
er,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.my_fragment_layout,
container, false);
TextView myTextView = view.findViewById(R.id.myTextView);
return view;
}
}
Если в методе onCreateView() понадобится добавить обработчик событий на элементы интерфейса, то элемент следует искать не по всей Ac-
tivity, а в отдельном компоненте в привязанном к разметке макету. Метод
findViewById() нужно вызывать к view, как представлено в примере выше,
а не без модификатора, как в Activity. В приведенном выше примере функция inflater.inflate() ищет заданный файл по идентификатору и присваивает
найденный результат переменной view. Следующая строка показывает, как
найти TextView на макете фрагмента.
После того, как фрагмент создан, его нужно разместить на экране.
Для этого существует два способа:

2. Интерфейс мобильного приложения (Activity)
44
установка фрагмента в файл макета. При использовании данного
способа фрагменты теряют многие свои преимущества, например динамическую работу с ними;
создание фрагментов из кода. Данный способ наиболее предпо-
чтителен, так как позволяет совершать действия с фрагментом в любой
удобный момент времени.
Рассмотрим первый способ. Для расположения фрагментов на макете
существует специальный тег “fragment”. Для него обязательными свойствами являются идентификатор, высота, ширина и название класса, к которому принадлежит фрагмент – android:name [19].
<fragment
android:id="@+id/my_fragment"
android:name="com.example.aseatari.myapplication.MyFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
Для отображения такого фрагмента на экране больше никаких действий предпринимать не нужно.
Второй способ намного интереснее. Для того чтобы динамически добавить фрагмент на экран, сначала необходимо задать элемент разметки, в
который он будет добавлен. Рекомендуется использовать FrameLayout, так
как он позволит отобразить свое содержимое с наименьшим искажением.
Далее следует сделать последовательно несколько действий в классе Activi-
ty:
1. Определить менеджер фрагментов getFragmentManager() в Activity:
FragmentManager fragmentManager = getFragmentManager().
2. Открыть транзакцию для выполнения любых действий с фрагмен-
тами:
FragmentTransaction fragmentTransaction =
fragmentManager.beginTransaction().
3. Создать экземпляр класса фрагмента:
MyFragment fragment = new MyFragment().

2.5. Фрагменты
45
4. Добавить фрагмент в стек с помощью транзакции. Рекомендуется
использовать не функцию add(), а функцию replace(), которая не просто добавляет фрагмент, а проверяет есть ли он там или нет и, если есть, заменяет
его на новый и ставит в верхушку стека:
fragmentTransaction.replace(R.id.fragment_container, fragment).
5. Завершить транзакцию и сохранить все сделанные изменения с по-
мощью функции commit():
fragmentTransaction.commit().
Все представленные выше действия позволяют добавить фрагмент из
кода приложения и записываются следующим образом:
MyFragment fragment = new MyFragment();
getFragmentManager()
.beginTransaction()
.replace(R.id.fragment_container, fragment)
.commit();
Фрагмент с представленным выше макетом представлен на рис. 18.
Рис. 18. Пример отображения макета фрагмента

2. Интерфейс мобильного приложения (Activity)
46
Создание фрагмента возможно не только вручную, но и автоматически: правый клик по имени пакета ->New->Fragment и выбрать необходи-
мый тип фрагмента. Откроется окно, представленное на рис. 19.
Среда разработки предлагает создать пустой xml-файл и связать его с
фрагментом (первая галочка).
Вторая галочка предлагает добавить во фрагмент паттерн “Фабрика”.
Он будет представлен методом newInstance(String, String), возвращающим
экземпляр класса фрагмента с включенным Bundle с двумя переданными в
метод полями. Взятие этих полей будет также добавлено в метод
onCreate().
Рис. 19. Автоматическое создание фрагмента
Третья галочка позволит автоматически добавить средство передачи
данных из фрагмента в Activity. Данный параметр для выполнения лабораторных работ не требуется.

2.5. Фрагменты
47
2.5.2. Работа с фрагментами
Фрагменты хранятся в стеке и переключаться между ними можно по
нажатию кнопки назад. При каждом нажатии будет отображаться каждый
положенный ранее в стек фрагмент. Если стек опустеет закроется Activity.
Положить фрагмент в стек можно с помощью функции addToBack-
Stack(). Входным параметром у него будет строка-тег фрагмента, который
является необязательным и может равняться null. Вытолкнуть последний
положенный фрагмент можно с помощью функции popBackStack().
Так как фрагмент тесно связан с Activity, имеются методы доступа к
Activity из фрагмента и наоборот. Получить экземпляр создавшего фрагмент Activity можно функцией getActivity(). Может возникнуть ситуация, в
которой фрагмент больше не связан с Activity и метод вернет null. Чтобы
такой ситуации избежать в Support Library 27.1.0 появился метод requareAc-
tivity().
Передать данные во фрагмент из Activity можно с помощью структуры Bundle (рассмотрено в лабораторной работе 1) и метода setArguments() у
фрагмента.
MyFragment fragment = new MyFragment();
Bundle args = new Bundle();
args.putString("MyKey", "MyValue");
fragment.setArguments(args);
Достать переданные аргументы можно с помощью функции getArguments() в методе onCreate() фрагмента.
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle args = getArguments();
if (args != null) {
String value = args.getString("MyKey");
}
}

2. Интерфейс мобильного приложения (Activity)
48
Контрольные вопросы
1. Что такое Activity?
2. Способы создания Activity.
3. Что такое макет приложения?
4. Способы создания макета приложения.
5. Что такое Layout?
6. Основные виды Layout.
7. LinearLayout. Основные атрибуты.
8. Что такое Layout_weight?
9. Что такое Gravity?
10. TableLayout. Свойства.
11. FrameLayout. Атрибуты.
12. ConstraintLayout. Основные атрибуты.
13. Атрибуты View-элементов.
14. Варианты EditText.
15. Параметр scaleType для ImageView.
16. Спасобы обработки нажатия на кнопку.
17. Что такое Intent?
18. Переходы между Activity.
19. Создание Intent.
20. Добавление данных в Intent.
21. Что такое фрагмент?
22. Основные классы работы с фрагментом.
23. Способы создания фрагмента.
24. Шаги добавления фрагмента из кода приложения.

49
3. РАБОТА С РЕСУРСАМИ
Ресурсы – файлы, используемые в приложении, например, файлы
разметки, изображения, строковые константы и т. д. Почти все ресурсы
хранятся в проекте в каталоге res. Для каждого типа ресурсов имеется свой
подкаталог в каталоге res, в каждом из которых хранятся:
1) animator/ – файлы XML, определяющие анимации свойств [20];
2)
anim/ – файлы XML, определяющие анимации преобразований
[21];
3)
color/ – файлы XML, определяющие список состояния цветов [22];
4)
drawable/ – файлы растровых изображений (.png, .png, .jpg, .gif), а
также файлы в формате XML, которые представляют из себя следующие
подтипы графических ресурсов [23]:
файлы растровых изображений,
файлы из девяти фрагментов (растровые изображения с возмож-
ностью изменения размера),
списки состояний,
формы,
графические анимации,
другие графические элементы;
5)
mipmap/ – графические ресурсы с различной плотностью,
предназначенные для значков запуска [24];
6)
layout/ – файлы XML, которые определяют макет
пользовательского интерфейса [25];
7)
menu/ – файлы XML, определяющие меню приложения, такие как
меню параметров, контекстное меню и т.д [26];
8) raw/ – произвольные файлы для сохранения их в исходной форме.
Для того, чтобы открыть эти ресурсы с помощью InputStream, необходимо
вызвать Resources.openRawResource() с идентификатором ресурса
, который
имеет вид R.raw.<em>filename</em>
.
Если требуется получить доступ к исходным именам файлов и
иерархии файлов, можно сохранять некоторые ресурсы в каталоге assets/
(вместо каталога res/raw/). Файлы в каталоге assets/ не получают
идентификатора ресурса в
R.java, поэтому их чтение возможно только с
помощью
AssetManager;
9) values/ – файлы XML, которые содержат различные используемые
в приложении значения, например, ресурсы строк;

3. Работа с ресурсами
50
10) xml/ – произвольные xml-файлы.
В общей сложности можно определить следующие типы ресурсов
[27], представленные в табл. 1.
Таблица 1
Типы ресурсов
Тип ресурса
Каталог
Название файла
Типы данных
ресурса
Строки
/res/values/
strings.xml
<string>
Plurals
/res/values/
strings.xml
<plurals>
Массивы строк
/res/values/
strings.xml или arrays.xml
<string-array>
Логические значения
Boolean
/res/values/
bools.xml
<bool>
Цвета
/res/values/
colors.xml
<color>
Список цветов
/res/color/
Произвольное название
<selector>
Размеры (Dimensions)
/res/values/
dimens.xml
<dimen>
Идентификаторы ID
/res/values/
ids.xml
<item>
Целые числа
/res/values/
integers.xml
<integer>
Массив целых чисел
/res/values/
integers.xml
<integer-array>
Графические файлы
/res/drawable/
Файлы с расширением jpg и
png
-
Tween-анимация
/res/anim/
Файл xml с произвольным
названием
<set>, <alpha>,
<rotate>, <scale>,
<translate>
Покадровая анимация
/res/drawable/
Файл xml с произвольным
названием
<animation-list>
Анимация свойств
/res/animator/
Файл xml с произвольным
названием
<set>,
<objectAnimator>,
<valueAnimator>
Меню
/res/menu/
Файл xml с произвольным
названием
<menu>
XML-файлы
/res/xml/
Файл xml с произвольным
названием
Бинарные и текстовые
ресурсы
/res/raw/
Файлы мультимедиа (mp3,
mp4), текстовые и другие
файлы
Разметка графического
интерфейса
/res/layout/
Файл xml с произвольным
названием
Стили и темы
/res/values/
styles.xml, themes.xml
<style>
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]
