View Binding w/Android
View Binding Purposes?
note: View binding is a feature that allows you to more easily write code that interacts with views. Once view binding is enabled in a module, it generates a binding class for each XML layout file present in that module. An instance of a binding class contains direct references to all views that have an ID in the corresponding layout.
View Binding is part of Android Jetpack. View Binding was introduced at the Android Talk at Google IO/19. Let’s learn more about this. In most cases, view binging replaces findViewById. Ultimately the findViewById, is used to declare the view variable for x times to use it. It makes a lot of boilerplate code inside the view Activity/Fragment. That is why View Binding came to provide a good way to access all views with onlu init one variable.
Key features
- ViewBinding is always null safe and type-safe, which supports both Java and Kotlin.
- ViewBinding is introduced in the Gradle version 3.6 and above (which comes with the Android Studio 4.0, only gradle 3.6).
- ViewBinding also helps to reduce the boilerplate code, hence reducing the code redundancy.
- While using the ViewBinding proper naming conventions are need to be followed because it creates the binding class internally using the name of the same layout file. Naming the layout file in the snake case is preferred. For Example, the ViewBinding creates activity_main.xml(snake case) file as ActivityMainBinding(pascal case), which contains all the property and instances of all the views containing in that layout.
- And also whatever IDs of all elements are created inside the layout XML file, the ViewBinding converts them to camel case. For example: android:id=”button_submit” -> buttonSubmit. Which is much useful in the code readability.
- Using ViewBinding the compilation of the code is a bit faster as compared to the traditional findViewById() method.
- The ActivityMainBinding class is generated in the following path under the project hierarchy this can be viewed.
Before View Binding
class MainActivity: AppCompatActivity() {
val btnSignIn = findViewById<AppCompatButton>(R.id.btn_signIn)
val txtUserStatus = findViewById<AppCompatTextView>(R.id.tv_userStatus)
txtUserStatus?.Text = userProfile?.overview
btnSignIn?.setOnClickListener {
Snackbar sb = Snackbar.make(cl, "Successfully login attempt", Snackbar.LENGTH_SHORT);
sb.show();
}
}
After View Binding
class MainActivity: AppCompatActivity() {
val binding = ActivityMainBinding.inflate(layoutInflater)
binding.tv_UserStatus.text = userProfile?.overview
binding.btnSignIn.setOnClickListener {
Snackbar sb = Snackbar.make(cl, "Login Attempt Successful", Snackbar.LENGTH_SHORT);
sb.show();
}
}
Why View Binding
If you review the to above code clip you can notice a bit of the differences. For exmple you declare the binding variable from the generated view binding class. Now you can access all the view ids from the binding variable. The main advantages of using View Binding:
- Type Safety
- View binding provide a generated method od the same type as defined in the XML layout.
- Null Safety
- findViewById
Using View Binding
- enable viewBinding and this should take place with build.gradle
buildFeatures {
viewBinding = true
}
- After enabling viewBinding perform the sync and let’s modify the XML layout
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/cl_layer"
tools:context=".MainActivity"
tools:ignore="">
<androidx.appcompat.widget.AppCompatTextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/tv_header"
android:text="View Binding w/Kotlin"
android:textSize="30dp"
android:textAlignment="center"
android:layout_marginStart="15dp"
android:layout_marginTop="150dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
/>
<androidx.appcompat.widget.AppCompatEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/et_message"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:layout_marginTop="128dp"
android:hint="Sir, your text here"
app:layout_constraintEnd_toEndOf="@id/tv_header"
app:layout_constraintStart_toStartOf="@id/tv_header"
app:layout_constraintTop_toBottomOf="@id/tv_header" />
<androidx.appcompat.widget.AppCompatButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/btn_submit"
android:layout_marginTop="16dp"
android:text="Submit"
app:layout_constraintEnd_toEndOf="@id/et_message"
app:layout_constraintTop_toBottomOf="@id/et_message" />
</androidx.constraintlayout.widget.ConstraintLayout>
PS: If your view id uses the under_score, it will be generated as a camelCase variable.
- The things that need to be focused on here are, creating the instance of the ViewBinding.
Kotlin
class MainActivity : AppCompatActivity() {
//create instance ActivityMainBinding
private lateinit var amb : ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
//create the instance of ActivityMainBinding
val binding = ActivityMainBinding.inflate(layoutInflater)
//binding.root returns the root layout
setContentView(binding.root)
binding.btnSubmit.setOnClickListener {
val msg = binding.etMessage.text.toString()
if (!msg.isEmpty()) Snackbar.make(binding.clLayer, binding.etMessage.text.toString(), Snackbar.LENGTH_SHORT).show()
else Snackbar.make(binding.clLayer, "Message is currently empty", Snackbar.LENGTH_SHORT).show()
}
}
}
Java
public class MainActivity extends AppCompatActivity {
//binding class to the xml
//allows the system to automatically generate the system
ActivityMainBinding amb;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//inflating the xml
amb = ActivityMainBinding.inflate(getLayoutInflater());
//retrieve the root layout
View v = amb.getRoot();
//ContentView for the layout
setContentView(v);
//calling the button and setting the click listener
//call the button by id and set the click listener
amb.btnSubmit.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String msg = amb.etMessage.getText().toString();
if (!msg.isEmpty()) Snackbar.make(amb.clLayer, amb.etMessage.getText().toString(), Snackbar.LENGTH_SHORT).show();
else Snackbar.make(amb.clLayer, "Message is empty", Snackbar.LENGTH_SHORT).show();
}
});
}
}
And that’s it. You are done setting up your view using View Binding.
if youre interested in seeing a tutorial on the topic check it out here:
- Published in Android, Java, Kotlin, Programming Languages
Oh, I need A Splash Screen, Right?
If you have had any smart phone before the I am sure you have seen a splash screen before. If you have not then for your information a spalsh screen is a screen that displays when you first open an app on the device. Many developer may refers to this as a launch screen and displays when that app is loading after being opened. When this loading process has completed, it transitions to a different screen where actual actions can be performed.
If you have noticed these splash sceen you most definitely noticed that they tend to only display for a short time and then its gone. Personally I feel that the splash screen is pretty vital part to any application since it is the user’s first impression/experience with the application.
Implementing Splash Screens
There are technically two ways to implement a splash screen.
Using a Timer (Get It Together)
This is the old easy approach. You have to create a dedicated splash screen Activity that shows up for x seconds then opens the appropriate activity. You get more flexibility here as you can add animations, custom views or any other element you can normally fit into an Activity layout. A very basic implementation of this is below
class SplashActivity : AppCompatActivity() {
//setting the timer for the activity
private val SPLASH_TIMER:Long = 5000 // this equates to seconds
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_splash)
//fire after timer expires
timedSplashScreen()
}
private fun timedSplashScreen() {
Handler().postDelayed({
//start the main activity
startActivity(Intent(this, MainActivity::class.java))
}, SPLASH_TIMER)
}
}
Advantages:
- You can display awesome animation or some custom design that has been built. For example, the development of games.
- perform alternative activities on the splash screen
Disadvantages
- the launcher activity doesn’t show up immediately
- this is even worst during a cold start
- additionally, during cold start the user is stuck looking at the
windowBackground- afterward, the user still waits until the splash screen time expires before the app content
- Don’t expect the animation to wow your user every time
Using a Smart Timer (Get It Together)
This is very similar to the timer method listed above. The difference here is rather than make the delay be fixed, you vary it based on whether this is the user’s first time launching the app or not. We can accomplish this by using the SharedPreferences.
class SmartSplashActvity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_smart_splash_actvity)
splashScreenKey()
}
private fun splashScreenKey() {
val sp = getPreferences(MODE_PRIVATE)
val firstLaunchPrefKey = "pref_first_launch"
val splashDuration = when (sp.getBoolean(firstLaunchPrefKey, true)) {
true -> {
//
sp.edit().putBoolean(firstLaunchPrefKey, false).apply()
5000
}
false -> {
//
10000
}
}
splashScreenDuration(splashDuration)
}
private fun splashScreenDuration(splashDuration: Int) {
Handler().postDelayed({
startActivity(Intent(this, MainActivity::class.java))
}, splashDuration.toLong())
}
}
Advantages:
- All the advantages that timer accomplished
- this method could aid in getting to the content quicker to the user.
Disadvantages
- all the disadvantages that exist for timer method
Splash Screen Best Practice
Now doing what needs to be done the right way. When the app is launched and has been in the memory yet, there is a delay between when the user started your app and when the launcher Activity’s onCreate() is called. During this what we call a “cold start”, the window manager tries to draw a UI placeholder using elements from the theme.xml. The key is creating a custom theme that overrides windowBackground, then replacing that custom theme with your standard theme before calling super.onCreate() in the activity.
class DedicatedSplashScreen : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
startActivity(Intent(this, MainActivity::class.java))
finish()
}
}
- Keep it free from unnecessary distraction
- Don’t use multiple colors or logos
- Use animation sparingly
Splash screens are simple. They’re used to enhance a brand and give users something nice to look at as they wait. .
- Published in Android, Kotlin, Programming Languages, Tutorial


