- Android Data Binding: RecyclerView
- Reduce, Reuse, Rebind
- Android Data Binding in RecyclerView
- Reusing the ViewHolder
- What’s Left?
- Долгожданный View Binding в Android
- Как включить
- Как использовать
- Отличия от других подходов
- Использование в RecyclerView.ViewHolder
- Android Data Binding in RecyclerView
- View Binding in Android: Activities, Fragments, Dialogs, and RecyclerView Adapters
- Using RecyclerView with ViewBinding in Android via Kotlin
- Dependencies
- Working with ViewBinding in Android using Kotlin
- Aayush Gupta ・ Jan 28 ・ 3 min read
- Implementation
Android Data Binding: RecyclerView
Reduce, Reuse, Rebind
While sometimes I like to think so, Data Binding as a term doesn’t always mean Android Data Binding. RecyclerView has its own way of binding data to the UI. RecyclerView has an Adapter with two very important methods that we implement to bind data:
RecyclerView exposes the common ViewHolder pattern as a first class citizen in its API. In onCreateViewHolder(), the Views are created and the ViewHolder contains references to them so that the data can be set quickly. Then in onBindView(), the specific data is assigned to the Views.
Android Data Binding in RecyclerView
As discussed in a previous article, Android Data Binding can be treated like the ViewHolder pattern. Ideally, we’d just return the generated Binding class from our onCreateViewHolder(), but it doesn’t extend RecyclerView.ViewHolder. So, the binding class will have to be contained by the ViewHolder instead.
Now, my adapter can create and bind using Android Data Binding:
If you were looking closely, you saw the executePendingBindings() at the end of MyViewHolder.bind(). This forces the bindings to run immediately instead of delaying them until the next frame. RecyclerView will measure the view immediately after onBindViewHolder. If the wrong data is in the views because the binding is waiting until the next frame, it will be measured improperly. The executePendingBindings() is important!
Reusing the ViewHolder
If you’ve ever used a RecyclerView’s ViewHolder before, you can see that we’ve saved a bunch of boilerplate code in which the data is set into the Views. Unfortunately, we still have to write a bunch of ViewHolders for different RecyclerViews. It also isn’t clear how you’d extend this should you have multiple view types. We can fix these problems.
It is common to have only one data object passed into a data binding class, like item above. When you have this pattern, you can use naming convention to make a single ViewHolder for all RecyclerViews and all view types. The convention we’ll use is to name the one view model object “obj.” You may prefer “item” or “data,” but if I use “obj,” it is easier to pick out in the example.
In MyViewHolder, I am using ViewDataBinding, the base class for all generated bindings, instead of the specific ItemBinding. This way, I can support any layout in my ViewHolder. I’m also using setVariable() instead of the type-safe, but class-specific, setObj() method so that I can assign whatever view model object type that I need. The important part is that the variable must be named “obj” because I use BR.obj as the key in setVariable(). That means you must have a variable tag in your layout file like this:
Of course, your variable will have whatever type your data bound layout requires instead of “Item.”
I can then create a base class that can be used for all of my RecyclerView Adapters.
In this Adapter, the layout ID is being used as the view type so that it is easier to inflate the right binding. This lets the Adapter handle any number of layouts, but the most common usage is to have a RecyclerView with a single layout, so we can make a base class for that:
What’s Left?
All the boilerplate from the RecyclerView is now handled and all you have left to do is the hard part: loading data off the UI thread, notifying the adapter when there is a data change, etc. Android Data Binding only reduces the boring part.
You can also extend this technique to support multiple variables. It is common to supply an event handler object to handle things like click events and you may want to pass that along with a view model class. If you always pass in the Activity or Fragment, you could add those variables. As long as you use consistent naming, you can use this technique with all of your RecyclerViews.
Using Android Data Binding with RecyclerViews is easy and significantly reduces boilerplate code. Maybe your application will only need one ViewHolder and you’ll never need to write onCreateViewHolder() or onBindViewHolder() again!
Источник
Долгожданный View Binding в Android
Пару дней назад Google выпустил Android Studio 3.6 Canary 11, главным нововведением в которой стал View Binding, о котором было рассказано еще в мае на Google I/O 2019.
View Binding — это инструмент, который позволяет проще писать код для взаимодейтсвия с view. При включении View Binding в определенном модуле он генерирует binding классы для каждого файла разметки (layout) в модуле. Объект сгенерированного binding класса содержит ссылки на все view из файла разметки, для которых указан android:id .
Как включить
Чтобы включить View Binding в модуле надо добавить элемент в файл build.gradle :
Также можно указать, что для определенного файла разметки генерировать binding класс не надо. Для этого надо указать аттрибут tools:viewBindingIgnore=»true» в корневой view в нужном файле разметки.
Как использовать
Каждый сгенерированный binding класс содержит ссылку на корневой view разметки ( root ) и ссылки на все view, которые имеют id. Имя генерируемого класса формируется как «название файла разметки», переведенное в camel case + «Binding».
Например, для файла разметки result_profile.xml :
Будет сгенерирован класс ResultProfileBinding , содержащий 2 поля: TextView name и Button button . Для ImageView ничего сгенерировано не будет, как как оно не имеет id . Также в классе ResultProfileBinding будет метод getRoot() , возвращающий корневой LinearLayout .
Чтобы создать объект класса ResultProfileBinding , надо вызвать статический метод inflate() . После этого можно использовать корневой view как content view в Activity :
Позже binding можно использовать для получения view:
Отличия от других подходов
Главные преимущества View Binding — это Null safety и Type safety.
При этом, если какая-то view имеется в одной конфигурации разметки, но отсутствует в другой ( layout-land , например), то для нее в binding классе будет сгенерировано @Nullable поле.
Также, если в разных конфигурациях разметки имеются view с одинаковыми id, но разными типами, то для них будет сгенерировано поле с типом android.view.View .
(По крайней мере, в версии 3.6 Canary 11)
А вообще, было бы удобно, если бы сгенерированное поле имело наиболее возможный специфичный тип. Например, чтобы для Button в одной конфигурации и TextView в другой генерировалось поле с типом TextView ( public class Button extends TextView ).
При использовании View Binding все несоответствия между разметкой и кодом будут выявляться на этапе компиляции, что позволит избежать ненужных ошибок во время работы приложения.
Использование в RecyclerView.ViewHolder
Ничего не мешает использовать View Binding при создании view для RecyclerView.ViewHolder :
Однако, для создания такого ViewHolder придется написать немного бойлерплейта:
Было бы удобнее, если при работе с RecyclerView.ViewHolder метод inflate(. ) не будет иметь параметр layoutInflater , а будет сам получать его из передаваемого parent .
Тут нужно ещё упомянуть, что при использовании View Binding поиск view через findViewById() производится только один раз при вызове метода inflate() . Это дает преимущество над kotlin-android-extensions , в котором кеширование view по умолчанию работало только в Activity и Fragment , а для RecyclerView.ViewHolder требовалась дополнительная настройка.
В целом, View Binding это очень удобная вещь, которую легко начать использовать в существующих проектах. Создатель Butter Knife уже рекомендует переключаться на View Binding.
Немного жаль, что такой инструмент не появился несколько лет назад.
Источник
Android Data Binding in RecyclerView
На Google IO 2015 анонсировали новую библиотеку Data Binding Library. Основная ее задача — вынесения взаимодействия модели и View в xml-файлы. Она значительно упрощает написание кода и избавляет от необходимости использования методов findByViewId(), добавления ссылок на view-элементы внутри Activity/Fragment’ов. Также она позволяет использовать кастомные атрибуты, привязывая их к статическим методам. Поскольку статьей просто по Data Binding уже достаточно, но по его использованию в RecycleView всего ничего, восполним этот пробел.
Настройка
Для начала заходим в файл build.gradle, который лежит в корневом каталоге проекта. В блоке dependencies выставляем:
Далее подключим Data Binding плагин к проекту. Для этого в build.gradle добавляем строчку с плагином. Также проверяем, чтобы compileSdkVersion была 23.
Биндинг
Перейдем к созданию xml-файла. Он, как обычно, создается в паке res/layoyt. В качестве корневого тега используем layout. Android Studio может подсвечивать его красным или предлагать выставить ширину и высоту, но мы ее игнорируем.
Чтобы создался биндер-класс, который и будет привязывать модель к view, нужно привязать xml к модели. Для этого внутри тега указываем имя и путь к нашей модели. В качестве примера будет отображатьcя список фильмов.
Осталось добавить свой layout и привязать к нему модель. Пусть у каждого фильма будет картинка, заголовок и краткое описание. Чтобы указать, что поле будет считываться из модели используем “@<*какое поле из модели использовать*>”.
С android:text=»@
Перейдем к адаптеру. Напишем простой RecyclerView.Adapter. Начнем с ViewHolder. Как он выглядел раньше:
Как он выглядел после Butter Knife:
Как он выглядит после DataBinding:
Далее нас интересуют два основных метода адаптера: onCreateViewHolder и onBindViewHolder. Созданием и биндигом будет заниматься MovieItemBinding. Он генерируется по названию xml, который мы написали выше. В данном случае файл xml назывался movie_item.xml.
Теперь перейдем к onBindViewHolder, как он выглядел раньше:
Как он выглядит теперь:
Но это еще не всё, как на счет кастомного app:imageUrl=»@
На вход поступит imageView и то, что передаст модель в качестве image. Теперь все заработает.
Остальные полезности
В модели Movie была переменная isWatched. Допустим, мы хотим, чтобы у просмотренных и новых фильмов были разные обработчики на клик. С DataBinding’ом теперь это проще простого. Напишем обработчик нажатия для фильма.
Добавим его в xml-файл в тег data.
Теперь в методе адаптера onBindViewHolder можно засетить наш лисенер. Как и в случае с биндером, название метода генерируется соотвественному названию переменной в xml-файле.
Пусть по загрузке картинка у просмотренных фильмов будет черно-белая. Для преобразование картинки добавим новый атрибут.
В адаптере через @BindingAdapter реализуем обработку
Также очень удобно использовать стабовые значения, если одно из полей пустое.
Стоит также отметить, что внутри MovieItemBinding содержатся ссылки на все view, у которых есть ID в xml-файле.
Библиотека очень упрощает работу с RecycleView, количество кода при написании теперь уменьшается в разы, при этом никаких if/else для колбеков и данных. С JavaRX можно еще больше упростить обновление данных, пока правда оно работает только в одну сторону: при изменении данных обновляется UI, но не наоборот.
Источник
View Binding in Android: Activities, Fragments, Dialogs, and RecyclerView Adapters
Jun 16, 2020 · 3 min read
Whenever we start a project the most monotonous work is to initialize each of the views from our layout files and using findViewById again and again. For a long time, we have been doing this but now ViewBinding can save your time.
What is View Binding? According to the official documentation
View binding is a feature that allows you to more easily write code that interacts with views. Once view binding is enabled in a module, it generates a binding class for each XML layout file present in that module. An instance of a binding class contains direct references to all views that have an ID in the corresponding layout.
In short its a replacement for our old friend findViewById.
Why use View Binding:
To use View Binding in your projects your Android Studio version should be at least 3.6.
In your build.gradle file add the following code:
From Android Studio version 4.0 use the following code:
Let’s see how itis implemented.
I am adding all the XML files here and you can see that I haven’t done anything special here everything is what we do normally.
Источник
Using RecyclerView with ViewBinding in Android via Kotlin
RecyclerView is one of the most used libraries in Android. In this article, I will show you how you can use it in conjunction with ViewBinding to make the most of it.
Dependencies
Here are the required dependencies:
- ViewBinding enabled in build.gradle file of the module,
- RecyclerView widget added to your host Fragment/Activity, and
- A XML layout that will be used by RecyclerView’s Adapter class to inflate the host Fragment/Activity.
In case you are unfamiliar with the topic of ViewBinding, you can check out my article on it.
Working with ViewBinding in Android using Kotlin
Aayush Gupta ・ Jan 28 ・ 3 min read
Implementation
We will create a class for our Adapter and extend it to RecyclerView.Adapter class while instantiating it.
This requires us to create a custom ViewHolder class that extends to RecyclerView.ViewHolder and will take our layout’s binding as an argument used to get the root of the layout file while at it.
Exit fullscreen mode
In the above example code, I am accepting a list as the class constructor. This list is supposed to have multiple elements of type Example which will have text as a key which we will use later.
Notice how the inner class’s constructor is of type RVExampleBinding . You need to make sure that you use the layout resource you created earlier to be consumed by the Adapter class.
Now, we need to override the class functions in order to complete the Adapter setup.
The first method we will override is onCreateViewHolder . This function will return an instance of the ViewHolder class we created above. As the class constructor requires us to pass the required Binding , we will use pass the same while inflating the layout.
Exit fullscreen mode
The second method we will override is getItemCount . This function will return the size of the list we accepted as an argument in the Adapter class.
Exit fullscreen mode
The third and the last method we will override is onBindViewHolder . In this method, we will use the holder variable which we accepted as an argument to access the GUI components using binding. position argument will help us to access the element at the specific position in the list.
Exit fullscreen mode
Here is how my Adapter class RVExample.kt looks like:
Exit fullscreen mode
and that’s it. Now you can use RecyclerView with ViewBinding and take the benefit of null and type safety offered by ViewBinding.
Источник