ButterKnife for Open Event Android

Open Event Android, by FOSSASIA has been coded in a very clean and systematic manner. One of the great things used in it is the ButterKnife library. It has made increased the readability and understand ability of the app’s code.

ButterKnife, developed and maintained by Jake Wharton(Square Inc.) is an Android library designed to make Java code less complex and efficient. The library operates with the use of annotations and hence, binds classes to the relevant annotations in Java and do the job.

First off, here’s the very first thing that you want to do before starting to use ButterKnife — Adding it’s dependency in the build.gradle file of your project.

compile 'com.jakewharton:butterknife:8.6.0
annotationProcessor 'com.jakewharton:butterknife-compiler:8.6.0'

At FOSSASIA, we have extensively used this amazing library to simplify the code for our Open Event Android application. I hope this blog will help newcomers in understanding our code base in a better way.

We have the famous @Bindview annotation by ButterKnife to bind views to Android components without having to call R.FindViewById() method for every view. The following is a code sample from Open Event Android about the same.

@BindView(R.id.toolbar) Toolbar toolbar;

@BindView(R.id.nav_view) NavigationView navigationView;

@BindView(R.id.progress) ProgressBar downloadProgress;

@BindView(R.id.layout_main) CoordinatorLayout mainFrame;

@BindView(R.id.drawer) DrawerLayout drawerLayout;

@BindView(R.id.appbar) AppBarLayout appBarLayout;

Similarly, the ButterKnife library also handles events in an Android application and has annotations like @onClick, @onLongClick among others. So while using ButterKnife for an event, choose the appropriate event and the corresponding annotation followed by the Java method that is to be executed. Here is an example for the same.

@OnClick(R.id.submit)

public void submit(View view) {

// TODO submit data to server...

}

The ButterKnife library also helps to bind resources in your project.

It simplifies the View holder pattern inside a list adapter as illustrated in the following example.

public class MyAdapter extends BaseAdapter {

@Override public View getView(int position, View view, ViewGroup parent) {

   ViewHolder holder;

   if (view != null) {

     holder = (ViewHolder) view.getTag();

   } else {

     view = inflater.inflate(R.layout.whatever, parent, false);

     holder = new ViewHolder(view);

     view.setTag(holder);

   }

   holder.name.setText("John Doe");

   // etc...

   return view;

 }

static class ViewHolder {

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

   @BindView(R.id.job_title) TextView jobTitle;

   public ViewHolder(View view) {

     ButterKnife.bind(this, view);

   }

 }

}

The above code sample has been taken from http://jakewharton.github.io/butterknife/ and you can visit the site for further in-depth knowledge on ButterKnife.

How ButterKnife works?

I will be talking a bit about the working of the ButterKnife library. Firstly, I would like to introduce annotations concept in Java briefly before proceeding.

“In the Java, computer programming language, an annotation is a form of syntactic metadata that can be added to Javasource code. Classes, methods, variables, parameters and packages may be annotated.” As it is rightly said, Annotations can be of various uses like Getting information for the compiler, Compile-time and deployment-time processing, Runtime processing. However, please note that annotations can NOT modify and edit the existing classes. They can simply make more classes.

With this, I’m gonna continue on the working of ButterKnife. From the above discussion it must be clear now that ButterKnife is not changing any of our classes. It makes new classes to handle the code.

ButterKnife goes through all the files in your project and identifies the ButterKnife annotations used, if any. It then creates new classes for every annotation encountered, based on the annotations used. These new classes contain the general methods that would have been used in a project without ButterKnife. When we finally call ButterKnife.inject(this) , the inject()of all the new classes made by ButterKnife are called which then perform the desired function during execution.

Finally, try to go through the complete documentation for Butterknife and Java annotations for more information.