- View Binding in Android
- Getting started with View Binding
- Using View Binding in Fragments
- Start using View Binding
- One-Liner ViewBinding Library
- Creating a custom view with Data binding: It’s so simple!
- 1 — Intro
- 2 — The project
- 3 — Let’s create XML of the keyboard
- 4 — We need to communicate with the XML
- 5 — Let’s use our library
- 6 — The ViewModel
- 7 — Finally, the bind
- 8 — Is this approach really better?
- Долгожданный View Binding в Android
- Как включить
- Как использовать
- Отличия от других подходов
- Использование в RecyclerView.ViewHolder
- View Binding in Android Jetpack [Updated]
- Main advantages
- View binding and Kotlin synthetics or ButterKnife
- Setup View Binding
- Usage
- Use view binding in activities
- Use view binding in fragments
- Disabling View Binding
- Migrate from Kotlin synthetics to Jetpack view binding
- Migrating From findViewById
View Binding in Android
We have learnt that every time we need to access a view from our XML layout into our Java or Kotlin code, we must use findViewById(). It was okay for small/personal projects where we use 5 to 6 views in a layout. But for larger projects we have comparatively more views in a layout, and accessing each view using the same findViewById() is not really comfortable.
What is View Binding?
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
Simply put, this allows us to access the views from the layout file in a very simple way by linking variables of our Kotlin or Java code with the XML views. When a layout is inflated, it creates a Binding object, which contains all the XML views that are casted to the correct type. This makes it really easier for us since we can retrieve all views in one line of code.
Getting started with View Binding
- Let’s start by enabling view binding in our project:
In build.gradle(:app) add the code in -> android
2. Before the onCreate() method, we create our binding object
3. Perform the following steps in onCreate() method:
- Call the inflate() method to create an instance of the binding class for the activity to use.
- Get reference to the root view
- Pass the root view to setContentView() [setContentView(binding.root)] instead of layout [setContentView(R.id.activity_main)]
4. To get reference of any view, we can use the binding object:
Using View Binding in Fragments
We follow the same steps:
- Before the onCreateView() method, we create our binding object
2. Initialize our binding object in onCreateView()
3. To get reference of any view, we can use the binding object
Note: The name of the binding class is generated by converting the name of the XML file to camel case and adding the word “Binding” to the end. Similarly, the reference for each view is generated by removing underscores and converting the view name to camel case . For example, activity_main.xml becomes ActivityMainBinding, and you can access @id/text_view as binding.textView.
View binding has important advantages over using findViewById():
- Null safety: Since view binding creates direct references to views, there’s no risk of a null pointer exception due to an invalid view ID.
- Type safety: The fields in each binding class have types matching the views they reference in the XML file. This means that there’s no risk of a class cast exception.
Start using View Binding
If you’re intrigued by View Binding and want to learn more about it, here’s some resources for you to learn:
One-Liner ViewBinding Library
You would have noticed that to use View Binding, we need to call the static inflate() method included in the generated binding class ( which creates an instance of the binding class for the activity or fragment )
Yesterday I came across an awesome library that makes ViewBinding one-liner ( By removing the boilerplate code and easily set ViewBindings with a single line )
One-liner ViewBinding Library : [Click Here]
Источник
Creating a custom view with Data binding: It’s so simple!
Leandro Borges Ferreira
Aug 24, 2017 · 4 min read
1 — Intro
Sometimes we use the same UI element many times in our project. A smart way to avoid repeating the same code over and over is to create a CustomView or a fragment to encapsulate the desired behavior.
But, sometimes, creating custom views or managing fragments lif e cycle may be over complicated. You usually end up with a custom view with a lot of boiler plate code or nested fragments with complex life cycles. A really simple way to deal with this problem is to use data binding to create little pieces of reusable UI. We only need to write code in the XML and the communication with the component is made by the bindings.
2 — The project
We are going to build a simple number keyboard to illustrate the use of data binding for creating UI components. This one:
Nothing really special here. The interesting part is HOW we do it.
3 — Let’s create XML of the keyboard
You can construct the keyboard with the code in the next gist. It has a lot of lines, but it’s just the some information over and over. I will explain the important part after the gist, so don’t waste too much time on this piece code.
The name of this xml is number_keyboard, this will be important later.
4 — We need to communicate with the XML
The communication parts (the important parts in the XML) are this:
We are importing the Actions so we can use some constants that we are going to define. We also need a listener for the button clicks. This is our keyListener, it is a variable in our XML and we are going to instantiate this when we finally use our library.
So we have a listener that will listen for the clicks in all the buttons. All we have to do now is to define the interface for this listener and our library is complete. No need for concrete classes!
So we define our listener:
To make this library able to erase the text, we need to define a Char that ask for erase instead of writing:
So this is our library. Pretty easy, right?
So now all we need to use this library in a project. Let’s do that.
5 — Let’s use our library
So it is time to use the library. We didn’t instantiate our keyListener, do you remember that? So we need to add the key listener in the XML of our activity. It will inside our viewModel, the class that coordinates our activity.
Our keyboard is the code:
We use our library as a simple include. That’s the magic: we don’t need a fragment with a complex life cycle or a complicated custom view, all we have is a simple include.
For the communication we use a listener in our ViewModel. The ViewModel will be defined in our XML. Let’s take a look:
We are defining our ViewModel. It has a testObservable that will receive the text inserted in the EditText. Please note that I am using two way data binding. The ViewModel also it has our listener.
So let’s create our ViewModel
6 — The ViewModel
To coordinate our XML, we just need a simple ViewModel.
The onKeyClick is implementing the OnKeyClick interface that we defined in our library, that’s how our communication works. The method receiveText() receives the character provided by Keyboard then evaluates if the command is to erase or to write and performs the right action.
7 — Finally, the bind
Create the activity and create the bind, simple as that:
8 — Is this approach really better?
My first try was to create a fragment to solve the keyboard problem. It seamed like a good solution and, at first, it worked just fine. But then I had to use the keyboard inside an another fragment in a ViewPager. This created some annoying problems with the life cycle of nested fragments for a very simple screen… nested fragments are just a nightmare o.O
So I decided to make a component using data binding. It made the project a lot simpler and my favorite part: No concrete classes! Just a simple interface for a listener. I used the same approach for some other views, and it worked fine. This is a scope of problem where data binding really shines!
But please remember that this is no silver bullet. If the problem you are trying to solve involves complex animations, the lack of Java/Kotlin code can make it impossible. Evaluate your needs before deciding to make a component with a fragment, custom view or data binding.
If you enjoyed reading this, please click the heart icon below. This will help to share the story with others. If you would like to see more content like this one, follow me.
Источник
Долгожданный 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.
Немного жаль, что такой инструмент не появился несколько лет назад.
Источник
View Binding in Android Jetpack [Updated]
View binding is the current recommendation from the Google team for importing the views from XML to Activity , Fragment , or Adapter classes. View binding is a feature that allows us to more easily write code that interacts with views. In most cases, view binding replaces findViewById . It supports both Java and Kotlin.
To learn more about view binding check out the official documentation.
Table of Contents
Main advantages
The new ViewBinding feature has some advantages compared to the traditional approach and some of the libraries:
- Null safety: view binding creates direct references to views, there’s no risk of a NullPointerException due to an invalid view ID. Also, when a view is only exists regarding some conditions, the field containing its reference in the binding class is marked with @Nullable .
- Type safety: All the View binding fields are generated matching the same type as the ones referenced in XML, so there’s no need to typecast. This means that the risk of a class cast exception is much lower, since If for some reason your layout and code doesn’t match, the build will fail at compile time instead at runtime.
- Speed: it doesn’t have any build time speed impact since it does not use annotation processors like ButterKnife or DataBinding.
Before getting started, check out another post on the jetpack,
View binding and Kotlin synthetics or ButterKnife
One of the most common questions asked about view binding is, “Should I use view binding instead of Kotlin synthetics or ButterKnife?” Both of these libraries are used successfully by many apps and solve the same problem.
For most apps we recommend trying out view binding instead of these libraries because view binding provides safer, more concise view lookup.
Setup View Binding
To enable view binding in a module, set the viewBinding build option to true in the module-level build.gradle file.
Usage
Once enabled for a project, view binding will generate a binding class for all of your layouts automatically. You don’t have to make changes to your XML — it’ll automatically work with your existing layouts.
You can use the binding class whenever you inflate layouts such as Fragment , Activity , or even a RecyclerView Adapter (or ViewHolder ).
For example, given a layout file called activity_main.xml:
The generated binding class is called ActivityMainBinding . This class has two fields: a TextView called textAppName and a Button called buttonGotoFragment .
Every binding class also includes a getRoot() method, providing a direct reference for the root view of the corresponding layout file. In this example, the getRoot() method in the ResultProfileBinding class returns the ConstraintLayout root view.
Use view binding in activities
To use View Binding in Activity, create an instance of the binding class, get the root view, and pass it to setContentView().
You can now use the instance of the binding class to reference any of the views:
Use view binding in fragments
In the onCreateView method, inflate your layout file and create the binding instance:
same like activity binding you can use the instance of the binding class to reference any of the views.
Disabling View Binding
If for any reason you want to disable View Binding on a specific layout, you can open it up and add the following statement.
Migrate from Kotlin synthetics to Jetpack view binding
Kotlin Android Extensions is deprecated, which means that using Kotlin synthetics for view binding is no longer supported. If your app uses Kotlin synthetics for view binding, use this guide to migrate to Jetpack view binding.
Update the Gradle file
Jetpack view binding is enabled on a module by module basis. For each module that uses view binding, set the viewBinding build option to true in the module-level build.gradle file:
Also,remove the line that enables Kotlin Android Extensions:
Now you can use the above mentioned options to work with activity and fragments.
Migrating From findViewById
2. add the binding class for your XML layout.
3. Now, replace setContentView() with the following:
Replace textView with binding.textView . Then add the binding. prefix to the rest of the views marked in red by the IDE.
Thanks for reading. You can download android view binding example in GITHUB.
If you have any questions, please feel free to leave a comment below.
Источник