View Binding ułatwia pisanie kodu, który wchodzi w interakcję z widokami. Oto jak to skonfigurować w projekcie Android Gradle.
Większość programistów Androida prawdopodobnie zna klasykę findViewById()
metoda. Przekaż mu identyfikator jednego z widoków w układzie XML, a zwróci odwołanie do zawyżonej wersji tego widoku. Wszystko to przy założeniu, że podałeś właściwy identyfikator i że widok faktycznie istnieje. findViewById()
nie ma wbudowanych kontroli, które uniemożliwiałyby próbę odzyskania widoku, którego nie można odzyskać. Wprowadź powiązanie widoku.
Zamiast używać findViewById()
w każdym żądanym widoku View Binding automatycznie generuje klasę powiązania dla każdego układu XML. Każdy widok z identyfikatorem jest automatycznie dodawany do klasy, dzięki czemu można się do niego bezpośrednio odwoływać.
Dodanie powiązania widoku do projektu Gradle w systemie Android jest bardzo proste.
Konfiguracja stopniowania
View Binding jest włączone na poziomie modułu w Gradle. Jeśli masz wiele modułów, musisz włączyć je indywidualnie dla każdego z nich.
w android
block na poziomie modułu build.gradle
, dodaj opcję włączenia powiązania widoku.
android {
...
buildFeatures {
viewBinding true
}
}
Może pojawić się ostrzeżenie o nielegalnym dostępie, ale jest to błąd powodujący kłaczenie i można go bezpiecznie zignorować.
Zsynchronizuj projekt, a powiązanie widoku zostanie włączone. To jest takie proste.
Korzystanie z powiązania widoku
Istnieje kilka sposobów użycia powiązania widoku, ale zanim to nastąpi, porozmawiajmy o tym, jak generowane są klasy powiązań.
Składnia nazwy klasy
Załóżmy, że masz układ XML o nazwie some_layout.xml
. Zostanie nazwana odpowiadająca jej klasa powiązania SomeLayoutBinding
. Ten wzór dotyczy wszystkich plików.
Każde słowo (oddzielone podkreśleniami w nazwie pliku) zostanie zapisane wielką literą, a podkreślenia zostaną usunięte. „Wiązanie” zostaje następnie dodane na końcu.
Tworzenie instancji z istniejącym widokiem
Jeśli plik układu został już powiększony i masz odwołanie do katalogu głównego układu, możesz nakazać klasie powiązania widoku, aby korzystała z istniejącego układu.
Kotlina:
val binding = SomeLayoutBinding.bind(someLayoutRoot /* should be a View instance */)
Jawa:
SomeLayoutBinding binding = SomeLayoutBinding.bind(someLayoutRoot /* should be a View instance */);
Na przykład, jeśli chciałbyś użyć klasy wiążącej we fragmencie, wyglądałoby to mniej więcej tak.
Kotlina:
classSomeFragment : Fragment(R.layout.some_layout) {
//Lazy initialization means bind() won't be called until "binding" is referenced.
private val binding by lazy { SomeLayoutBinding.bind(view) }
override fun onViewCreated(view: View, savedInstanceState: Bundle?){
super.onViewCreated(view, savedInstanceState)
//Once this method is called, you can start using the binding.
}
}
Jawa:
publicclassSomeFragmentextendsFragment{
private SomeLayoutBinding binding = null;publicSomeFragment(){
super(R.layout.some_layout);
}
@Override
publicvoidonViewCreated(View view, Bundle savedInstanceState){
super.onViewCreated(view, savedInstanceState);
//Initialize the binding.
binding = SomeLayoutBinding.bind(view);
}
}
Tworzenie instancji z nowym widokiem
Klasa wiążąca może również zająć się powiększeniem układu za Ciebie.
Kotlina:
val binding = SomeLayoutBinding.inflate(layoutInflater /* should be a LayoutInflater instance */)
Jawa:
SomeLayoutBinding binding = SomeLayoutBinding.inflate(layoutInflater /* should be a LayoutInflater instance */);
Ta metoda jest przydatna zarówno w przypadku fragmentów, jak i działań.
Jakiś przykładowy fragment wyglądałoby mniej więcej tak.
Kotlina:
classSomeFragment : Fragment() {
private val binding by lazy { SomeLayoutBinding.inflate(LayoutInflater.from(requireContext())) }
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?){
//The "root" of the binding class is the root of its layout.
return binding.root
}
}
Jawa:
publicclassSomeFragmentextendsFragment{
private SomeLayoutBinding binding = null;
@Override
publicvoidonCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
//Initialize the binding.
binding = SomeLayoutBinding.inflate(inflater);
//The "getRoot()" method of the binding class returns the root of the layout.
return binding.getRoot();
}
}
Jakiś przykładowa aktywność wyglądałoby mniej więcej tak.
Kotlina:
classSomeActivity : AppCompatActivity() {
private val binding by lazy { SomeLayoutBinding.inflate(layoutInflater) }override fun onCreate(savedInstanceState: Bundle?){
super.onCreate(savedInstanceState)
//This is equivalent to calling "setContentView(R.layout.some_layout)" but allows use of the binding class.
setContentView(binding.root)
}
}
Jawa:
publicclassSomeActivityextendsAppCompatActivity{
private SomeLayoutBinding binding = null;@Override
protectedvoidonCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
//Instantiate the binding.
binding = SomeLayoutBinding.inflate(getLayoutInflater());
//This is equivalent to calling "setContentView(R.layout.some_layout)" but allows use of the binding class.
setContentView(binding.getRoot());
}
}
Odwoływanie się do widoków
Teraz, gdy klasa powiązania widoku jest skonfigurowana i gotowa do użycia, czas zacząć z niej korzystać.
Powiedzmy, że zawartość some_layout.xml
są mniej więcej takie:
android:
...>
android:
...
/>
android:
...
/>
android:
...>
android:
...
/>
LinearLayout>
LinearLayout>
Istnieje wiele identyfikatorów, do których można się odwołać w kodzie. Ale dopóki utworzona zostanie instancja klasy wiążącej, odwoływanie się będzie łatwe.
W Kotlinie do widoków odwołują się zmienne pasujące do ich identyfikatorów, z pewnymi zmianami. Podkreślenia są usuwane, a powstały ciąg znaków jest umieszczany w wielkości liter wielbłądziej. Na przykład, aby odnieść się some_frame_layout
z kodu, którego byś użył binding.someFrameLayout
. The someFrameLayout
zmienna będzie instancją FrameLayout.
val someFrameLayout: FrameLayout = binding.someFrameLayout
W Javie do widoków odwołują się metody pobierające pasujące do ich identyfikatorów, w formacie podobnym do Kotlina. Na przykład, aby odnieść się some_frame_layout
, użyłbyś binding.getSomeFrameLayout()
. Metoda zwróci instancję FrameLayout.
FrameLayout someFrameLayout = binding.getSomeFrameLayout();
Odniesienia do widoku są również spłaszczone w powiązaniu. Odwoływanie się inner_imageview
jest tym samym, co odwoływanie się some_frame_layout
.
Wniosek
Jak z pewnością widzisz, View Binding w Androidzie jest zarówno łatwe do wdrożenia, jak i łatwe w użyciu. W wielu przypadkach jest łatwiejszy w użyciu niż findViewById()
.
Aby uzyskać więcej szczegółów na temat implementacji View Binding, wraz z kilkoma przykładami, sprawdź oficjalną dokumentację Google.