Skip to main content

Butter Knife View Library for Android


Android ButterKnife library is a view injection library that injects views into android activity / fragments using annotations. For example, @BindView annotation avoids using findViewById() method by automatically type casting the view element.

Not just view binding, butterknife provides lot of other useful options like binding stringsdimensdrawablesclick events and lot more. 


1. Adding ButterKnife Dependency

First thing you have to do is, add ButterKnife in your project by adding the below dependencies in your project’s app/build.gradle file. Once added, sync your project, you are good to go.

android {
  ...
  // Butterknife requires Java 8.
  compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
  }
}

dependencies {
  implementation 'com.jakewharton:butterknife:10.2.2'
  annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.2'
}

2. Basic Usage Once the dependency is added, all the butterknife annotations will be available to import. To begin with, we’ll see how to use @BindView and @OnClick annotations. Let’s say you have the below layout for your activity that has a TextView and a Button. <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center_horizontal" android:orientation="vertical"> <TextView android:id="@+id/lbl_title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Enter your email" android:textAllCaps="true" /> <EditText android:id="@+id/input_name" android:layout_width="match_parent" android:layout_height="wrap_content" /> <Button android:id="@+id/btn_enter" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="@dimen/dimen_20" android:text="@string/enter" /> </LinearLayout>

To make the views available in the activity, we need to follow the below steps. 1. Use @BindView along with the id (R.id.lbl_title) of the view while declaring the view variable. 2. Call ButterKnife.bind(this) in onCreate() method after setContentView() is called. That’s all, the view injection happens and no need to typecast the view variable using
findViewById() method anymore. Also you can see, the click event is attached just by
adding @OnClick annotation before the method.

