Observabilidade é a capacidade de um objeto de notificar outros sobre alterações nos dados. A Data Binding Library permite que você faça objetos, campos ou as coleções observáveis.
Você pode usar qualquer objeto para vinculação de dados, mas a modificação não atualizar a IU automaticamente. Você pode usar a vinculação de dados para fornecer aos seus dados a capacidade de notificar outros objetos (conhecidos como listeners) quando as mudanças nos dados. Há três tipos de classes observáveis: campos, coleções e objetos.
Quando um desses objetos de dados observáveis é vinculado à IU e uma propriedade do quando o objeto de dados mudar, a interface será atualizada automaticamente.
Campos observáveis
Caso suas classes tenham apenas algumas propriedades, pode não valer a pena o esforço de
crie classes que implementem a
Observable
. Neste
caso, é possível usar a classe Observable
genérica e os seguintes
Classes específicas de primitivos para tornar os campos observáveis:
ObservableBoolean
ObservableByte
ObservableChar
ObservableShort
ObservableInt
ObservableLong
ObservableFloat
ObservableDouble
ObservableParcelable
Campos observáveis são objetos observáveis independentes que têm uma única
. As versões primitivas evitam encaixotar e desencaixar a caixa durante o acesso.
as operações. Para usar esse mecanismo, crie uma propriedade public final
na biblioteca
ou uma propriedade somente leitura em Kotlin, como mostrado nas
exemplo a seguir:
Kotlin
class User { val firstName = ObservableField<String>() val lastName = ObservableField<String>() val age = ObservableInt() }
Java
private static class User { public final ObservableField<String> firstName = new ObservableField<>(); public final ObservableField<String> lastName = new ObservableField<>(); public final ObservableInt age = new ObservableInt(); }
Para acessar o valor do campo, use o
set()
e
Métodos do acessador get()
ou use a propriedade do Kotlin
sintaxe:
Kotlin
user.firstName = "Google" val age = user.age
Java
user.firstName.set("Google"); int age = user.age.get();
Coleções observáveis
Alguns apps usam estruturas dinâmicas para reter dados. As coleções observáveis permitem
acesso a essas estruturas usando uma chave. A
Classe ObservableArrayMap
é útil quando a chave é um tipo de referência, como String
, conforme mostrado
exemplo a seguir:
Kotlin
ObservableArrayMap<String, Any>().apply { put("firstName", "Google") put("lastName", "Inc.") put("age", 17) }
Java
ObservableArrayMap<String, Object> user = new ObservableArrayMap<>(); user.put("firstName", "Google"); user.put("lastName", "Inc."); user.put("age", 17);
No layout, você pode encontrar o mapa usando as chaves de string, conforme mostrado no exemplo a seguir:
<data>
<import type="android.databinding.ObservableMap"/>
<variable name="user" type="ObservableMap<String, Object>"/>
</data>
…
<TextView
android:text="@{user.lastName}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:text="@{String.valueOf(1 + (Integer)user.age)}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
O ObservableArrayList
é útil quando a chave é um número inteiro, da seguinte maneira:
Kotlin
ObservableArrayList<Any>().apply { add("Google") add("Inc.") add(17) }
Java
ObservableArrayList<Object> user = new ObservableArrayList<>(); user.add("Google"); user.add("Inc."); user.add(17);
No layout, é possível acessar a lista pelos índices, conforme mostrado no exemplo a seguir:
<data>
<import type="android.databinding.ObservableList"/>
<import type="com.example.my.app.Fields"/>
<variable name="user" type="ObservableList<Object>"/>
</data>
…
<TextView
android:text='@{user[Fields.LAST_NAME]}'
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:text='@{String.valueOf(1 + (Integer)user[Fields.AGE])}'
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
Objetos observáveis
Uma classe que implementa a interface Observable
permite o registro da
ouvintes que querem ser notificados sobre mudanças de propriedade dos dados observáveis
objeto.
A interface Observable
tem um mecanismo para adicionar e remover listeners, mas é
decide quando as notificações são enviadas. Para facilitar o desenvolvimento, o módulo
A Binding Library fornece a
classe BaseObservable
, que
implementa o mecanismo de registro do listener. A classe de dados que implementa
BaseObservable
é responsável por notificar quando as propriedades mudam. Afazeres
atribua uma anotação Bindable
para o getter e chamar
notifyPropertyChanged()
no setter, conforme mostrado no exemplo a seguir:
Kotlin
class User : BaseObservable() { @get:Bindable var firstName: String = "" set(value) { field = value notifyPropertyChanged(BR.firstName) } @get:Bindable var lastName: String = "" set(value) { field = value notifyPropertyChanged(BR.lastName) } }
Java
private static class User extends BaseObservable { private String firstName; private String lastName; @Bindable public String getFirstName() { return this.firstName; } @Bindable public String getLastName() { return this.lastName; } public void setFirstName(String firstName) { this.firstName = firstName; notifyPropertyChanged(BR.firstName); } public void setLastName(String lastName) { this.lastName = lastName; notifyPropertyChanged(BR.lastName); } }
A vinculação de dados gera uma classe chamada BR
no pacote do módulo, que contém
os IDs dos recursos usados para vinculação de dados. A anotação Bindable
gera uma entrada no arquivo da classe BR
durante a compilação. Se a classe de base
para classes de dados não possa ser mudado, implemente a interface Observable
usando um
PropertyChangeRegistry
para registrar e notificar os listeners de forma eficiente.
Objetos com reconhecimento de ciclo de vida
Os layouts do seu app também podem se vincular a fontes de vinculação de dados que automaticamente notificar a interface sobre alterações nos dados. Dessa forma, suas vinculações reconhecem o ciclo de vida e são acionados somente quando a interface está visível na tela.
A vinculação de dados oferece suporte
StateFlow
e
LiveData
Para mais informações sobre
usando LiveData
na vinculação de dados, consulte Usar o LiveData para notificar a interface sobre os dados
mudanças.
Usar StateFlow
Se o app usa o Kotlin com corrotinas, você pode usar
StateFlow
como fonte de vinculação de dados. Para usar um objeto StateFlow
com
sua classe de vinculação, especifique um proprietário do ciclo de vida para definir o escopo da
StateFlow
. O exemplo a seguir especifica a atividade como
proprietário do ciclo de vida após a classe de vinculação ser instanciada:
class ViewModelActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
// Inflate view and obtain an instance of the binding class.
val binding: UserBinding = DataBindingUtil.setContentView(this, R.layout.user)
// Specify the current activity as the lifecycle owner.
binding.lifecycleOwner = this
}
}
Conforme descrito em Vincular visualizações de layout à arquitetura
componentes, vinculação de dados
funciona perfeitamente com ViewModel
objetos. É possível usar StateFlow
e ViewModel
juntos da seguinte maneira:
class ScheduleViewModel : ViewModel() {
private val _username = MutableStateFlow<String>("")
val username: StateFlow<String> = _username
init {
viewModelScope.launch {
_username.value = Repository.loadUserName()
}
}
}
No layout, atribua as propriedades e os métodos do objeto ViewModel
a
as visualizações correspondentes usando expressões de vinculação, conforme mostrado abaixo
exemplo:
<TextView
android:id="@+id/name"
android:text="@{viewmodel.username}" />
A IU é atualizada automaticamente sempre que o valor do nome do usuário muda.
Desativar o suporte ao StateFlow
Para apps que usam Kotlin e AndroidX, o suporte a StateFlow
é automaticamente
incluídos na vinculação de dados. Isso significa que a dependência de corrotinas é
incluída automaticamente no app se a dependência ainda não estiver disponível.
Para desativar essa funcionalidade, adicione o seguinte ao seu
Arquivo build.gradle
:
Groovy
android { ... dataBinding { addKtx = false } }
Kotlin
android { ... dataBinding { addKtx = false } }
Como alternativa, é possível desativar StateFlow
globalmente no projeto adicionando
linha a seguir ao arquivo gradle.properties
:
Groovy
android.defaults.databinding.addKtx = false
Kotlin
android.defaults.databinding.addKtx = false
Outros recursos
Para saber mais sobre vinculação de dados, consulte os recursos a seguir:
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.
- Módulo Saved State para ViewModel
- Vincular visualizações de layout a componentes de arquitetura
- Visão geral da biblioteca Paging