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 *