Android – Get more out of Butter Knife

By -

I have played a role in many android applications, whether it could be company projects or open source projects. Believing in knowledge sharing and expertise, I have also contributed into couple of projects of community members, by providing mentorship!

During my involvement in all of these projects, I have observed most of the android developers are using Butter Knife library for only injecting views.

Butter Knife - logo

Butter Knife – logo

In this post

As I said I have found most of the android developers are using Butter Knife either for binding views by using @Bind or defining click listeners by @OnClick annotations. But in this part, I will share about more features and functionalities which Butter Knife provides and there by we can reduce boilerplate code as much as possible in Android.

Butter Knife

Butter Knife is a popular view injection library created and open sourced by Jake Wharton.

In simpler words, Butter knife allows you to annotate the inflation of your views and OnClickListeners so that you can get back to writing the code that really matters.

compile 'com.jakewharton:butterknife:7.0.1'

Important
Butter Knife uses compile time annotations and so not generating any overhead at run-time. Instead of slow reflection or generating views at run-time, it actually creates required code ahead of time. So It doesn’t cause any performance issues or slow down your application!

Regular Usage

Bind views and implementing onclicklistener for the particular views

As I said, mostly I have found developers using @Bind and @OnClick annotations of Butter Knife library.

class LetsNurtureDemoActivity extends Activity {
   
  @Bind(R.id.edUserName) EditText edUserName;
  @Bind(R.id.edPassword) EditText edPassword;
  @Bind(R.id.instructions) TextView txtInstructions;
 
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.demo_activity);
    ButterKnife.bind(this);
  }
 
  @OnClick(R.id.btnLogin)
  public void btnLoginClick(View view) { 
    .....
    .....
    .....
   }
}

More usages

Below are some of the features provided by Butter Knife but as I said I haven’t seen that it is being used by most of the android developers, but these are the good features provided in Butter Knife library itself so I hope you will start using it!

1. Common listener for multiple views

@OnClick({ R.id.button1, R.id.button2, R.id.button2 })
public void buttonClicks(View view) {
 
        switch(view.getId()) {
            case R.id.button1:
        Toast.makeText(this, "Button1 clicked!", LENGTH_SHORT).show();
                break;
             
        case R.id.button1:
        Toast.makeText(this, "Button2 Clicked!", LENGTH_SHORT).show();                
        break;
 
            case R.id.button1:
        Toast.makeText(this, "Button3 clicked!", LENGTH_SHORT).show();
                break;
             
        }
}

2. More listeners attachment

  @OnLongClick(R.id.hello) boolean sayGetOffMe() {
    Toast.makeText(this, "Let go of me!", LENGTH_SHORT).show();
    return true;
  }
 
  @OnItemClick(R.id.list_of_things) void onItemClick(int position) {
    Toast.makeText(this, "You clicked: " + adapter.getItem(position), LENGTH_SHORT).show();
  }
 
    @OnItemSelected({R.id.spinnerCountry}) 
    void onItemSelected(Spinner spinner, int position) { 
        
    } 
  
    @OnItemSelected(value=R.id.spinnerCountry, callback = OnItemSelected.Callback.NOTHING_SELECTED) 
    void onNothingSelected() { 
  
    } 

Same way you can add below listeners to the views:

@OnLongClick
@OnPageChange
OnPageChange.Callback
@OnTextChanged
OnTextChanged.Callback
@OnTouch
@OnItemLongClick
@OnCheckedChanged

3. Bind resources

This is one of the good feature Butter knife provides. Same as we can eliminate findViewById by using @Bind annotation, It also allows us to bind colors, dimens, string, drawable, etc. resources.

class ExampleActivity extends Activity {
 @BindColor(R.color.red) int red; 
  @BindString(R.string.activity_title) String activityTitle;
   @BindDimen(R.dimen.btn_horizontal_margin_common) Float btnHorizontalMarginCommon;
  @BindDrawable(R.drawable.ic_instructions) Drawable iconInstructions;
}

4. Group multiple views into a List or Array

Bind({ R.id.first_name, R.id.middle_name, R.id.last_name })
List<EditText> nameViews;

The apply method allows you to act on all the views in a list at once.

ButterKnife.apply(nameViews, DISABLE);
ButterKnife.apply(nameViews, ENABLED, false);

Action and Setter interfaces allow specifying simple behavior.

static final ButterKnife.Action<View> DISABLE = new ButterKnife.Action<View>() {
  @Override public void apply(View view, int index) {
    view.setEnabled(false);
  }
};
 
static final ButterKnife.Setter<View, Boolean> ENABLED = new ButterKnife.Setter<View, Boolean>() {
  @Override public void set(View view, Boolean value, int index) {
    view.setEnabled(value);
  }
};

5. Setting View Properties

An Android Property can also be used with the apply method.

ButterKnife.apply(nameViews, View.ALPHA, 0.0f);

6. ButterKnife.findById to find views particularly

Butter knife has included findById methods which simplify code that still has to find views on a View, Activity, or Dialog. It uses generics to infer the return type and automatically performs the cast.

View view = LayoutInflater.from(context).inflate(R.layout.thing, null);
TextView firstName = ButterKnife.findById(view, R.id.first_name);
TextView lastName = ButterKnife.findById(view, R.id.last_name);
ImageView photo = ButterKnife.findById(view, R.id.photo);

Add a static import for ButterKnife.findById and enjoy even more fun.

7. @Nullable annotation

It will throw exception if the target view can not be found. To indicate that the field may not be present in the layout, use any variant of the @Nullable annotation.

@Nullable  @Bind(R.id.edUserName) 
EditText edUserName;

Until I write next post

This has brought us to the end of this article, I hope you got to learn more usages of Butter knife. Please feel free to share if you have liked this article or any comments, if any!

Resources

Paresh Mayani

Lazy android developer, exploring the horizon of android development since 7 years. He is Technical Lead - Android at Lets Nurture, India. He is also Application Architect at KarConnect. He is the Head/Organizer of Google Developers Group (GDG), Ahmedabad

Loading Facebook Comments ...
Loading Disqus Comments ...