Butterknife implementation in Android || Activity, Fragment, Adapter

 

ButterknifeĀ  :

Butterknife is used as bind the components from layout directly into code.In previous blog i have discussed Butter Knife usage but in this blog i will provide detailed code.

Butterknife makes the handling of components much easier than traditional way of handling them also this process makes it faster in populating data to views.

Add Dependency :

Add Butter Knife and Recycler View to your project

build.gradle (Project):

Add mavenCentral

repositories {
    .
    mavenCentral()
    .
}

 

in dependency add ButterKnife classpath

dependencies {
    .
    classpath 'com.jakewharton:butterknife-gradle-plugin:10.2.1'
    .
}

 

build.gradle (app):

Add compile options java version to ‘8′

android {
  
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}

 

Also please refer to the official site to know the latest version of dependency’s before starting this tutorial.

 

dependencies {

implementation com.jakewharton:butterknife:10.2.1

annotationProcessor com.jakewharton:butterknife-compiler:10.2.1

}

 

Project Structure :

This image depicts the usage of android butterknife project structure implementation.

butterknife android project structure

 

Let’s start coding

color.xml

<resources>
    <color name="colorPrimaryDark">#3700B3</color>
</resources>

dimen.xml

<resources>

    <dimen name="txtSize">20dp</dimen>

</resources>

activity_main.xml

Add UI components Edittext to take user input ans set it to Textview, Also add imageview to display a image using android butterknife, fragment container, checkboxes, and buttons to redirect views.

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
    tools:context=".MainActivity">

    <EditText
        android:id="@+id/edtInput"
        android:layout_width="196dp"
        android:layout_height="45dp"
        android:layout_marginTop="36dp"
        android:hint="user input..."
        android:maxLines="1"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.223"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/btnGo"
        android:layout_width="30dp"
        android:layout_height="30dp"
        android:layout_marginStart="124dp"
        android:layout_marginLeft="124dp"
        android:background="@android:drawable/ic_input_add"
        app:layout_constraintBottom_toTopOf="@+id/txtName"
        app:layout_constraintEnd_toStartOf="@+id/imgView"
        app:layout_constraintHorizontal_bias="0.008"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/edtInput"
        app:layout_constraintVertical_bias="0.389" />

    <TextView
        android:id="@+id/txtName"
        android:layout_width="197dp"
        android:layout_height="76dp"
        android:gravity="center|left"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.219"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/edtInput"
        app:layout_constraintVertical_bias="0.135" />

    <ImageView
        android:id="@+id/imgView"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_marginStart="32dp"
        android:layout_marginLeft="32dp"
        android:layout_marginTop="64dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintStart_toEndOf="@+id/edtInput"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/btnList"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginEnd="48dp"
        android:layout_marginRight="48dp"
        android:text="Recycle List"
        android:textAllCaps="false"
        app:layout_constraintBottom_toTopOf="@+id/container"
        app:layout_constraintEnd_toStartOf="@+id/btnFragment"
        app:layout_constraintHorizontal_bias="0.797"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/txtName"
        app:layout_constraintVertical_bias="0.191" />

    <Button
        android:id="@+id/btnFragment"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginEnd="72dp"
        android:layout_marginRight="72dp"
        android:text="Fragment Home"
        android:textAllCaps="false"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/btnList" />

    <FrameLayout
        android:id="@+id/container"
        android:layout_width="300dp"
        android:layout_height="200dp"
        app:layout_constraintBottom_toTopOf="@+id/termsCheck"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.495"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/btnFragment"
        app:layout_constraintVertical_bias="0.518" />

    <CheckBox
        android:id="@+id/termsCheck"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="36dp"
        android:onClick="check"
        android:text="I agree to terms and conditions"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.497"
        app:layout_constraintStart_toStartOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

 

MainActivity.java

Initialize android ButterKnife components by binding them as ButterKnife bind in MainActivity.

ButterKnife.bind(this);

 

then

@BindView(R.id.txtName)
TextView txtName;

@BindView(R.id.edtInput)
EditText edtInput;

@BindView(R.id.imgView)
ImageView imgView;

@BindView(R.id.btnGo)
Button btnGo;

@BindView(R.id.btnFragment)
Button btnFragment;

@BindView(R.id.btnList)
Button btnList;

@BindView(R.id.termsCheck)
CheckBox termsCheck;

 

now bind color, dimension value and drawable icon

@BindColor(R.color.colorAccent)
int accent;

@BindDimen(R.dimen.txtSize)
float txtSize;

@BindDrawable(R.drawable.logo)
Drawable logo;

 

set UI components

btnGo.setOnClickListener(this);
btnList.setOnClickListener(this);
btnFragment.setOnClickListener(this);

txtName.setTextSize(txtSize);
txtName.setTextColor(accent);

imgView.setImageDrawable(logo);

 

we can directly handle onClick listener in this way too using butterknife

@OnClick(R.id.termsCheck)
public void check(View view) {
    Toast.makeText(this,""+termsCheck.getText().toString(),Toast.LENGTH_SHORT).show();
}

 

import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentTransaction;

import com.abhishek.butterknife.RecyclerList.RecycleListActivity;

