- Урок 20. Android Data Binding. Обработка событий
- Ссылка на метод
- Вызов метода
- Android databinding, with Kotlin!
- Getting Started
- First Steps
- What is Android data binding, and why should I use it?
- Setting up a view for Databinding
- Creating your own custom attributes
- How does databinding work?
- Sample app
- Wrapping up
- Databinding in Android using Kotlin
- Introduction
- The goal of the tutorial
- Prerequisites
- 1. Installing the required dependencies
- 2. Model
- 3. ViewModel
- 4. ViewModelFactory
- 5. User Interface
- 6. MainActivity
- Conclusion
- References
- About the author
- Want to learn more about the EngEd Program?
Урок 20. Android Data Binding. Обработка событий
В этом уроке рассмотрим как обрабатывать события View.
Полный список уроков курса:
С помощью биндинга мы можем вешать обработчики на события View. Есть два способа это сделать, давайте рассмотрим их.
Ссылка на метод
Рассмотрим пример с onClick. Допустим, у нас на экране, который отображает данные по работнику (Employee), есть кнопка Delete и мы хотим присвоить ей onClick обработчик.
Создаем свой класс обработчик:
Он не обязательно должен наследовать OnClickListener. Но его метод должен быть public и иметь те же параметры, что и метод OnClickListener.onClick(View view), т.е. должен быть один параметр типа View. Имя метода может быть любым.
Прописываем этот обработчик, как variable в layout.
В onClick кнопки ссылаемся на его метод onDelete:
Осталось создать объект MyHandler и передать его в биндинг:
По нажатию на кнопку Delete будет вызван метод onDelete объекта myHandler.
Если при попытке настроить обработчик в биндинге вы получаете подобную ошибку:
Listener class android.view.View.OnClickListener with method onClick did not match signature of any method handler::onDelete
внимательно проверьте, что модификаторы доступа и параметры метода в вашем обработчике такие же, что и в методе интерфейса стандартного обработчика. В случае с onClick — это OnClickListener.
Вызов метода
Если в первом способе мы просто указывали биндингу, какой метод обработчика вызвать, то во втором способе мы просто сами будем вызывать этот метод. Этот способ более гибкий, т.к. метод нашего обработчика не обязан иметь те же параметры, что и метод интерфейса стандартного обработчика.
Рассмотрим снова пример с onClick. Создаем обработчик.
В метод onDelete мы планируем получать не View, как в примере раньше, а объект Employee.
MyHandler так же, как и ранее, прописываем в variable и передаем в binding.
В onClick кнопки пишем вызов
Здесь используетcя лямбда. На вход нам предлагаются те же параметры, что и в методе интерфейса стандартного обработчика, т.е. view из OnClickListener.onClick(View view). Но мы не используем этот параметр. В метод onDelete мы передаем employee, который у нас описан, как один из variable в layout.
В результате по нажатию на кнопку, биндинг предоставит нам View, на которое было нажатие. Но мы его проигнорируем, возьмем у биндинга объект Employee и отправим в handler.onDelete.
Биндинг дает нам возможность не писать параметры в лямбде, если они нам не нужны. Т.е. можно сделать так:
Таким образом биндинг поймет, что его View нам не нужно, и не будет его передавать. Имейте ввиду, что если в стандартном обработчике несколько параметров, то вы можете указать либо все параметры, либо ни одного.
Чтобы закрепить тему, давайте рассмотрим пример с CheckBox. Например, на экране с данными по работнику есть чекбокс Enabled, который включает/выключает работника.
В обработчике создаем метод,
Будем получать объект Employee и состояние чекбокса.
В onCheckedChanged пишем вызов метода нашего обработчика.
В лямбде указываем параметры, которые пришли бы нам в стандартном обработчике OnCheckedChangeListener.onCheckedChanged(CompoundButton compoundButton, boolean checked).
Параметр view нам не понадобится, а вот checked передаем в метод вместе с employee.
Теперь по нажатию на чекбокс, биндинг будет вызывать метод onEnabled и передавать туда Employee объект и состояние чекбокса.
Рассмотрим еще несколько интересных моментов.
При вызове обработчика мы можем использовать условия.
Например, есть такой обработчик.
Мы можем в layout указать его методы следующим образом
Т.е. если чекбокс включен, то вызываем метод onEnabled, иначе — onDisabled.
Если в одном из случаев нам ничего не надо вызывать, то можно использовать void
В биндиге по умолчанию есть переменная context, которую вы всегда можете использовать, если есть необходимость.
Значение переменной context получено вызовом метода getContext у корневого View вашего layout.
В этих примерах я создавал отдельный объект обработчика, но разумеется вы можете создавать интерфейсы. прописывать их в качестве variable в layout и использовать хоть само Activity в качестве реализации.
Присоединяйтесь к нам в Telegram:
— в канале StartAndroid публикуются ссылки на новые статьи с сайта startandroid.ru и интересные материалы с хабра, medium.com и т.п.
— в чатах решаем возникающие вопросы и проблемы по различным темам: Android, Kotlin, RxJava, Dagger, Тестирование
— ну и если просто хочется поговорить с коллегами по разработке, то есть чат Флудильня
— новый чат Performance для обсуждения проблем производительности и для ваших пожеланий по содержанию курса по этой теме
Источник
Android databinding, with Kotlin!
The MVVM design pattern allows us to write code that is much easier to maintain, test, and reason about in Android development. In this post, we will describe how to setup an application for databinding using the `MVVM` pattern in Kotlin, although many of the concepts are also equally valid for `MVP`
Getting Started
This post walks through the steps to set up Android databinding using the MVVM pattern in Kotlin. If you learn best by playing directly with code, I have provided a simple sample app that that implements all of the features discussed below.
First Steps
First we require a few prerequisites for our Android project:
Add the Kotlin plugin to your gradle file:
Enable databinding in the gradle file:
Add databinding as a kapt dependency
Add the Kotlin standard library as a dependency
What is Android data binding, and why should I use it?
Android data binding allows for 1 or 2-way binding within the layout XML files of Android. This should be familiar to anyone who has done web based development with Angular or Ember, or C# WPF development.
The most basic case is to add an on-click listener. This requires no registering of on click listeners in any of your application code, just some XML in the layout file and a function to be called in your ViewModel class
If you are new to databinding the above might look a bit odd — why is my root element , what is this tag, what is that crazy string in the onClick attribute? Do not worry if it is confusing now, we will walk you through it line by line.
First the layout element:
All Android layout files that you wish to enable databinding for must start with this tag. This tag will only contain namespace declarations, not any height or width specifications. It will then include any layout or view within it as a child element, just as you would any other layout file.
This namespace gives access to the app attributes. These are custom attributes provided by either your project (more on this later!), or by the Android library itself. An example will be shown later of this in action.
The data tag is used to include all your Java / Kotlin values you wish to inject into the layout file.
The import tag is used to import any type that is used within the layout. Later we will show you an example utilising this concept to determine the visibility of the view.
The variable tag is used to store any values that will be used in the layout. In this case the DemoViewModel class is loaded as it contains the business logic which will control this view.
Here we are accessing the boolean field on the DemoViewModel called buttonVisible , and if it is true, then we are setting the visibility of the Button to View.VISIBLE , otherwise we are setting it to View.GONE . These values from the View class require an import as described above.
Here we can register a lambda which, when the user clicks on the button, will execute the provided code. In our case it will just call the buttonClicked method on the DemoViewModel class.
Finally we are binding the standard android attribute android:text to the string value contained in the field text in the DemoViewModel class. The syntax looks a bit weird but basically @ is used to tell the auto generated data binding class to replace this value, with whatever is inside the vm.text field. For 2 way binding (e.g. changes on a text view update the value in the view model) then the sytax would be @= , e.g. @=
Setting up a view for Databinding
In order to actually use databinding we need to set the content view of our activity using the Android provided android.databinding.DataBindingUtil class. This will return an auto generated ViewDataBinding class specific to our layout XML file, which allows us to inject any variables we need. In this case we need to inject the DemoViewModel class into the layout.
As you can see with the above code there is no need to directly access any View elements in the code, and all business logic is handled within the ViewModel , with the minimum just to setup the view inside the Activity .
The only odd thing in the above code is the use of ObservableField . An ObservableField is a simple data wrapper which will allow the layout to be notified whenever the value has changed. After using the set method in the buttonClicked function, it will update the internal String with the new value, and then notify any listeners (in our case the layout) of the change. The ObservableField can be used for any type as it allows generics e.g. ObservableField , ObservableField .
Creating your own custom attributes
So the MVVM architecture looks great right? What about if we want to change the text color of the TextView dynamically based on character length? Does that mean we have to reference the View within our ViewModel (breaking the idea that no Android specific code should be in the ViewModel )? We don’t have to! There are two ways to create your own custom attributes for a view.
First we will create some helpful extension methods to make detecting text changes easier:
Then, using a @BindingAdapter(«myCustomAttribute») annotation you can specify package function as a handler for a view’s attribute:
Or an alternative way is to create a custom view which will contain your business logic:
Then in the layout, regardless of which of the above approaches are used, you bind some data to your new attribute:
How does databinding work?
In order for the layout to interact with these injected values some glue code is generated by Android. This glue code will handle the on click listeners, binding adapters, and 2 way binding for us. So as developers we can just focus on the actual business logic.
Sample app
You can find the sample app that implements all of the features discussed above here: https://github.com/instil/kotlin-databinding
Wrapping up
Here at Instil we have been very much swept off our feet by the power and readability offered by Kotlin. The best bit being you don’t have to stop using any of the best practices you already know from Java, as Kotlin has such strong interoperability with Java while also being backed up by the fantastic tooling provided by Jetbrains in both IntelliJ and Android Studio.
Источник
Databinding in Android using Kotlin
December 3, 2020
If you have ever wondered if there is a way to link the UI directly to the data source ? You are in the right place. Repeating the dreaded findViewbyID statement in your code can be tedious.
It takes so much time that one may end up forgetting variables’ IDs. Well, there is a solution. That solution is data binding . We will learn how to implement this concept in this tutorial.
Introduction
Without going any further, it’s essential to understand what data binding is and it’s advantages. The data binding library is part of Android Jetpack utilities.
According to the Android developer documentation, the data binding library allows users to bind layouts and UI components to data sources declaratively.
The data binding library seeks to eliminate something like this:
By introducing this.
The goal of the tutorial
In this project, we will create a simple Notes app in Android using Kotlin . As you guessed, the app will make use of the data binding library.
At the end of the tutorial, your application should be similar to the one shown in the video below.
Prerequisites
This tutorial is intended for those who have some experience in Android programming using Kotlin . You can download the full source code here.
1. Installing the required dependencies
Launch Android studio and create a new project. Once the project is ready, go to the Gradle scripts folder and open build.gradle (module: app) .
Add buildFeatures and set databinding to true . This notifies the Android system that our app uses data binding. Therefore, the proper files will be generated.
In the same build.gradle file, add the lifecycle library to your dependencies . This library helps connect the UI to a ViewModel and LiveData .
Read more about MVVM architecture here.
Remember to add apply plugin: kotlin-kapt at the top of the file.
2. Model
In your primary folder, create a new package and name it model . Then create a Note.kt file in this package.
As shown, the data class NoteItem only holds two variables ( title and description ). These values are required to initialize the class.
3. ViewModel
The ViewModel makes it easy to update data changes on the UI .
Create a package named viewmodels in your main folder.
Then create a new file and name it MainViewModel.kt . The file will contain the following variables.
The isStringEmpty variable is a Boolean . It will help determine whether or not the user’s input is empty.
The inputTitle and inputdescription variables will store the user’s data. The values stored in these variables will change according to the user’s input; hence, we use MutableLiveData .
The list will store the NoteItem arraylst . It’s capable of refreshing itself when it detects a change in its content.
The NotesViewModel also contains three important methods; init , addData , and clearData .
The init method will initialize the isStringEmpty variable to false . This method launches automatically once the NotesViewModel is created.
The addData method takes the user input and checks if it’s empty.
The isStringEmpty variable is updated to true if the data is empty.
Otherwise, the data is entered into a NoteItem object and passed to the arraylst .
The arraylst is then stored in list.
The clearData function resets the arraylst and list , as shown below.
Note: To use the bindable component, the NotesViewModel must extend the Observable class. You will then need to implement the methods below.
Your final NotesViewModel file should look like this.
4. ViewModelFactory
In the same viewmodels package, create a file named NotesViewModelFactory and add the code below.
The NotesViewModelFactory will throw an Exception in case the ViewModel is not found.
5. User Interface
Let’s create the app UI before finalizing with the MainActivity .
Since this is a Notes App, we need to allow the user to enter, save, and clear data. Therefore, the application will have two EditTexts and two Buttons .
Whatever the user types will be displayed in a TextView on the click of the submit button. The app UI is shown below.
To include data binding in the UI, enclose all content with .
The ViewModel is introduced to the layout in the section, as shown. Ensure that the type value points to the specific folder that has the required ViewModel .
The EditText widgets will be bound to the NotesViewModel using @=
The submit and clear buttons will connect to the NotesViewModel by @<()->NotesViewModel.addData()> statement.
This is illustrated below.
We’ll use the TextView with the ID content to display the user’s input.
Here is the full code for the activity_main.xml .
6. MainActivity
In this class, we need to initialize the NotesViewModel and the ActivityMain data binding.
The lateinit allows variables to be initialized at a later stage.
The NotesViewModelFactory is initialized first and then passed to the NotesViewModel as a parameter.
The databinding is also assigned the required viewmodel and lifecycleowner .
We will observe the list in the NotesViewModel using the following commands.
We’ll observe the isStringEmpty variable to determine if the user has clicked the submit button without entering data. A Toast message will appear in case the user inputs are empty.
The complete MainActivity.kt is shown below.
When you run your application, it should appear as in the video below.
Conclusion
As a developer, data binding will allow you to save time by eliminating boilerplate code. The UI components are updated automatically in case of any data changes. This functionality enables you to create both high quality and productive applications.
References
Peer Review Contributions by: Peter Kayere
About the author
A lover of technology. An upright individual not afraid of getting out of the comfort zone and trying out new things.
Want to learn more about the EngEd Program?
Discover Section’s community-generated pool of resources from the next generation of engineers.
Источник