public class MainActivity extends AppCompatActivity { @BindView(R.id.lbl_title) TextView lblTitle; @BindView(R.id.input_name) EditText inputName; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // bind the view using butterknife ButterKnife.bind(this); } @OnClick(R.id.btn_enter) public void onButtonClick(View view) { Toast.makeText(getApplicationContext(), "You Name is: " + inputName.getText().toString(), Toast.LENGTH_SHORT).show(); } }

3. Using in Fragments
Using view injection in Fragment is same as Activity except the ButterKnife.bind() method changes. In addition to target parameter, we need to pass inflated view as param. You will also have to use Unbinder to unbind the view in onDestroyView() becauseof the Life cycle methods of Fragment.low is the example usage of ButterKnife in Fragment. public class MyFragment extends Fragment { Unbinder unbinder; @BindView(R.id.lbl_name) TextView lblName; @BindView(R.id.btn_enter) Button btnEnter; @BindView(R.id.input_name) EditText inputName; public MyFragment() { // Required empty public constructor } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment View view = inflater.inflate (R.layout.fragment_my, container, false); // bind view using butter knife unbinder = ButterKnife.bind(this, view); return view; } @Override public void onDestroyView() { super.onDestroyView(); // unbind the view to free some memory unbinder.unbind(); } }


4. Using in List Adapter
ButterKnife also can be used in list adapters too. Below is the example of @BindView in recyclerview’s adapter class.
public class ContactsAdapter extends RecyclerView.Adapter<ContactsAdapter.MyViewHolder> { private List<Contact> contacts; public class MyViewHolder extends RecyclerView.ViewHolder { @BindView(R.id.name) TextView name; @BindView(R.id.mobile) TextView mobile; public MyViewHolder(View view) { super(view); // binding view ButterKnife.bind(this, view); } } public ContactsAdapter(List<Contact> contacts) { this.contacts = contacts; } @Override public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View itemView = LayoutInflater.from(parent.getContext()) .inflate(R.layout.contact_list_row, parent, false); return new MyViewHolder(itemView); } @Override public void onBindViewHolder(MyViewHolder holder, int position) { Contact contact = contacts.get(position); holder.name.setText(contact.getName()); holder.mobile.setText(contact.getMobile()); } @Override public int getItemCount() { return contacts.size(); } }

5. Using with Resources – Strings, Colors, Dimens, Drawables etc.,
In addition to binding view elements, you can also bind other resources like strings (@BindString), colors (@BindColor), dimensions (@BindDimen) and drawables (@BindDrawable). Below example demonstrates multiple annotations and their usage.

public class MainActivity extends AppCompatActivity { @BindView(R.id.logo) ImageView imgLogo; @BindView(R.id.lbl_title) TextView lblTitle; @BindDrawable(R.mipmap.ic_launcher) Drawable drawableLogo; @BindColor(R.color.colorPrimaryDark) int colorTitle; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // bind the view using butterknife ButterKnife.bind(this); // setting label color lblTitle.setTextColor(colorTitle); // displaying logo using drawable imgLogo.setImageDrawable(drawableLogo); } }
6. Adding Click Listener (Listener Binding)
We have already seen the example of @OnClick annotation, but below are variants of function params.

// click event with source view params @OnClick(R.id.btn_enter) public void onButtonClick(View view) { Toast.makeText(getApplicationContext(), "You have entered: " + inputName.getText().toString(), Toast.LENGTH_SHORT).show(); }
// click event without params @OnClick(R.id.btn_enter) public void onButtonClick() { Toast.makeText(getApplicationContext(), "You have entered: " + inputName.getText().toString(), Toast.LENGTH_SHORT).show(); } // click event with specific type param @OnClick(R.id.btn_enter) public void onButtonClick(Button button) { Toast.makeText(getApplicationContext(), "You have entered: " + inputName.getText().toString(), Toast.LENGTH_SHORT).show(); }

7. Grouping Multiple Views into List & applying action
There might be scenarios where in you want to apply some action on to group of views, like applying color, setting text or selecting all CheckBoxes at once. This can be done very easily using ButterKnife. All you have to do is, use @BindViews annotation to store all the views into a List and using ButterKnife.Action() method to apply some operations on to all views. In the below example, two actions are applied to group of TextViews. First, the text is set from an array of strings. Second, a color is applied to all the TextViews in the list.

public class MainActivity extends AppCompatActivity { @BindColor(R.color.colorPrimaryDark) int colorTitle; @BindViews({R.id.lbl1, R.id.lbl2, R.id.lbl3}) List<TextView> lblArray; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // bind the view using butterknife ButterKnife.bind(this); final String[] lblText = new String[]{"Cat", "Dog", "Rat"}; ButterKnife.Action<TextView> APPLY_TEXT = new ButterKnife.Action<TextView>() { @Override public void apply(TextView view, int index) { view.setText(lblText[index]); } }; // setting text to array of labels ButterKnife.apply(lblArray, APPLY_TEXT); // Applying color to group of labels ButterKnife.Action<TextView> APPLY_COLOR = new ButterKnife.Action<TextView>() { @Override public void apply(@NonNull TextView view, int index) { view.setTextColor(colorTitle); } }; ButterKnife.apply(lblArray, APPLY_COLOR); } } 8. Annotations Below are the list of annotations provided by ButterKnife and their usage.



Annotation



Description


@BindView


Binds view object. TextView, Button, Spinner or 

any view object


@BindView(R.id.logo)

ImageView imgLogo;



@BindViews


Binds array of views into List


@BindViews({R.id.lbl_name, 

R.id.lbl_email,

 R.id.lbl_address})

List<TextView> lblArray;




@BindDrawable


Binds drawable element. Loads the drawable 

image from res folder


@BindDrawable(R.mipmap.ic_

launcher)

Drawable drawableLogo;



@BindString


Binds string resource


@BindString(R.string.app_name)

String appName;



@BindColor



Binds color resource


@BindColor(R.color.colorPrimary

Dark)


int colorTitle;



@BindDimen



Binds dimen resource


@BindDimen(R.id.padding_hori)

float paddingHorizontal;



@BindAnim



Binds animation from anim resource


@BindAnim(R.anim.move_up)

Animation animMoveUp;




@BindBitmap



Binds bitmap object.


@BindBitmap(R.mipmap.ic_

launcher)

Bitmap logo;







@BindFloat



Binds float value


@BindFloat(R.dimen.radius)

float radius;



@BindInt


Binds int resource


@BindInt(R.integer.distance)

int distance;



I hope we have covered most of the ButterKnife features.

That's all folks !!

Comments

Popular posts from this blog

Android Logging using Timber Library

  Timber     is a logger with a small, extensible API which provides utility on top of Android's normal Log class. Before  the release, we’ll cleanup the log statements by removing them manually (even though logs can be disabled in release build). This tedious process can be avoided easily by using Timber. Timber provides lots of other options as well. Let’s see how it can be used in our projects to maintain the logs better. 1. Timber Below are few debug statements printed using default Log class. int a = 100 ; Log.e( "TAG" , String.format( "Integer a value is: %d" , a));   String name = "Android Codest" ; Log.e( "TAG" , String.format( "Find source from: %s" , name)); The above same statements can be printed using Timber as below. int a = 100 ; Timber.d( "Integer a value is: %d" , a);   String name = " Android Codest " ; Timber.d( " Find source from : %s" , name); You can notice here, the TAG is not p...

Convert your apk into Android App Bundle

Android App Bundle In Google I/O 2018, a new publishing format has been introduced for Android applications called Android App Bundle. It is a new upload format that includes all your app’s compiled code and resources, but defers APK generation and signing to Google Play. Traditionally, Android apps are distributed using a special file called an Android Package(.apk). How to build an app bundle? You can easily build your app bundle using Android Studio(3.2 Canary 14+) or using command line interface. The generated app bundle will be stored at app/build/outputs/bundle/buildVariant/bundle.aab. Android Studio : Go to Build > Build Bundle(s)/APK(s) and select Build Bundle(s). Console : ./gradlew bundle Dynamic Delivery with Split APKs A fundamental component of Dynamic Delivery is the split APK mechanism available on Android 5.0 (API level 21) and higher. Split APKs are very similar to regular APKs — they include compiled DEX bytecode, resources, and an Android manifest. However, the ...

Push Notification using Firebase in Android

This is a tutorial about sending push notifications to Android through Firebase, based on the new release of Firebase this year (2016). This tutorial shows how to setup the skeleton for sending and receiving push notifications via FCM with instructions on server code. 1. Get started Add a new project or import an existing project to  Firebase console . If you choose to create a new project, you need to set the project name and country. For example, I will call my project Firebase Notification Then select "Add Firebase to your Android app". Set a package name for your app. I only set my package name and omit the SHA-1 because I don't use Firebase for my app's authentication. Click the  ADD APP  button here to download google-services.json. This is an important file and you will need to put it into your app. 2. Add google-services.json to your app folder Replace the google-services.json in your app folder. The Google services plugi...