Недавно понадобилось делать пагинацию подручными способами, пришлось выкручиваться как только можно, так что сегодня я поделюсь своим опытом создания пагинации из локального списка. Это в принципе совсем не сложно и вполне можно самому додуматься как такое сделать, но в интернете я не нашел статей, так что думаю кому-то да пригодится.
Вот так вот будет выглядеть наша пагинация, она работает так потому что я специально сделал задержку перед загрузкой и кажется что данные подгружаются откуда-то с удаленного сервера, а на деле оно все хранится локально у нас в списке. Если же убрать эту задержку данные просто будут загружаться так быстро как вы приближаетесь к его концу. Для начала хочу сказать что в этом проекте я использовал уже возможно знакомый для вас код, так как я взял его из одной своей статьи: Работа с Retrofit. Оттуда я взял собственно код запроса, частично код адаптера и модели для респонса. И просто разбил этот список который нам возвращает апи на несколько частей. В приложении я сделал так что бы оно загружало по 10 итемов каждый раз когда мы скролим в низ. То есть мы дошли до низа списка, и делаем «запрос» на получение еще 10 из списка и так пока у нас не закончатся итемы.
Давайте начнем. По старинке для начала настроим наш проект для работы, нам нужно добавить библиотеки и настроить манифест для работы с интернетом.
У нас в проекте будет две основных библиотеки — это Retrofit и ButterKnife, первая нам нужна для создания реквестов на апи, вторая для упрощенного подключения вьюх к активитям. А еще у нас будет одна библиотека RecyclerView для списка.
Далее давайте настроим манифест. В нем нам всего лишь надо прописать пермишен доступа в интернет.
Ну, а дальше давайте приступим к кодингу. С начала напишем всю работу с апи, оно у нас стандартное как и весь код с ретрофитом. У нас есть интерфейс в котором у нас все реквесты к апи, класс который описывает эти запросы и модель которая принимает респонс с сервера и парсит ее.
Для начала давайте создадим модель. В ней у нас будет всего лишь один ArrayList который будет в себе хранить все данные которые возвращаются нам с сервера.
SearchModel.java
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
import java.util.ArrayList;
import java.util.List;
publicclassSearchModel{
@SerializedName("list")
@Exposeprivate List<List<String>> list = new ArrayList<>();
public List<List<String>> getList() {
return list;
}
publicvoidsetList(List<List<String>> list){
this.list = list;
}
}
Вот такой вот класс. Нам нужен всего лишь этот класс, его нам будет достаточно для парсинга данных.
Дальше нам нужно описать интерфейс запросов. У нас он короткий, всего один запрос который мы будем вызывать далее.
Тут как видно мы делаем get запрос на какой-то адрес и дальше в коде указываем что принимать мы будем SearchModel, а отправлять название песни которую мы ищем и ключ который нам выдали для работы с апи сайт с которого я взял это АПИ.
Дальше нам нужно написать сервис который будет создавать запросы с нашего интерфейса, так сказать будет описывать работу нашего интерфейса.
Собственно тут мы в константах описали адрес сайта к которому будем обращаться за АПИ, указали ключ который мы будем использовать как токен и дальше мы создаем статический инстанс нашего класса что бы нам проще было обращаться к паблик методам этого класса. Далее в конструкторе инициализируем ретрофит, подключаем к нему фабрики для конверта данных и указываем какой класс будем использовать для создания запросов.
Ниже в методе logLevel() мы говорим что мы хотим видеть все логи которые есть во время запросов и когда запрос прекращает свою работу.
Дальше нам нужно создать адаптер который мы будем использовать для отображения списка песен.
В целом стандартный адаптер, единственное что интересное это метод add(), он у нас для сетта данных в адаптер, в него мы передаем List и как бы потом в onBindViewHolder() мы его парсим по позиции так как этот список имеет статичное количество параметров и он содержит в себе по определенным полям определенные данные которые нам интересны. Собственно по id 4 и id 3 мы получаем имя исполнителя и название песни.
Вот так будет выглядеть отдельный айтем для адаптера.
Еще нам не хватает одного класса который будет добавлять айтемы с задержкой. Его мы реализовали как AsyncTask в котором будем делать задержку на 3 секунды и потом возващать колбек в активити.
Вполне себе стандартный код как по мне, в onPreExecute() мы вызываем колбек который возвращает в активити колбек и у нас будет стартовать прогрес диалог который будет показывать что данные загружаются. Дальше в методе doInBackground() мы делаем задержку на 3 секунды, и в onPostExecute() мы вызываем колбек который добавляет данные в адаптер и прячет прогрес диалог.
Дак, адаптер и класс который загружает данные у нас есть, теперь нужно соеденить все кусочки в одно целое в нашей активити. В ней мы проинициализируем все нужные классы, подключим все методы, запустим адаптер и сделаем запрос на сервер для получения музыки.
В методе onCreate() мы инициализируем леяут, ButterKnife, так же в этом методе мы инициализируем RecyclerView, создаем адаптер и сетим его в наш RecyclerView, и добавляем onScrollListener и в нем проверяем дошли ли мы до конца списка, и если дошли то запускаем наш AddItemsTask который по истечению 3 секунд добавит новые данные с помощью колбека onFinishTask(). Ну и в самом низу этого метода мы делаем запрос на сервер.
Метод recycleViewSetup() нам нужен для настройки RecyclerView, без этого метода наш список просто не отобразится на экране. В нем мы задаем размер, расположение, количество колонок и т.д., для нашего списка.
Методы onResponse() и onFailure() стандартные методы Retrofit, в первом мы сетим данные в список для дальнейшей работы с ним и вызываем метод который сетит часть данных, а именно 10 итемов в адаптер.
Метод addItemToAdapter() нам нужен для создания пагинации, в нем мы берем наш каунтер и прибавляем ему NUM_ITEMS_PAGE который равен у нас 10, собственно 10 итемам которые мы в начале будем отображать. Дальше в цикле мы проходимся paginationCounter количество раз с шагом paginationCounter — NUM_ITEMS_PAGE, это мы делаем для того что бы у нас всегда загружались только с нужного шага данные, то есть если мы на 5 шаге то у нас будет грузиться с 5 по 6 так как paginationCounter = 60, а NUM_ITEMS_PAGE = 10, а в сумме одно минус другое дает нам общее количество итемов которые нам нужно загрузить в адаптер. Потом мы останавливаем прогресс бар, проверяем что бы у нас не дай бог не выскачил IndexOfBoundsException и добавляем айтем в адаптер.
Ну и дальше идут два наших колбека onStartTask() и onFinishTask() которые выполняют собственно два важных события, делания прогресс бара видимым и прятание его с последующим вызовом метода addItemToAdapter().
Наша разметка будет выглядеть очень просто, в ней у нас будет всего лишь RecycerView и ProgressBar.
И собственно все, у нас готов наш проект, включаем и наслаждаемся его работой. У тех кто дошел до этого момента должен случиться эстетически оргазм от того что все работает и все так красиво написанно. Возможно у кого-то конечно есть предложения по улучшению кода, я всегда за, предлагайте.
Комментариев нет:
Отправить комментарий