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

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

.pdf
Скачиваний:
0
Добавлен:
07.09.2026
Размер:
1 Мб
Скачать
☆
6.1. Создание RecyclerView
91
Данная функция вызывается системой каждый раз при создании но-
вого элемента. Если прокрутить список вниз, а потом вернуть вверх, эта функция вызвана не будет, так как элемент был создан при первом появле­нии в области видимости и закеширован.
6. View v = LayoutInflater.from(parent.getContext()) .inflate(R.layout.recycler_view_item, parent, false);
Связывает макет элемента списка с View-элементом.
7. MyViewHolder vh = new MyViewHolder(v);
Создает объект класса MyViewHolder, в конструкторе которого со-
здаются все view-элементы и устанавливаются необходимые «слушатели».
8. public void onBindViewHolder(MyViewHolder holder, int position)
Данная функция вызывается после onCreateViewHolder() и наполняет
данными каждый элемент списка.
9. holder.mTextView.setText(mDataset.get(position));
В представленной строке view-элементам переданного ViewHolder
присваиваются данные, соответствующие переданной как входной пара­метр позиции. В примере данные получают из списка строк.
10. public int getItemCount()
Возвращает число (количество элементов списка). В примере данное
количество равно количеству элементов в mDataset.
После создания адаптера необходимо его применить к RecyclerView.
Таким образом, в классе Activity создаем поле:
private RecyclerView.Adapter mAdapter;
и присваиваем адаптер RecyclerView:
mRecyclerView.setAdapter(mAdapter);
6. Списки в мобильных приложениях
92
В текущем примере кода класса адаптера присутствует существенная ошибка – адаптер не инициализирован. Для инициализации адаптера в кон­кретном примере необходим список строк, которые будут получать из ре­сурсов.
Первое – необходимо создать массив строк в файле strings.xml.
<string-array name="recycler_data">
<item>My string 1</item>
<item>My string 2</item>
<item>My string 3</item>
</string-array>
Второе – «прочитать» массив строк в Activity
String[] myString = getResources().getStringArray(R.array.recycler_data);
где из Activity получают класс ресурсов (getResources()), который отвечает за все манипуляции с ресурсами, не только строковыми, но и с изображе­ниями (drawable) и другими типами ресурсов. Далее по индексу (R.array.recycler_data) происходит поиск массива и присвоение его массиву типа String.
Третье – преобразование массива строк в список.
List<String> recyclerData = Arrays.asList(myString);
где Arrays.asList() – стандартная функция языка java для преобразования массива в список.
Далее инициализируем адаптер созданным списком:
mAdapter = new MyRecyclerViewAdapter(recyclerData);
На данном этапе создание списка можно считать законченным. Ре­зультат правильно выполненных выше действий в виде экрана приложения представлен на рис. 28.
6.2. Загрузка данных в RecyclerView
93
Рис. 28. Экран приложения со списком RecyclerView
6.2. Загрузка данных в RecyclerView
В подразд. 6.1 был рассмотрен способ заполнения списка данными из ресурсов, в подразд. 5.1, 5.2 – загрузка с парсингом JSON-файла. Далее рассмотрим объединение данных действий.
Список, содержащий данные для RecyclerView, необходимо опреде­лить как глобальный и проинициализировать. В результате чего его размер будет равен 0:
private List<String> recyclerData = new ArrayList<>();
Далее следует инициализировать адаптер созданным списком и при­своить адаптер RecyclerView:
mAdapter = new MyRecyclerViewAdapter(recyclerData);
mRecyclerView.setAdapter(mAdapter);
6. Списки в мобильных приложениях
94
После необходимо модернизировать класс AsyncTask, созданный в
подразд. 4.1:
class MyAsyncTask extends AsyncTask<String, Integer, List<String>> {
protected List<String> doInBackground(String... arg) { String myString = arg[0]; return myString; }
protected void onPostExecute(List<String> fruitList) {
} }
В представленном выше коде программы изменен третий параметр класса со String на List<String>. Данный класс должен выполнять функцию загрузки данных в RecyclerView, поэтому в его методе doInBackground должно происходить формирование этого списка, а в методе onPostExecute – передача его в адаптер. Для этого тип выходного значения doInBack-
ground и входного onPostExecute должен совпадать с типом списка в Recy­clerView, как и третий тип AsyncTask.
Далее нужно представить логику загрузки данных в методе doInBackground с использованием любого описанного ранее вида заполне­ния списка. Предположим, были загружены данные в формате JSON и пре­образованы к типу Fruits, как показано в подразд. 5.2. Потом следует полу­чить созданный список, дописав в классе Fruits метод getFruits, который возвращает приватное поле List<String> fruits:
public List<String> getFruits() {
return fruits;
}
Таким образом, метод doInBackground примет вид:
protected List<String> doInBackground(String... arg) {
/*downloading json см. ЛР 5*/
6.2. Загрузка данных в RecyclerView
95
Gson gson = new Gson(); Fruits fruitItems = gson.fromJson(response.toString(), Fruits.class); return fruitItems.getFruits(); }
Далее изменим логику работы метода onPostExecute:
protected void onPostExecute(List<String> fruitList) { recyclerData.clear(); recyclerData.addAll(fruitList); mAdapter.notifyDataSetChanged(); }
где
1) recyclerData.clear() предположим, что список заполняется не пер-
вый раз, в котором уже хранятся данные. Для удаления старых данных ис­пользуется метод clear(), который удаляет все элементы.
2) recyclerData.addAll(fruitList) добавление новых данных в список.
Метод addAll копирует все элементы поданного ему на вход списка.
3) mAdapter.notifyDataSetChanged() метод уведомляет RecyclerView о том, что содержащиеся в нем данные изменились и ему необходимо отоб­разить новые. Данный метод следует использовать, если изменяется весь список. RecyclerView содержит методы для уведомления об изменении (удалении, перемещении) одного элемента, изменения порядка следования элементов:
3.1. notifyItemChanged(int)
3.2. notifyItemInserted(int)
3.3. notifyItemRemoved(int)
3.4. notifyItemRangeChanged(int, int)
3.5. notifyItemRangeInserted(int, int)
3.6. notifyItemRangeRemoved(int, int)
Такие узконаправленные методы действуют быстрее и экономичнее,
поэтому их использование предпочтительнее в любом удобном случае.
Для загрузки данных по адресу сайта, его нужно передать в Async-
Task. Тип передаваемого параметра должен соответствовать первому типу AsyncTask. В примере данная строка, т.е. вызов загрузки данных с переда- чей параметра выглядит следующим образом:
6. Списки в мобильных приложениях
96
MyAsyncTask myAsyncTask = new MyAsyncTask(); myAsyncTask.execute("https://developer.android.com/");
6.3. Обновление списка
Загрузка данных в список требует обновления информации.
Для выполнения действий по «свайпу» сверху используется SwipeRe­freshLayout [44], который считывает жест верхнего «свайпа» и уведомляет о нем разработчика. Для его использования необходимо выполнить не­сколько шагов:
1. Добавить SwipeRefreshLayout в макет приложения. Он не отобра­жается в списке элементов, потому все действия с ним нужно выполнять в текстовом режиме. Так как это разновидность Layout, он должен содержать в себе обновляемый элемент, в данном случае RecyclerView. Если этого не сделать, уведомление о «свайпе» не придет. Этот элемент не требует каких­либо особых параметров, достаточно указать идентификатор, высоту и ши­рину. После добавления этого элемента код макета будет выглядеть следу­ющим образом:
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity">
<android.support.v4.widget.SwipeRefreshLayout android:id="@+id/mySwipeRefreshLayout" android:layout_width="match_parent" android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView android:id="@+id/my_recycler_view" android:layout_width="match_parent" android:layout_height="match_parent" tools:listitem="@layout/recycler_view_item" />
Контрольные вопросы
97
</android.support.v4.widget.SwipeRefreshLayout> </android.support.constraint.ConstraintLayout>
2. Следующий шаг – определение SwipeRefreshLayout в java-классе. Обеспечивается стандартным способом с использованием метода findViewById(), объект SwipeRefreshLayout делают глобальным для воз­можности обращения к нему из «слушателя» «свайпа», рассмотренного на следующем шаге. В результате получим следующую строку:
private SwipeRefreshLayout mySwipeRefreshLayout; mySwipeRefreshLayout = findViewById(R.id.mySwipeRefreshLayout);
3. Далее следует добавить объекту «слушатель» «свайпа» – onRe­freshListener с методом onRefresh():
mySwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { @Override public void onRefresh() { mySwipeRefreshLayout.setRefreshing(false); } });
«Слушатель» обязательно должен содержать вызов функции
setRefreshing, для того чтобы убрать визуальное отображение индикатора
обновления. Принимаемый параметр имеет тип Boolean, где false означает скрыть индикатор, true – показать.
На этом создание функции обновления списка можно считать закон­ченным. Если нужно обновить данные в RecyclerView, в слушатель добав­ляется метод обновления данных или, например, вызов AsyncTask как было показано ранее.
Контрольные вопросы
1. Способы организации списка в Android.
2. Различия между ListView и RecyclerView.
3. Особенности RecyclerView.
6. Списки в мобильных приложениях
98
4. Основные методы RecyclerView.
5. Шаги создания RecyclerView.
6. Что такое адаптер?
7. Создание адаптера.
8. Основные методы адаптера.
9. Загрузка данных в RecyclerView.
10. Что такое SwipeRefreshLayout?
11. Шаги реализации SwipeRefreshLayout.
99
7. БАЗА ДАННЫХ В ANDROID
В большинстве мобильных приложений в процессе работы приложе­ния возникает необходимость где-то хранить большой объем данных, и са­мым подходящим вариантом являются базы данных (БД). В системе An­droid используется БД SQLite.
SQLite является бесплатной библиотекой, которая реализует авто­номные базы данных, не нуждающиеся в серверах и не требовательные к ресурсам, компактные и надежные. Работа с БД SQLite выполняется по­средством команд языка SQL. SQLite читает и пишет данные в обычные файлы на диске. Полная база данных SQL с несколькими таблицами, индексами, триггерами и представлениями компактно хранится в одном файле.
7.1. Создание базы данных
Первым шагом при работе с БД является её создание и обновление на более новую версию. Данные действия в системе Android реализуются с использованием класса SQLiteOpenHelper [45]. Необходимо создать класс­наследник SQLiteOpenHelper (в представленном ниже примере – класс DBHelper), который может находиться как в одном файле с Activity, так и в отдельном.
public class DBHelper extends SQLiteOpenHelper {
public DBHelper(@androidx.annotation.Nullable Context context,
@androidx.annotation.Nullable String name,
@androidx.annotation.Nullable SQLiteDatabase.CursorFactory factory,
int version) {
super(context, name, factory, version);
}
public DBHelper(@androidx.annotation.Nullable Context context,
@androidx.annotation.Nullable String name,
@androidx.annotation.Nullable SQLiteDatabase.CursorFactory factory,
int version, @androidx.annotation.Nullable DatabaseErrorHandler er-
rorHandler) {
super(context, name, factory, version, errorHandler);
}
7. База данных в Android
100
public DBHelper(@androidx.annotation.Nullable Context context, @androidx.annotation.Nullable String name, int version, @androidx.annotation.NonNull SQLiteDatabase.OpenParams openPar­ams) { super(context, name, version, openParams); }
@Override public void onCreate(SQLiteDatabase db) {
}
@Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVer­sion) {
} }
В классе DBHelper имеются три вида конструкторов и два метода on-
Create и onUpgrade. В данном учебном пособии будет использоваться пер-
вый конструктор, входными параметрами которого являются контекст, название БД, фабрика курсоров (в приведенных примерах не используется) и версия БД. В методе onCreate должны содержаться скрипты создания таблиц, в методе onUpgrade (вызывается при изменении версии БД) – скрипты изменения таблиц.
Вторым шагом при работе с БД является создание таблиц в методе onCreate() с использованием метода execSQL() [46], который выполняет пе­реданный ему скрипт, например, для создания таблицы. Данный метод бу­дет вызван только если БД не существует и ее необходимо создать. В примере ниже приведен скрипт создания таблицы:
db.execSQL("create table mytable ("
+ "id integer primary key autoincrement,"
+ "field1 text,"
+ "field2 text" + ");");
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]