import butterknife.BindColor;
import butterknife.BindDimen;
import butterknife.BindDrawable;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {


    @BindView(R.id.txtName)
    TextView txtName;

    @BindView(R.id.edtInput)
    EditText edtInput;

    @BindView(R.id.imgView)
    ImageView imgView;

    @BindView(R.id.btnGo)
    Button btnGo;

    @BindView(R.id.btnFragment)
    Button btnFragment;

    @BindView(R.id.btnList)
    Button btnList;

    @BindView(R.id.termsCheck)
    CheckBox termsCheck;

    @BindColor(R.color.colorAccent)
    int accent;

    @BindDimen(R.dimen.txtSize)
    float txtSize;

    @BindDrawable(R.drawable.logo)
    Drawable logo;

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

        ButterKnife.bind(this);

        btnGo.setOnClickListener(this);
        btnList.setOnClickListener(this);
        btnFragment.setOnClickListener(this);

        txtName.setTextSize(txtSize);
        txtName.setTextColor(accent);

        imgView.setImageDrawable(logo);
    }

    @Override
    public void onClick(View v) {

        switch (v.getId()){

            case R.id.btnGo:
                txtName.setText(edtInput.getText().toString());
                break;

            case R.id.btnList:
                startActivity(new Intent(this, RecycleListActivity.class));
                break;

            case R.id.btnFragment:

                Fragment homeFragment = new HomeFragment();
                FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
                transaction.replace(R.id.container, homeFragment);
                transaction.addToBackStack(null);
                transaction.commit();
                break;

        }
    }

    // onClick using ButterKnife
    @OnClick(R.id.termsCheck)
    public void check(View view) {
        Toast.makeText(this,""+termsCheck.getText().toString(),Toast.LENGTH_SHORT).show();
    }
}

 

recycler_row.xml

Add a textview

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    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="wrap_content">

    <TextView
        android:id="@+id/txtRow"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="12dp"
        android:padding="10dp"
        android:text="text"
        android:textColor="@android:color/black"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.281"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />


</androidx.constraintlayout.widget.ConstraintLayout>

 

RecyclerAdapter.class

import com.abhishek.butterknife.R;

import java.util.ArrayList;

import butterknife.BindView;
import butterknife.ButterKnife;

public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.ViewHolder> {

    ArrayList<String> arrayList = new ArrayList<>();

    public RecyclerAdapter(ArrayList<String> arrayList) {
        this.arrayList = arrayList;
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {

         View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recyler_row,parent,false);
         ViewHolder viewHolder = new ViewHolder(view);


        return viewHolder;
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {

        holder.textView.setText(arrayList.get(position));
    }

    @Override
    public int getItemCount() {
        return arrayList.size();
    }

    public class ViewHolder extends RecyclerView.ViewHolder{

        @BindView(R.id.txtRow)
        public TextView textView;

        public ViewHolder(@NonNull View itemView) {
            super(itemView);

            ButterKnife.bind(this,itemView);
        }
    }
}

 

activity_recycle_list.xml

Add recycler view to layout

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</androidx.constraintlayout.widget.ConstraintLayout>

 

RecycleListActivity.java

Initialize butterknife

ButterKnife.bind(this);

 

@BindView(R.id.recyclerView)
RecyclerView recyclerView;

 

RecyclerView components and Arraylist

RecyclerView.Adapter recyclerAdapter;
RecyclerView.LayoutManager layoutManager;
ArrayList<String> names;

 

import android.os.Bundle;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.abhishek.butterknife.R;

import java.util.ArrayList;
import java.util.Arrays;

import butterknife.BindView;
import butterknife.ButterKnife;

public class RecycleListActivity extends AppCompatActivity {

    @BindView(R.id.recyclerView)
    RecyclerView recyclerView;

    RecyclerView.Adapter recyclerAdapter;
    RecyclerView.LayoutManager layoutManager;
    ArrayList<String> names;

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

        ButterKnife.bind(this);

        names = new ArrayList<>(Arrays.asList("Abhi", "Sam ", "Michal", "Perk", "John"));

        layoutManager = new LinearLayoutManager(this);
        recyclerView.setLayoutManager(layoutManager);

        recyclerAdapter = new RecyclerAdapter(names);
        recyclerView.setAdapter(recyclerAdapter);

    }
}

 

fragment_home.xml

<androidx.constraintlayout.widget.ConstraintLayout
    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">

    <TextView
        android:id="@+id/txtFragName"
        android:layout_width="145dp"
        android:layout_height="41dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

 

HomeFragment.class

Initialize butterknife in fragment as

ButterKnife.bind(this,view);

 

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;

import butterknife.BindView;
import butterknife.ButterKnife;

public class HomeFragment extends Fragment {

    @BindView(R.id.txtFragName)
    TextView textView;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

        View view = inflater.inflate(R.layout.fragment_home, container, false);

        ButterKnife.bind(this,view);

        textView.setText("Fragment Home");

        return view;
    }
}

Butterknife output :

In the view we have assigned a image from drawable folder using android butterknife android which can also be fetched from gallery to imageview, remaining buttons will show the flow of app where list is generated and binded using butterknife even in fragment the same.

 

If you are having any query’s on android butterknife implementation do let us know in the comment section below. If you like this tutorial do like and share us for more interesting updates.

Show Buttons
Hide Buttons
Read previous post:
Kotlin coroutines with retrofit || Kotlin Tutorial

  Kotlin Coroutine : Kotlin coroutine provide a safer way of asynchronous coding. A coroutine is light weight thread which...

Close