The Evolution of View Linking in Android

In this lesson, we will discuss The Evolution of View Linking in Android

The Android development environment has been based on three types of files since the beginning: XML, Kotlin, and Java. XML files contain everything related to design, and Kotlin/Java files include anything other than the design part.

Eventually, UI and business logic needed to be linked, and that’s what this article is all about. Let’s see how finding a view in the layout is evolved over the years.

To learn android course visit:android online training Blog.

findViewByID’

findViewByID is the first one in the line, and it was introduced in API Level 1 by the Android team. This function provides a view object as a return type and developers link this object to the view created in the View class.

Every view in Android is extended from the View class. Thus, all the views used in the XML layout, one way or another, extends to the View class. findViewByID returns an instance of that class.

class ExampleActivity extends Activity

{ TextView title;

TextView subtitle;

@Override public void onCreate(Bundle savedInstanceState)

{

super.onCreate(savedInstanceState);

setContentView(R.layout.simple_activity);

title = (TextView) findViewById(R.id.title)

subtitle = (TextView) findViewById(R.id.subtitle)

}}

Recently, the Android team made an enhancement to this function to overcome view casting. So the developers no longer need to cast the views while linking with findViewByID.

Despite the efforts to enhance findViewByID, many developers felt it wasn’t the best approach. So people started creating alternatives like Butter Knife, and at some point, the Android team came up with data binding (though its primary focus isn’t only to link the views).

Butter Knife

The Android Butter Knife library is a lightweight view0injection library that works on annotations. It was one of the first libraries that seemed to be a successful alternative to the traditional findViewByID.

It was created by Jake Wharton, and you can find the documentation on how to use Butter Knife on its official website. This library links the views from a layout using the@BindView annotation. For a while, developers used it as a sort of formal alternative to findViewByID. Let’s take a look at how to use it:

class ExampleActivity extends Activity

{

@BindView(R.id.title) TextView title;

@BindView(R.id.subtitle) TextView subtitle;

@Override public void onCreate(Bundle savedInstanceState)

{ super.onCreate(savedInstanceState);

setContentView(R.layout.simple_activity);

ButterKnife.bind(this);

}}

It’s almost similar to findViewByID; the only benefit for developers in terms of removing boilerplate code is that we don’t need to implement the declaration and initialization of the views separately.

Data Binding

The Data Binding Library is a support library that allows you to bind UI components in your layouts to data sources in your app using a declarative format, rather than programmatically.

The Data Binding Library generates binding classes for the layouts, which we can use in Android components like Activity and Fragment. Data binding is a sort of declarative solution with type and null safety.

To make a layout support data binding, we have to wrap the content of the file with the layout tag. This will generate a binding file of that layout with a reference to all of the views in it. Have a look:

<layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto">

<ConstraintLayout... /> <!-- UI layout's root element -->

</layout>

Once we’ve finished that part in the XML, a binding class will be generated, and we need to use it in the View class. This binding-file instance contains all of the views in the layout. Have a look:

override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState)

val binding: ActivityMainBinding = DataBindingUtil.setContentView(

this, R.layout.activity_main)

binding.tvName.text = "John"}

This seems to be a reasonable solution, but data binding is created to solve more complicated problems than just linking views, such as the layout file accessing Data classes to publish data from the XML itself and loading remote images using binding adapters.

These sort of things made Data Binding a complicated library to solve the view-linking problem. By nature, data binding is created to solve complicated issues because it creates a longer compile time and also errors are hard to understand.

Kotlin Synthetics

When Kotlin was introduced for Android development, it solved many problems, including view linking. Kotlin Extensions is a plugin by the Kotlin team. It eliminates the need to use findViewById in your code.

With the help of Kotlin Extensions, synthetic code came into existence in Android, which solves the view-linking problem in Android without using findViewByID. Unlike other libraries here, we can use the ID of the view directly in class files.

Kotlin synthetics invokes thefindViewById function the first time and then caches the view instances in a HashMap by default. This cache configuration can be changed to SparseArray or no cache via the Gradle settings.

Kotlin synthetics is one of the best approaches — it’s type-safe, and we can use the IDs directly from the layout. By using the ? operator from Kotlin, we can make this process null-safe.

Apart from the benefits, we have a problem here — if we use an ID of the view, Android Studio shows autocomplete, even if the layout that’s inflated is different from the one that has the view you’re trying toaccess. In such cases, if you don’t use the ? operator, your app will crash.

override fun onCreate(savedInstanceState: Bundle?)

{

super.onCreate(savedInstanceState)

setContentView(R.layout.activity_main)

tv_name?.text = "John"}

View Binding

Finally ViewBinding, is an official solution to link views to class files. The idea behind ViewBinding is to create a binding class for every layout that holds the references of the views in the layout. This reduces boilerplate code in your components (Activity and Fragment), and we can access views by creating an instance to that class.

With view binding, you no longer need to do the null check on a view while performing actions on it, just like in data binding. As the binding class generated directly from the layout file, it only contains the views within the layout.

Type-safety is one of the most significant advantages in view binding. If you try to assign a text watcher to a button, it won’t accept it because the Binding class contains the reference with appropriate view types.

View binding’s sole purpose is to replace the use of findviewbyId. Unlike data binding, it’s lightweight so it won’t take much time for compilation.

class MainActivity : AppCompatActivity()

{

private lateinit var activityMainBinding: ActivityMainBinding override fun onCreate(savedInstanceState: Bundle?)

{

super.onCreate(savedInstanceState)

activityMainBinding = ActivityMainBinding.inflate(layoutInflater)

val rootView = activityMainBinding.root

setContentView(rootView)

}

}

Bonus

To learn more about Android advanced development, visit the following tutorials Blog:

android app development course

Comments

Popular posts from this blog

Android App Project Package Structure (Android Studio)

ImageView and ImageButton in Android

Developing Android unit and instrumentation tests - Tutorial