Добавил:
ivanov666
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Разработка мобильных приложений в среде Android Studio. Учебное пособие
.pdf
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, минимально
влияющем на содержимое. Меню должно располагаться в элементе NavigationView. Причем у 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.
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]
