View Binding gör det enklare att skriva kod som interagerar med vyer. Så här ställer du in det i ditt Android Gradle-projekt.
De flesta Android-utvecklare är förmodligen bekanta med klassikern findViewById()
metod. Ge det ett ID för en av vyerna i din XML-layout och det kommer att returnera en referens till den uppblåsta versionen av den vyn. Det är allt förutsatt att du har passerat rätt ID och att vyn faktiskt existerar. findViewById()
har inga inbyggda kontroller som hindrar dig från att försöka hämta en vy som du inte kan hämta. Gå till View Binding.
Istället för att använda findViewById()
på varje vy du vill, genererar View Binding automatiskt en bindningsklass för varje layout-XML. Varje vy med ett ID läggs automatiskt till i klassen, så att du kan referera till dem direkt.
Att lägga till View Binding till ett Android Gradle-projekt är superenkelt.
Gradle-inställning
View Binding är aktiverat på modulnivå i Gradle. Om du har flera moduler måste du aktivera det individuellt för var och en.
I den android
block på din modulnivå build.gradle
, lägg till alternativet för att aktivera Visa bindning.
android {
...
buildFeatures {
viewBinding true
}
}
Det kan finnas en varning om olaglig åtkomst, men det är ett luddfel och kan säkert ignoreras.
Synkronisera projektet och View Binding kommer att aktiveras. Det är så enkelt.
Använda View Binding
Det finns några sätt att använda View Binding, men innan något av det händer, låt oss prata om hur bindningsklasserna genereras.
Syntax för klassnamn
Säg att du har en layout-XML som heter some_layout.xml
. Dess motsvarande bindningsklass kommer att namnges SomeLayoutBinding
. Det mönstret gäller för alla filer.
Varje ord (avgränsat med understreck i filnamnet) kommer att skrivas med versaler, och understrecket kommer att tas bort. "Bindning" läggs sedan till i slutet.
Instantierar med befintlig vy
Om du redan har blåst upp layoutfilen och du har en referens till roten av layouten, kan du tala om för View-bindningsklassen att använda den befintliga layouten.
Kotlin:
val binding = SomeLayoutBinding.bind(someLayoutRoot /* should be a View instance */)
Java:
SomeLayoutBinding binding = SomeLayoutBinding.bind(someLayoutRoot /* should be a View instance */);
Om du till exempel vill använda bindningsklassen i ett Fragment, skulle det se ut ungefär så här.
Kotlin:
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.
}
}
Java:
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);
}
}
Instantierar med New View
Bindningsklassen kan även ta hand om att blåsa upp layouten åt dig.
Kotlin:
val binding = SomeLayoutBinding.inflate(layoutInflater /* should be a LayoutInflater instance */)
Java:
SomeLayoutBinding binding = SomeLayoutBinding.inflate(layoutInflater /* should be a LayoutInflater instance */);
Denna metod är användbar i både fragment och aktiviteter.
En exempel Fragment skulle se ut ungefär som följande.
Kotlin:
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
}
}
Java:
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();
}
}
En exempel aktivitet skulle se ut ungefär som följande.
Kotlin:
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)
}
}
Java:
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());
}
}
Refererar till vyer
Nu när View-bindningsklassen är inställd och redo att användas, är det dags att faktiskt använda den.
Låt oss säga innehållet i some_layout.xml
är något i stil med följande:
android:
...>
android:
...
/>
android:
...
/>
android:
...>
android:
...
/>
LinearLayout>
LinearLayout>
Det finns många ID: n att referera till i koden. Men så länge du har den bindande klassen instansierad, blir det lätt att referera.
I Kotlin refereras till vyer av variabler som matchar deras ID, med vissa ändringar. Understreck tas bort och den resulterande strängen är kamelklädd. Till exempel för att referera some_frame_layout
från kod, skulle du använda binding.someFrameLayout
. De someFrameLayout
variabel kommer att vara en instans av FrameLayout.
val someFrameLayout: FrameLayout = binding.someFrameLayout
I Java refereras till vyer av getter-metoder som matchar deras ID: n, med ett liknande format som Kotlin. Till exempel för att referera some_frame_layout
, skulle du använda binding.getSomeFrameLayout()
. Metoden returnerar en instans av FrameLayout.
FrameLayout someFrameLayout = binding.getSomeFrameLayout();
View-referenserna är också tillplattade i bindningen. Refererar inner_imageview
är detsamma som att referera some_frame_layout
.
Slutsats
Som jag säkert kan se är View Binding i Android både lätt att implementera och lätt att använda. I många fall är det lättare att använda än findViewById()
.
För mer information om implementering av View Binding, tillsammans med några exempel, kolla in Googles officiella dokumentation.