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

Разработка мобильных приложений в среде Android Studio. Учебное пособие

.pdf
Скачиваний:
0
Добавлен:
07.09.2026
Размер:
1 Мб
Скачать
☆
7.2. Заполнение БД данными
101
В представленном выше скрипте создается таблица с названием mytable и двумя полями field1 и field2. Таблица имеет идентификатор типа целое число (integer), заполняющийся самостоятельно – строка primary key
autoincrement.
Если необходимо создать несколько таблиц, то метод execSQL() вы­зывается несколько раз.
Далее необходимо в Activity реализовать ряд действий с созданным классом DBHelper:
1. Объявить глобальную переменную класса DBHelper:
DBHelper dbHelper;
2. Инициализировать данную переменную в методе onCreate с по-
мощью первого конструктора:
dbHelper = new DBHelper(this, "mybd", null, 1);
3. Создать локальную переменную класса SQLiteDatabase, которая и
является переменной для реализации всех действий с БД. Для ее инициали­зации используется объект класса SQLiteOpenHelper (в примере, DBHelper) и методы getWritableDatabase() или getReadableDatabase(), где первый от­крывает БД на запись, второй – на чтение.
SQLiteDatabase db = dbHelper.getWritableDatabase();
К данной переменной следует применять методы insert, delete и другие для работы с таблицами и данными в БД.
На этом создание БД, состоящей из одной таблицы, закончено.
7.2. Заполнение БД данными
Для добавления строки в таблицу используется метод insert(),
long rowID = db.insert("mytable", null, cv);
который может вернуть номер добавленной строки.
Данный метод принимает на вход три параметра:
7. База данных в Android
102
1. Название таблицы.
2. Используется, если добавляется пустая строка. Имеет тип String.
3. Данные для вставки – формат ContentValues [47]. Данный класс
содержит записи типа ключ-значение, которые представляют собой поле таблицы и значение поля. Один объект класса содержит все пары значений для одной строки таблицы.
ContentValues cv = new ContentValues(); cv.put("field1", "field 1 text"); cv.put("field2", "field 2 text");
7.3. Чтение данных из БД
Чтение данных из БД выполняется в несколько шагов:
1. Создание классов SQLiteOpenHelper и SQLiteDatabase, открытие
БД на чтение:
dbHelper = new DBHelper(this, "mybd", null, 1); SQLiteDatabase db = dbHelper.getReadableDatabase();
2. Чтение данных из БД реализуется с использованием Cursor [48].
Данный класс можно представить как таблицу с данными. Для получения данных из БД используется метод query() со следующими параметрами:
2.1. Имя таблицы;
2.2. Список полей: columns – представляет собой массив значений
типа String:
String[] columns = new String[]{"field1", "sum(field2) as field"}.
2.3. Условие where: selection – String:
String selection = "field1 > ?".
2.4. Массив аргументов для условия where. В нем можно использо-
вать знаки «?», которые будут заменены этими значениями – selectionArgs (представляет собой массив значений типа String, содержащих названия полей).
7.3. Чтение данных из БД
103
2.5. Группировка: groupBy – строка, содержащая названия полей, по
которым будет происходить группировка.
2.6. Использование условий для агрегатных функций: having – пред-
ставляет собой строку, содержащую условие:
String having = "sum(field3) > 25";
2.7. Сортировка: orderBy – строка, содержащая название поля, по ко-
торому произойдет сортировка.
Пример.
Cursor cursor = db.query("mytable", columns, selection, null, null, having,
null);
В примере некоторые значения параметров равны null. Так следует делать, если поле не используется. Если подать только один ненулевой ар­гумент – название таблицы – в курсоре окажутся все записи.
3. Поставить значение курсора на первую строку выборки:
cursor.moveToFirst();
Если в выборке нет ни одной строки, метод вернет значение false, иначе true.
4. Необходимо найти индексы полей, по которым в курсоре хранятся
значения каждой записи.
int idColIndex = cursor.getColumnIndex("id");
int field1ColIndex = cursor.getColumnIndex("field1");
int field2ColIndex = cursor.getColumnIndex("field2").
5. Продолжать брать из курсора значения пока есть следующая за-
пись:
do {
int id = cursor.getInt(idColIndex);
7. База данных в Android
104
String field1 = cursor.getString(field1ColIndex); String field2 = cursor.getString(field2ColIndex); } while (cursor.moveToNext()).
6. Если курсор больше не нужен, закрыть его:
cursor.close().
Контрольные вопросы
1. Что такое SQLite?
2. Шаги создания БД SQLite.
3. Создание таблицы БД.
4. Добавление данных в БД.
5. Получение данных из БД.
6. Что такое Cursor?
7. Параметры метода query().
8. Методы работы с Cursor.
105
8. ИНТЕРФЕЙС МОБИЛЬНОГО ПРИЛОЖЕНИЯ (ВЗАИМОДЕЙСТВИЕ С ПОЛЬЗОВАТЕЛЕМ)
В данном разделе будут рассмотрены некоторые дополнительные возможности взаимодействия пользователя с интерфейсом мобильного приложения и их реализация.
8.1. NavigationDrawer
Большинство приложений должно иметь какую-либо систему нави­гации. Самой распространенной для системы Android является боковое ме­ню, которое называется NavigationDrawer. Создавать его путем добавления View-элементов на Activity.
Для работы с боковым меню необходимо подключить дополнитель­ные библиотеки, добавив в часть dependencies следующие строки:
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support:design:28.0.0'
Далее среда разработки предложит пересобрать проект для того, что­бы она скачала новые подключенные библиотеки, и они стали доступны для использования.
8.1.1. Добавление NavigationDrawer в макет
Перед началом работы стоит заметить, что ни одного используемого элемента нет на панели инструментов и все действия придется выполнять в текстовом режиме.
Для этого в макете Activity, на котором должно находиться меню, ро­дительским элементом сделать DrawerLayout, как показано ниже.
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android" an-
droid:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
</android.support.v4.widget.DrawerLayout>.
8. Интерфейс мобильного прложения (взаимодействие с пользователем)
106
Далее необходимо добавить еще два дочерних элемента: элемент для отображения содержимого экрана и элемент для отображения меню. Со­держимое удобнее всего располагать в элементе FrameLayout, минимально влияющем на содержимое. Меню должно располагаться в элементе Naviga­tionView. Причем у DrawerLayout и NavigationView должно быть установ­лено свойство fitsSystemWindows в true для того, чтобы элементы знали, что содержат дочерние. Данное свойство характерно только для элементов бокового меню. Также необходимо указать, что меню будет появляться с правой стороны, за это отвечает свойство layout_gravity, установленное в значение start.
Ниже представлен описанный выше пример макета Activity с меню.
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/my_drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<FrameLayout
android:id="@+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<android.support.design.widget.NavigationView
android:id="@+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true" />
</android.support.v4.widget.DrawerLayout>.
8.1. NavigationDrawer
107
8.1.2. Добавление элементов меню
За содержимое меню отвечает свойство app:menu, которое принадле­жит элементу NavigationView и включает в себя ссылку на ресурс со спис­ком элементов.
Ниже представлен пример добавления элементов меню.
<android.support.design.widget.NavigationView
android:id="@+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:menu="@menu/drawer_menu" />
Ресурс необходимо создать вручную, причем в папке menu, которую среда разработки по умолчанию не создает. Поэтому сначала создаем папку
menu в папке res, потом в ней создаем файл элементов меню:
1. Правой кнопкой кликаем на папку res ->New->Directory и задаем
имя menu.
2. Правой кнопкой кликаем на папку menu New->Menu Resource File
и вводим желаемое имя.
Ниже представлен пример содержимого файла меню.
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<group android:checkableBehavior="single">
<item
android:id="@+id/my_item"
android:title="My item" />
</group>
</menu>
После создания файл будет содержать только открывающий и закры­вающий теги menu. Это особый модификатор, означающий что в файле со­держатся информация о меню [49]. Речь идет не только о боковом, но и о контекстном, и всплывающем меню. Это обязательный главный тег. Он
8. Интерфейс мобильного прложения (взаимодействие с пользователем)
108
может содержать либо группы (groups), либо отдельный элементы (item), либо и то, и другое одновременно. Группа может как содержать элементы, так и быть пустой. Элемент обязательно должен содержать идентификатор и название (title). Необязательные свойства – иконка, действие по клику (onClick) и много других [50].
В приведенном выше примере есть одна группа элементов с модифи­катором chekableBehavior = single, который разрешает или не разрешает выбирать сразу несколько элементов меню. Значение single означает, что нельзя. В группе содержится один элемент с идентификатором “my_item” и названием “My item”.
Также присутствует возможность добавить верхнюю часть меню, ко­торая представляет собой любой layout, содержащий любую информацию. Он задается с помощью свойства app:headerLayout элемента Naviga-
tionView.
8.1.3. Обработка кликов на элемент меню
Обработка кликов на элемент меню выполняется в классе Activity.
public class MainActivity extends Activity {
private DrawerLayout mDrawerLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mDrawerLayout = findViewById(R.id.my_drawer_layout);
NavigationView navigationView = findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(
new NavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(MenuItem menu-
Item) {
menuItem.setChecked(true);
8.1. NavigationDrawer
109
mDrawerLayout.closeDrawers(); return true; } }); } }
За обработку «нажатия» отвечает метод setNavigationItemSelectedLis- tener класса NavigationView. По синтаксису он аналогичен методу se- tOnClickListener для кнопки. Переопределённый метод onNavigationItem- Selected на вход принимает элемент меню (MenuItem). Класс MenuItem хранит идентификатор элемента. С помощью него можно понять, на какой элемент было совершено нажатие.
Внутри метода onNavigationItemSelected можно добавить переход на другой экран. В приведенном выше примере в метод добавлены две функции:
menuItem.setChecked(true) – выделяет элемент; mDrawerLayout.closeDrawers() – закрывает меню.
Данные функции необязательно добавлять в этот метод, но желательно, так как автоматически боковое меню не закрывается и элементы автоматиче­ски не выделяются.
Класс MenuItem хранит идентификатор элемента. С помощью него можно понять, на какой элемент было совершено нажатие.
public boolean onNavigationItemSelected(MenuItem menuItem) {
if (menuItem.getItemId() == R.id.my_item) {
menuItem.setChecked(true);
mDrawerLayout.closeDrawers();
}
return true;
}
Результат правильного выполнения всех вышеописанных действий представлен на рис. 29.
На данном этапе создание простейшего бокового меню можно счи­тать законченным. Оно выполняет свое основное предназначение:
8. Интерфейс мобильного прложения (взаимодействие с пользователем)
110
выезжает с левого края экрана по «свайпу»; имеет элементы; элементы кликабельны.
При необходимости можно добавить верхнюю часть, кнопку для от­крытия меню на toolbar, добавить обработчики кликов для каждого элемен­та и так далее [51].
Рис. 29. Экран приложения с боковым меню
8.2. AlertDialog
Диалоговое окно является одной из необходимых функций для взаи­модействия пользователя с контентом приложения. В Android они называ­ются AlertDialog и могут быть вызваны из любого места приложения, где доступен контекст.
Рассмотрим добавление диалогового окна по долгому нажатию на элемент списка RecyclerView.
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]