- RecyclerView
- getItemCount()
- onCreateViewHolder
- onBindViewHolder()
- Горизонтальная прокрутка
- Оптимизация
- Обработка нажатия кнопок в адаптере recyclerview (Kotlin)?
- 2 ответа
- Урок 4. Kotlin. Обработка нажатия кнопок и взаимодействие с view в android
- Продолжаем курс по разработке андроид-приложений на языке Kotlin для начинающих программистов.
- Автоматический импорт
- Отображение сообщения по нажатию кнопки
- RecyclerView Item Click Listener the Right Way
- Example Scenario
- Project Creation
- Data model
- Recyclerview Adapter and view holder
- Item Click the bad way
- Let us fix it
RecyclerView
Компонент RecyclerView появился в Android 5.0 Lollipop и находится в разделе Containers. Для простоты буду называть его списком, хотя на самом деле это универсальный элемент управления с большими возможностями.
Раньше для отображения прокручиваемого списка использовался ListView. Со временем у него обнаружилось множество недостатков, которые было трудно исправить. Тогда решили создать новый элемент с нуля.
Вначале это был сырой продукт, потом его доработали. На данном этапе можно считать, что он стал полноценной заменой устаревшего ListView.
Схематично работу RecyclerView можно представить следующим образом. На экране отображаются видимые элементы списка. Когда при прокрутке списка верхний элемент уходит за пределы экрана и становится невидимым, его содержимое очищается. При этом сам «чистый» элемент помещается вниз экрана и заполняется новыми данными, иными словами переиспользуется, отсюда название Recycle.
Компонент RecyclerView не является родственником ListView и относится к семейству ViewGroup. Он часто используется как замена ListView, но его возможности шире.
Следует сказать, что при работе с ним приходится писать много кода, который пугает новичков. Если с RecyclerView работать не постоянно, то порой забываются детали и сложно вспомнить необходимые шаги. Многие просто сохраняют отдельные шаблоны и копируют в разные проекты.
Внешний вид можно представить не только в виде обычного списка, но и в виде сетки. При необходимости можно быстро переключиться между разными типами отображения.
Для размещения своих дочерних элементов используется специальный менеджер макетов LayoutManager. Он может быть трёх видов.
- LinearLayoutManager — дочерние элементы размещаются вертикально (как в ListView) или горизонтально
- GridLayoutManager — дочерние элементы размещаются в сетке, как в GridView
- StaggeredGridLayoutManager — неравномерная сетка
Можно создать собственный менеджер на основе RecyclerView.LayoutManager.
RecyclerView.ItemDecoration позволяет работать с дочерними элементами: отступы, внешний вид.
ItemAnimator — отвечает за анимацию элементов при добавлении, удалении и других операций.
RecyclerView.Adapter связывает данные с компонентом и отслеживает изменения.
- notifyItemInserted(), notifyItemRemoved(), notifyItemChanged() — методы, отслеживающие добавление, удаление или изменение позиции одного элемента
- notifyItemRangeInserted(), notifyItemRangeRemoved(), notifyItemRangeChanged() — методы, отслеживающие изменение порядка элеметов
Стандартный метод notifyDataSetChanged() поддерживается, но он не приводит к внешнему изменению элементов на экране.
Программисты со стажем знают, что для создания «правильного» ListView нужно было создавать класс ViewHolder. В старых списках его можно было игнорировать. Теперь это стало необходимым условием.
Общая модель работы компонента.
Мы рассмотрим только базовый пример для быстрого знакомства. В реальных проектах примеры будут гораздо сложнее, чтобы обеспечить другие функциональные возможности — обработка жестов, анимация, динамическое удаление и добавление элементов.
Размещаем компонент в макете экрана через панель инструментов. Но сначала добавим зависимость.
Создадим макет для отдельного элемента списка. Варианты могут быть самыми разными — можно использовать один TextView для отображения строк (имена котов), можно использовать связку ImageView и TextView (имена котов и их наглые морды). Мы возьмём для примера две текстовые метки. Создадим новый файл res/layout/recyclerview_item.xml.
Добавим компонент в разметку экрана активности.
Минимальный код для запуска.
Пока ничего сложного, но выводить такой список ничего не будет. Нужен адаптер и данные для отображения. В адаптере описывается способ связи между данными и компонентом.
Начнём по порядку, чтобы запомнить последовательность. Для начала создадим обычный класс и в конструкторе передадим список строк. Список будет содержать имена котов.
Класс MyViewHolder на основе ViewHolder служит для оптимизации ресурсов. Новый класс добавим в состав нашего созданного ранее класса.
В созданном классе нужно просто перечислить используемые компоненты из макета для отдельного элемента списка. В нашем примере задействованы два TextView, инициализируем их через идентификаторы.
Создадим адаптер — наследуем наш класс от класса RecyclerView.Adapter и в качестве параметра указываем созданный нами MyViewHolder. Студия попросит реализовать три метода.
getItemCount()
Как правило данные являются однотипными, например, список или массив строк. Адаптеру нужно знать, сколько элементов нужно предоставить компоненту, чтобы распределить ресурсы и подготовиться к отображению на экране. При работе с коллекциями или массивом мы можем просто вычислить его длину и передать это значение методу адаптера getItemCount(). В простых случаях мы можем записать код в одну строчку.
onCreateViewHolder
В методе onCreateViewHolder нужно указать идентификатор макета для отдельного элемента списка, созданный нами ранее в файле recyclerview_item.xml. А также вернуть наш объект класса ViewHolder.
onBindViewHolder()
В методе адаптера onBindViewHolder() связываем используемые текстовые метки с данными — в одном случае это значения из списка, во втором используется одна и та же строка.
Должно получиться следующее.
Подключаем в активности. Создадим пока бессмысленный список строк, который передадим в адаптер.
Запускаем ещё раз.
Вариант с числами нам не интересен, поэтому добавим котов. Имена котов и кошек разместим в ресурсах в виде массива в файле res/values/strings.xml.
Создадим новую функцию для получения списка котов из ресурсов и передадим его адаптеру.
Горизонтальная прокрутка
Можем указать горизонтальный вариант прокрутки. Остальной код менять не придётся.
А можно вообще обойтись только XML-декларацией.
Оптимизация
При прокрутке под капотом выполняется сложная работа по обновлению контента. Поэтому не следует перегружать элементы списка сложной структурой и не перебарщивайте с вложенными элементами, а также нужно следить за оптимизацией, чтобы избежать лагов.
При работе с изображениями старайтесь использовать готовые библиотеки Picasso, Glide, Fresco и т.д.
Если картинки загружаются с сервера, неплохо заранее вычислять их размеры и пропорции. В некоторых случаях желательно позаботиться, чтобы картинки были одного размера (если это возможно).
Не перегружайте лишним кодом метод onBindViewHolder(). Только самое необходимое.
Источник
Обработка нажатия кнопок в адаптере recyclerview (Kotlin)?
У меня есть адаптер, в котором каждый элемент имеет по 3 кнопки, которые генерируют диалог, который затем выполняет действие. У меня есть ощущение, что это должно быть удалено из адаптера (у меня есть доступные модели представлений), но это работает, и мне интересно: следует ли мне переместить логику во фрагмент, в модель представления, нужно ли мне вообще ее перемещать ( код ниже — плохая практика, и если да, то почему)? Любая помощь / вклад будут очень благодарны.
Вот код адаптера:
Это модель представления с настроенными переменными данных в реальном времени, с которыми я не мог работать во фрагменте, в котором находится этот RecyclerView:
2 ответа
Как реализовать onClick в RecyclerView. Предположим, что в Your Recycler каждое представление представляет собой визуализацию некоторого item , и когда вы нажимаете на него, вы хотите что-то сделать с этим элементом:
- Создать класс: ClickListener :
- Теперь в вашем RecylerViewAdapter передайте в качестве аргумента этот Listener:
- В onBindViewHolder передайте этот слушатель как аргумент
- В вашем классе ViewHolder:
- В макете вашего элемента (который необходимо преобразовать в макет привязки данных) добавьте следующее:
- Теперь вы можете добавить к Button метод onClick :
- Когда вы создаете адаптер во фрагменте или действии, вы должны передать clickListenner в качестве параметра. Таким образом, вы можете обрабатывать все, начиная с фрагмента, и RecyclerView не заботится о том, что вы делаете в этой функции.
Вот те изменения, которые у меня работают сейчас:
Во фрагменте, содержащем RecyclerView:
Я не мог понять, как передать позицию и int для оператора when через xml onClick, но на данный момент, по крайней мере, у класса адаптера удалена логика представления.
Источник
Урок 4. Kotlin. Обработка нажатия кнопок и взаимодействие с view в android
Продолжаем курс по разработке андроид-приложений на языке Kotlin для начинающих программистов.
На прошлом уроке мы добавили кнопки на главном экране вашего приложения, но пока эти кнопки ничего не делают. В этом уроке сделаем так, чтобы кнопки реагировали, когда пользователь нажимает их.
Автоматический импорт
Перед добавлением поведения к кнопкам необходимо включить автоматический импорт, чтобы Android Studio автоматически импортировала все классы, необходимые для кода Котлин.
- В Android Studio откройте Редактор настроек. Перейдите к File >Other Settings >Default Settings.
- Выберите Auto Imports. В разделе Java убедитесь, что пункт Add Unambiguous Imports on the fly отмечен флажком.
- Закройте редактор настроек.
Отображение сообщения по нажатию кнопки
На этом шаге мы добавим функцию отображения тоста – короткого сообщения на экране. Функция будет выполняться при нажатии кнопки с надписью TOAST.
- Откройте класс MainActivity.kt. (раскройте ветвь app >java >com.example.android.myfirstapp чтобы найти MainActivity). Этот класс описывает поведение главного экрана нашего приложения.Пока что класс содержит только одну функцию, onCreate(). Функция onCreate() выполняется, когда активити стартует.
- Посмотрите внимательно на функцию onCreate(). Обратите внимание на вызов функции setContentView(). Эта строка устанавливает файл ресурсов activity_main.xml в качестве разметки активити главного экрана.
- Добавим новую функцию toastMe() в класс MainActivity. Функция toastMe() принимает один аргумент — View. Это представление, получающее событие нажатия кнопки.Функция создает и отображает всплывающее уведомление. Вот ее код:
Источник
RecyclerView Item Click Listener the Right Way
Some Android developers wonder why Google created a view like Recyclerview without a click listener(given the fact that the deprecated ListView has an item click listener).
Because there is no standard way of setting a click listener, new developers tend to confuse on the right way of doing it. In this article, I will show you how to do it in a proper way using an example scenario.
Example Scenario
- There is a Recyclerview adapter with a Recyclerview with a list of items(Users in this case).
- What we want is that when an item is clicked, we get the item’s model(User) information and may be pass it to a second activity.
Project Creation
From Android Studio, create an empty android project(Select the Kotlin support option) and name your activity, MainActivity.
- Delete the default ‘Hello World’ TextView in activity_main.xml .
- Add recyclerview and cardview dependencies in app level build.gradle file as shown below.
Add recyclerview in activity_main.xml where you removed the textview as shown below.
Ok we are good to go. The assumption is that you have worked with the recyclerview(in Java) before and know how to create a recyclerview adapter.. Next, we create the model class containing username and phone.
Data model
Sweet Kotlin. Just the above line of code gives us access to a setter and getter under the hood and other methods like toString. Check more at https://kotlinlang.org/docs/reference/data-classes.html .
Next, we create our view holder and adapter. Pay attention here because it is the most important part of what this article addresses.
Recyclerview Adapter and view holder
- Create a new Kotlin file called RecyclerAdapter.kt
- Next we create our item_user.xml layout as follows
The item_user has two textviews which holds the name and phone.
Next we create our view holder. As usual, our view holder has a constructor with an itemView as parameter and we get a reference to our views from item_user layout .
Then we create our adapter with the list of users as a parameter. An adapter contains the list of users
Item Click the bad way
Note that in onBindView, we can have access to the the current clicked item and thus open a new activity from here and pass our data..
This will work perfectly but it is a bad practice because
- It is not a good practice opening an Activity from a viewholder context
- Note that onBindViewHolder is called as your views are populated during scrolling. Thus you will have numerous calls to setOnClickListener.
Let us fix it
The way that you should do is that you create an ItemClickListener interface with one method ontemClicked with parameter User.
- We then pass modify the Adapter’s constructor to take the users list and an OnItemClickListener interface
- We also modify the the ViewHolder to have a bind function which takes a user and itemClick interface as follows.
This is all we have to do. We just have to implement the interface in our MainActivity .
Источник