Ao usar a vinculação de dados unidirecional, você pode definir um valor em um atributo e definir um que reage a uma mudança nesse atributo:
<CheckBox android:id="@+id/rememberMeCheckBox" android:checked="@{viewmodel.rememberMe}" android:onCheckedChanged="@{viewmodel.rememberMeChanged}" />
A vinculação bidirecional de dados fornece um atalho para esse processo:
<CheckBox android:id="@+id/rememberMeCheckBox" android:checked="@={viewmodel.rememberMe}" />
A notação @={}
, que inclui o caractere "=" assina, recebe dados
alterações na propriedade e monitoram as atualizações dos usuários ao mesmo tempo.
Para reagir a alterações nos dados de apoio, você pode fazer com que seu layout
uma implementação de Observable
, normalmente
BaseObservable
, e use uma
Anotação @Bindable
, como mostrado em
o seguinte snippet de código:
Kotlin
class LoginViewModel : BaseObservable { // val data = ... @Bindable fun getRememberMe(): Boolean { return data.rememberMe } fun setRememberMe(value: Boolean) { // Avoids infinite loops. if (data.rememberMe != value) { data.rememberMe = value // React to the change. saveData() // Notify observers of a new value. notifyPropertyChanged(BR.remember_me) } } }
Java
public class LoginViewModel extends BaseObservable { // private Model data = ... @Bindable public Boolean getRememberMe() { return data.rememberMe; } public void setRememberMe(Boolean value) { // Avoids infinite loops. if (data.rememberMe != value) { data.rememberMe = value; // React to the change. saveData(); // Notify observers of a new value. notifyPropertyChanged(BR.remember_me); } } }
Como o método getter da propriedade vinculável é chamado de getRememberMe()
, o
método setter correspondente da propriedade usa automaticamente o nome
setRememberMe()
.
Para mais informações sobre como usar BaseObservable
e @Bindable
, consulte Trabalhar com
objetos de dados observáveis.
Vinculação de dados bidirecional usando atributos personalizados
A plataforma fornece implementações de vinculação de dados bidirecionais para os tipos mais comuns
atributos bidirecionais e listeners de mudança, que podem ser usados
como parte do seu app. Se você quiser usar a vinculação de dados bidirecional com uma
atributos, você precisa trabalhar com os
@InverseBindingAdapter
e
@InverseBindingMethod
anotações.
Por exemplo, se você quiser ativar a vinculação de dados bidirecional em um atributo "time"
em uma visualização personalizada chamada MyView
, siga estas etapas:
Anotar o método que define o valor inicial e é atualizado quando o valor mudanças usando
@BindingAdapter
:Kotlin
@BindingAdapter("time") @JvmStatic fun setTime(view: MyView, newValue: Time) { // Important to break potential infinite loops. if (view.time != newValue) { view.time = newValue } }
Java
@BindingAdapter("time") public static void setTime(MyView view, Time newValue) { // Important to break potential infinite loops. if (view.time != newValue) { view.time = newValue; } }
Anote o método que lê o valor da visualização usando:
@InverseBindingAdapter
:Kotlin
@InverseBindingAdapter("time") @JvmStatic fun getTime(view: MyView) : Time { return view.getTime() }
Java
@InverseBindingAdapter("time") public static Time getTime(MyView view) { return view.getTime(); }
Neste ponto, a vinculação de dados sabe o que fazer quando os dados mudam (chama o método
método com a anotação
@BindingAdapter
) e o que
quando o atributo de visualização muda (ele chama o método
InverseBindingListener
).
No entanto, ela não sabe quando ou como o atributo muda.
Para isso, é necessário definir um listener na visualização. Pode ser um listener personalizado
associado à visualização personalizada, ou pode ser um evento genérico, como uma perda
de foco ou uma mudança de texto. Adicionar a anotação @BindingAdapter
ao método
que define o listener de alterações na propriedade:
Kotlin
@BindingAdapter("app:timeAttrChanged") @JvmStatic fun setListeners( view: MyView, attrChange: InverseBindingListener ) { // Set a listener for click, focus, touch, etc. }
Java
@BindingAdapter("app:timeAttrChanged") public static void setListeners( MyView view, final InverseBindingListener attrChange) { // Set a listener for click, focus, touch, etc. }
O listener inclui um InverseBindingListener
como parâmetro. Você usa o
InverseBindingListener
para informar ao sistema de vinculação de dados que o atributo tem
mudou. O sistema pode então começar a chamar o método anotado usando
@InverseBindingAdapter
e assim por diante.
Na prática, esse listener inclui uma lógica não trivial, incluindo listeners
para vinculação unidirecional de dados. Para ver um exemplo, consulte o adaptador do atributo de texto
mudar,
TextViewBindingAdapter
Converters
Se a variável vinculada a um objeto View
precisa ser formatada, traduzida ou alterada de alguma forma antes de ser exibida;
é possível usar um objeto Converter
.
Por exemplo, use um objeto EditText
que mostre uma data:
<EditText
android:id="@+id/birth_date"
android:text="@={Converter.dateToString(viewmodel.birthDate)}"
/>
O atributo viewmodel.birthDate
contém um valor do tipo Long
, então ele precisa
sejam formatados usando um conversor.
Como uma expressão bidirecional está sendo usada, também precisa haver um inverso
conversor para permitir que a biblioteca saiba como converter a string fornecida pelo usuário de volta.
ao tipo de dados de apoio, neste caso Long
. Esse processo é feito adicionando
a anotação @InverseMethod
;
a um dos conversores e faça com que essa anotação faça referência ao inverso
conversor. Um exemplo dessa configuração é mostrado no código a seguir
snippet:
Kotlin
object Converter { @InverseMethod("stringToDate") @JvmStatic fun dateToString( view: EditText, oldValue: Long, value: Long ): String { // Converts long to String. } @JvmStatic fun stringToDate( view: EditText, oldValue: String, value: String ): Long { // Converts String to long. } }
Java
public class Converter { @InverseMethod("stringToDate") public static String dateToString(EditText view, long oldValue, long value) { // Converts long to String. } public static long stringToDate(EditText view, String oldValue, String value) { // Converts String to long. } }
Loops infinitos usando vinculação de dados bidirecional
Tenha cuidado para não iniciar loops infinitos ao usar a vinculação bidirecional de dados. Quando
o usuário altera um atributo, o método anotado usando
@InverseBindingAdapter
é chamado, e o valor é atribuído à função de backup
. Isso, por sua vez, chamaria o método anotado usando
@BindingAdapter
, que acionaria outra chamada para o método anotado
usando @InverseBindingAdapter
e assim por diante.
Por isso, é importante quebrar possíveis loops infinitos comparando
valores novos e antigos nos métodos anotados usando @BindingAdapter
.
Atributos bidirecionais
A plataforma oferece suporte integrado para vinculação bidirecional de dados quando você usa os atributos na tabela a seguir. Para mais detalhes sobre como a plataforma oferece esse suporte, consulte as implementações dos adaptadores de vinculação correspondentes:
Classe | Atributos | Adaptador de vinculação |
---|---|---|
AdapterView
|
android:selectedItemPosition android:selection |
AdapterViewBindingAdapter
|
CalendarView |
android:date |
CalendarViewBindingAdapter
|
CompoundButton |
android:checked
|
CompoundButtonBindingAdapter
|
DatePicker
|
android:year android:month android:day |
DatePickerBindingAdapter
|
NumberPicker |
android:value
|
NumberPickerBindingAdapter
|
RadioButton
|
android:checkedButton |
RadioGroupBindingAdapter
|
RatingBar
|
android:rating
|
RatingBarBindingAdapter
|
SeekBar
|
android:progress |
SeekBarBindingAdapter
|
TabHost
|
android:currentTab |
TabHostBindingAdapter
|
TextView
|
android:text
|
TextViewBindingAdapter
|
TimePicker
|
android:hour android:minute |
TimePickerBindingAdapter
|
Outros recursos
Para saber mais sobre a vinculação de dados, consulte as seguintes recursos extras.
Amostras
- Amostras da Android Data Binding Library (link em inglês)
Codelabs
Postagens do blog
- Vinculação de dados: lições aprendidas (link em inglês)
Recomendados para você
- Observação: o texto do link aparece quando o JavaScript está desativado.
- Trabalhar com objetos de dados observáveis
- Layouts e expressões de vinculação
- Vincular visualizações de layout a componentes de arquitetura