Biblioteka powiązań danych generuje klasy powiązań, których możesz używać do uzyskiwania dostępu do zmiennych i widoków układu. Ta dokumentacja pokazuje, jak tworzyć i dostosowywać wygenerowane klasy powiązania.
Wygenerowana klasa powiązania łączy zmienne układu z widokami w układzie. Możesz dostosować nazwę i pakiet wiązania. Wszystkie wygenerowane klasy powiązań dziedziczą po klasie ViewDataBinding
.
Klasa powiązania jest generowana dla każdego pliku układu. Domyślnie nazwa klasy to nazwa pliku układu przekonwertowanego na wielkość liter w formacie Pascal z dodanym sufiksem Wiązanie. Jeśli na przykład nazwa pliku szablonu to activity_main.xml
, odpowiadająca mu klasa to ActivityMainBinding
.
Ta klasa zawiera wszystkie powiązania właściwości układu z widokami układu i wie, jak przypisywać wartości wyrażeń powiązań.
Tworzenie obiektu powiązania
Obiekt powiązania jest tworzony natychmiast po uzupełnieniu układu, dzięki czemu hierarchia widoków nie zostanie zmodyfikowana, zanim nastąpi powiązanie z widokami z wyrażeniami w układzie. Najczęstszą metodą wiązania obiektu z układem jest użycie metod statycznych w klasie powiązania. Możesz powiększyć hierarchię widoków danych i powiązać z nią obiekt za pomocą metody inflate()
klasy powiązania, jak pokazano w tym przykładzie:
Kotlin
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val binding: MyLayoutBinding = MyLayoutBinding.inflate(layoutInflater) setContentView(binding.root) }
Java
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); MyLayoutBinding binding = MyLayoutBinding.inflate(getLayoutInflater()); setContentView(binding.root); }
Istnieje alternatywna wersja metody inflate()
, która oprócz obiektu LayoutInflater
pobiera obiekt ViewGroup
, jak pokazano w tym przykładzie:
Kotlin
val binding: MyLayoutBinding = MyLayoutBinding.inflate(getLayoutInflater(), viewGroup, false)
Java
MyLayoutBinding binding = MyLayoutBinding.inflate(getLayoutInflater(), viewGroup, false);
Jeśli szablon został przekroczony za pomocą innego mechanizmu, możesz powiązać go oddzielnie w ten sposób:
Kotlin
val binding: MyLayoutBinding = MyLayoutBinding.bind(viewRoot)
Java
MyLayoutBinding binding = MyLayoutBinding.bind(viewRoot);
Czasami typ wiązania nie jest znany z góry. W takich przypadkach możesz utworzyć wiązanie za pomocą klasy DataBindingUtil
, jak w tym fragmencie kodu:
Kotlin
val viewRoot = LayoutInflater.from(this).inflate(layoutId, parent, attachToParent) val binding: ViewDataBinding? = DataBindingUtil.bind(viewRoot)
Java
View viewRoot = LayoutInflater.from(this).inflate(layoutId, parent, attachToParent); ViewDataBinding binding = DataBindingUtil.bind(viewRoot);
Jeśli używasz elementów wiązań danych w adapterze Fragment
, ListView
lub RecyclerView
, możesz skorzystać z metod klas wiązań inflate()
lub klasy DataBindingUtil
, jak pokazano w tym przykładzie kodu:
Kotlin
val listItemBinding = ListItemBinding.inflate(layoutInflater, viewGroup, false) // or val listItemBinding = DataBindingUtil.inflate(layoutInflater, R.layout.list_item, viewGroup, false)
Java
ListItemBinding binding = ListItemBinding.inflate(layoutInflater, viewGroup, false); // or ListItemBinding binding = DataBindingUtil.inflate(layoutInflater, R.layout.list_item, viewGroup, false);
Wyświetlenia z identyfikatorami
Biblioteka powiązań danych tworzy w klasie powiązania stałe pole dla każdego widoku, który ma identyfikator w układzie. Na przykład Biblioteka powiązań danych tworzy pola firstName
i lastName
typu TextView
na podstawie tego układu:
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable name="user" type="com.example.User"/>
</data>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{user.firstName}"
android:id="@+id/firstName"/>
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{user.lastName}"
android:id="@+id/lastName"/>
</LinearLayout>
</layout>
Biblioteka wyodrębnia widoki, w tym identyfikatory, z hierarchii widoków w jednym przebiegu. Ten mechanizm może być szybszy niż wywoływanie metody findViewById()
w przypadku każdego widoku danych w układzie.
Identyfikatory nie są niezbędne, ponieważ nie mają powiązania danych, ale w pewnych sytuacjach dostęp do widoków jest wymagany z poziomu kodu.
Zmienne
Biblioteka powiązań danych generuje metody akcesorów dla każdej zmiennej zadeklarowanej w układzie. Na przykład ten układ generuje metody setter i getter w klasie powiązania zmiennych user
, image
i note
:
<data>
<import type="android.graphics.drawable.Drawable"/>
<variable name="user" type="com.example.User"/>
<variable name="image" type="Drawable"/>
<variable name="note" type="String"/>
</data>
Strumienie widoków
W przeciwieństwie do zwykłych widoków obiekty ViewStub
zaczynają się od widoków niewidocznych. Gdy zostaną wyświetlone lub jawnie powiększone, zastępują się w układzie, zawyżając inny układ.
Obiekt ViewStub
znika z hierarchii widoków, więc widok obiektu powiązania też musi zniknąć, aby umożliwić jego zajęcie przez funkcję czyszczenia pamięci.
Widoki są ostateczne, obiekt ViewStubProxy
zastępuje obiekt ViewStub
w wygenerowanej klasie powiązania, zapewniając dostęp do obiektu ViewStub
, gdy istnieje, oraz dostęp do rozszerzonej hierarchii widoków, gdy ViewStub
jest zwiększony.
Podczas powielania innego układu dla nowego układu musi zostać ustanowione wiązanie.
Dlatego ViewStubProxy
musi nasłuchiwać parametru ViewStub
OnInflateListener
i w razie potrzeby ustanowić powiązanie. W danym momencie może istnieć tylko 1 detektor, więc ViewStubProxy
umożliwia skonfigurowanie obiektu OnInflateListener
, który wywołuje po ustanowieniu powiązania.
Natychmiastowe powiązanie
Gdy zmienna lub obserwowalny obiekt zmienia się, zmiana powiązania jest zaplanowana przed następną klatką. Czasami jednak powiązanie musi zostać wykonane od razu. Aby wymusić wykonanie kodu, użyj metody executePendingBindings()
.
Zmienne dynamiczne
Czasami konkretna klasa powiązania jest nieznana. Na przykład obiekt RecyclerView.Adapter
działający na podstawie dowolnych układów nie zna konkretnej klasy powiązania. Musi przypisać wartość wiązania podczas wywoływania metody onBindViewHolder()
.
W poniższym przykładzie wszystkie układy, z którymi element RecyclerView
wiąże się ze zmienną item
, Obiekt BindingHolder
ma metodę getBinding()
, która zwraca klasę podstawową ViewDataBinding
.
Kotlin
override fun onBindViewHolder(holder: BindingHolder, position: Int) { item: T = items.get(position) holder.binding.setVariable(BR.item, item); holder.binding.executePendingBindings(); }
Java
public void onBindViewHolder(BindingHolder holder, int position) { final T item = items.get(position); holder.getBinding().setVariable(BR.item, item); holder.getBinding().executePendingBindings(); }
Wątek w tle
Możesz zmienić model danych w wątku w tle, o ile nie jest on kolekcją. Powiązanie danych lokalizuje każdą zmienną lub pole podczas oceny, aby uniknąć problemów z równoczesnością.
Nazwy klas niestandardowego powiązania
Domyślnie klasa powiązania jest generowana na podstawie nazwy pliku układu rozpoczynającej się wielką literą, usuwaną podkreślenia ( _ ), wielką literą i przyrostkiem słowa Wiązanie. Na przykład plik układu contact_item.xml
generuje klasę ContactItemBinding
. Klasa jest umieszczana w pakiecie databinding
w pakiecie modułu. Jeśli na przykład pakiet modułu to com.example.my.app
, klasa powiązania jest umieszczona w pakiecie com.example.my.app.databinding
.
Możesz zmieniać nazwy klas powiązań i umieszczać je w różnych pakietach, dostosowując atrybut class
elementu data
. Na przykład ten układ generuje klasę powiązania ContactItem
w pakiecie databinding
w bieżącym module:
<data class="ContactItem">
...
</data>
Klasę powiązania możesz wygenerować w innym pakiecie, poprzedzając nazwę klasy kropką. Ten przykład generuje klasę powiązania w pakiecie modułu:
<data class=".ContactItem">
...
</data>
Możesz też użyć pełnej nazwy pakietu, w którym ma zostać wygenerowana klasa powiązania. Ten przykład tworzy klasę powiązania ContactItem
w pakiecie com.example
:
<data class="com.example.ContactItem">
...
</data>
Dodatkowe materiały
Więcej informacji o wiązaniach danych znajdziesz w tych materiałach dodatkowych.
- Przykłady z biblioteki powiązań danych na Androidzie
- Wiązanie danych na Androidzie
- Wiązanie danych – czego warto się nauczyć
Polecane dla Ciebie
- Uwaga: tekst linku jest wyświetlany, gdy JavaScript jest wyłączony
- Układy i wyrażenia powiązania
- Biblioteka powiązań danych
- Wyświetl powiązanie