Inject Views on Android

Have you ever get irritated by the unlimited number of findViewById method calls and complex on-click-listeners? Obviously, they increase the complexity of the code and they consume more time as well. Butter Knife is a perfect solution to get out of these irritating and time-consuming code segments.

Butter Knife is an injection library used to inject views into Java classes. Using this library is not going to reduce the performance since it uses compile-time injection instead of runtime injection. Compared to some other Android libraries and frameworks, it is less featured but personally, I like this library a lot for its less configuration and high performance. This article introduces the basic functionalities of Butter Knife and more details can be found at the official website.


Let's create a simple application with a TextBox and a Button to demonstrate the application of Butter Knife.
Step 1:
Create a new Android project “Butter Knife Demo”.

Step 2:
Create a TextBox and a Button in the activity_main.xml.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">


    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/etName"
        android:hint="Enter your name..."
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="183dp" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="OK"
        android:id="@+id/btnOK"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="121dp" />
</RelativeLayout>

Step 3:
Add the Butter Knife dependency to the build.gradle (Module:app).


compile 'com.jakewharton:butterknife:6.1.0'

After the modification, the build.gradle must look like this.
apply plugin: 'com.android.application'

android {
    compileSdkVersion 21
    buildToolsVersion "21.1.2"

    defaultConfig {
        applicationId "com.javahelps.butterknifedemo"
        minSdkVersion 10
        targetSdkVersion 22
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    compile 'com.android.support:appcompat-v7:22.1.1'
    compile 'com.jakewharton:butterknife:6.1.0'
}

After saving this file, synchronize the Gradle build.


Step 4:
Add an instance variable for EditText in the MainActivity.java. This instance variable should not be private or static if you are willing to inject it using Butter Knife.
package com.javahelps.butterknifedemo;

import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.widget.EditText;


public class MainActivity extends ActionBarActivity {
    EditText etName;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}


Step 5:
Annotate the instance variable using @InjectView(int) annotation as shown below.
package com.javahelps.butterknifedemo;

import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.widget.EditText;

import butterknife.InjectView;


public class MainActivity extends ActionBarActivity {
    @InjectView(R.id.etName)
    EditText etName;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}

Step 6:
Create a method for on click as shown below.
public void showName() {
    String name = etName.getText().toString();
    Toast.makeText(this, name, Toast.LENGTH_SHORT).show();
}

Step 7:
Annotate the method using @OnClick annotation to bind it with the button click.
@OnClick(R.id.btnOK)
public void showName() {
    String name = etName.getText().toString();
    Toast.makeText(this, name, Toast.LENGTH_SHORT).show();
}

Step 8:
Finally, call the 'inject(Activity)' method of ButterKnife class from the onCreate method.
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    ButterKnife.inject(this);
}

The final source code should be something similar to this code:
package com.javahelps.butterknifedemo;

import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.widget.EditText;
import android.widget.Toast;

import butterknife.ButterKnife;
import butterknife.InjectView;
import butterknife.OnClick;


public class MainActivity extends ActionBarActivity {
    @InjectView(R.id.etName)
    EditText etName;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.inject(this);
    }

    @OnClick(R.id.btnOK)
    public void showName() {
        String name = etName.getText().toString();
        Toast.makeText(this, name, Toast.LENGTH_SHORT).show();
    }
}

Here you can see that there are no findViewById method calls and no on-click listeners. The code looks pretty simple and easy to read.

Step 9:
Save all the changes and run the application.


Find the project at Git Hub.
Previous
Next Post »

Contact Form

Name

Email *

Message *