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.
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!