Wygenerowane klasy powiązań

Biblioteka wiązań danych generuje klasy powiązań, które umożliwiają dostęp do zmiennych i widoków układu. Z tej dokumentacji dowiesz się, jak tworzyć dostosować wygenerowane klasy powiązań.

Wygenerowana klasa powiązania łączy zmienne układu z widokami w obrębie układ. Możesz dostosować nazwę i pakiet dla wiązania. Wszystkie wygenerowane klasy powiązań dziedziczą z ViewDataBinding.

Dla każdego pliku układu generowana jest klasa powiązania. Domyślnie jest to nazwa to nazwa pliku układu przekonwertowanego na wielkość liter Pascal z klasą Wiązanie. dodany sufiks. Jeśli więc na przykład nazwa pliku układu to activity_main.xml, odpowiadająca mu wygenerowana klasa to ActivityMainBinding. Ta klasa zawiera wszystkie powiązania od właściwości szablonu do i wie, jak przypisywać wartości dla wyrażeń wiążących.

Tworzenie obiektu powiązania

Obiekt powiązania jest tworzony natychmiast po powiększeniu układu, by upewnij się, że hierarchia widoków nie została zmodyfikowana, zanim powiążesz ją z widokami danych wyrażeń w układzie. Najpopularniejsza metoda powiązania obiektu z jest użycie metod statycznych dla klasy powiązania. Możesz zwiększyć wyświetl hierarchię i powiąż z nią obiekt za pomocą metody inflate() funkcji zgodnie z poniższym przykładem:

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 pobiera ViewGroup oprócz LayoutInflater obiekt , jako w tym przykładzie:

Kotlin

val binding: MyLayoutBinding = MyLayoutBinding.inflate(getLayoutInflater(), viewGroup, false)

Java

MyLayoutBinding binding = MyLayoutBinding.inflate(getLayoutInflater(), viewGroup, false);

Jeśli układ został powiększony za pomocą innego mechanizmu, możesz go powiązać oddzielnie w taki sposób:

Kotlin

val binding: MyLayoutBinding = MyLayoutBinding.bind(viewRoot)

Java

MyLayoutBinding binding = MyLayoutBinding.bind(viewRoot);

Czasami nie znasz z wyprzedzeniem typu powiązania. W takich przypadkach możesz utwórz powiązanie za pomocą funkcji DataBindingUtil zajęcia, jak pokazano 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ązania danych wewnątrz Fragment ListView lub RecyclerView adaptera, lepiej użyć inflate() metod klas powiązań lub DataBindingUtil, w tym przykładowym kodzie:

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);

Widoki z identyfikatorami

Biblioteka wiązań danych tworzy pole stałe w klasie powiązania dla instancji z każdego widoku, który ma identyfikator w układzie. Na przykład w bibliotece wiązań danych tworzy pola firstName i lastName typu TextView z metody ten układ:

<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 jedną kartę. Ten mechanizm może być szybszy niż wywoływanie funkcji findViewById() dla każdego widoku w układzie.

Identyfikatory nie są tak potrzebne, ponieważ nie wymagają wiązania danych, w niektórych przypadkach, gdy dostęp do widoków jest niezbędny z poziomu kodu.

Zmienne

Biblioteka wiązań danych generuje metody akcesorów dla każdej zadeklarowanej zmiennej w układzie. Na przykład ten układ generuje metodę ustawiającą i pobierającą metody w klasie powiązania dla 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>

Wycinki widoku danych

W przeciwieństwie do zwykłych widoków obiektów ViewStub zaczynają się od niewidocznych. Gdy są widoczne lub jawnie powiększone, zastępują się w układzie, uzupełniając inny układ.

Ponieważ element ViewStub znika z hierarchii widoków, widok w obiekt powiązania musi też zniknąć, aby umożliwić jego wywołanie przez funkcję czyszczenia pamięci. Widoki są ostateczne, ViewStubProxy obiekt zastąpi ViewStub w wygenerowanej klasie powiązania, dając Ci dostęp do ViewStub, kiedy już istnieje, oraz dostęp do rozszerzonego widoku w hierarchii, gdy ViewStub jest zawyżona.

Podczas tworzenia innego układu musisz dla niego ustanowić powiązanie. Dlatego ViewStubProxy musi nasłuchiwać ViewStub. OnInflateListener. i w razie potrzeby ustalić powiązania. Ponieważ w danym momencie może istnieć tylko jeden detektor czas, ViewStubProxy umożliwia ustawienie funkcji OnInflateListener, która wywołuje funkcję po ustanowieniu powiązania.

Natychmiastowe powiązanie

Zaplanowana jest zmiana zmiennej lub obserwowalnego obiektu po zmianie zmiennej lub obserwacyjnego obiektu. przed następną klatką. Istnieją jednak sytuacje, w których powiązanie musi zostać wykonane natychmiast. Aby wymusić wykonanie, użyj executePendingBindings() .

Zmienne dynamiczne

Czasami konkretna klasa powiązania jest nieznana. Na przykład plik RecyclerView.Adapter działanie w dowolnych układach nie zna konkretnej klasy powiązania. it musi przypisać wartość powiązania podczas wywołania onBindViewHolder() .

W poniższym przykładzie wszystkie układy, z którymi jest powiązany element RecyclerView, mają tag item. Obiekt BindingHolder ma metodę getBinding() zwracanie ViewDataBinding – podstawa zajęcia.

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

Model danych możesz zmienić w wątku w tle, o ile nie jest to kolekcji. Wiązanie danych lokalizuje wszystkie zmienne lub pola podczas oceny na uniknąć problemów z równoczesnością.

Nazwy niestandardowych klas powiązania

Domyślnie klasa powiązania jest generowana na podstawie nazwy pliku układu, zaczyna się od wielkiej litery, usuń podkreślenia ( _ ), wielkie litery kolejną literę z sufiksem wyrazu Wiązanie. Na przykład plik układu contact_item.xml generuje klasę ContactItemBinding. Zajęcia zostaną umieszczone w pakiecie databinding w ramach pakietu modułów. Jeśli na przykład moduł pakiet to com.example.my.app, klasa powiązania jest umieszczona w tagu com.example.my.app.databinding.

Nazwy klas powiązań można zmieniać lub umieszczać w różnych pakietach za pomocą Atrybut class elementu data. Na przykład ten układ generuje klasę powiązania ContactItem w pakiecie databinding w funkcji obecny moduł:

<data class="ContactItem">
    ...
</data>

klasę powiązania możesz wygenerować w innym pakiecie, dodając do niej przedrostek; z kropką. Ten przykład generuje klasę powiązania w tagu pakiet modułów:

<data class=".ContactItem">
    ...
</data>

Możesz też użyć pełnej nazwy pakietu, w którym ma być klasa powiązania . Ten przykład tworzy klasę powiązania ContactItem w Pakiet com.example:

<data class="com.example.ContactItem">
    ...
</data>

Dodatkowe materiały

Więcej informacji o powiązaniach danych znajdziesz w dodatkowych materiałach poniżej.

. .