rakuishi.com

Android: ButterKnife で findViewById, setOnClickListener をシンプルに書く

レイアウト XML に書いた id を findViewById で紐付けたり、ボタンが押されたアクションを使う時に setOnClickListener すると、割とコードがごちゃごちゃしてしまう。

そんな時、ビューインジェクションライブラリ Butter Knife を使うとシンプルに書けます。この記事では、Butter Knife で出来ることをさくっと紹介します。

findViewById

以下のように、@InjectView して、onCreate() 内にて、ButterKnife.inject() をすれば、mButton が紐付いた状態になります。onCreate() 内で紐付けるよりもぱっと見わかりやすいです。

public class MainActivity extends Activity {

    @InjectView(R.id.main_button) Button mButton;

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

Fragment で使う場合は、LayoutInflater から View を作る時に、ButterKnife.inject() すれば OK です。

public class MainFragment extends Fragment {

    @InjectView(R.id.main_button) Button mButton;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View parentView = inflater.inflate(R.layout.fragment_main, container, false);
        ButterKnife.inject(this, parentView);
        return parentView;
    }
}

Listener

setOnClickListener する時は、以下のように書けます。findViewById(R.id.button) してからリスナーを紐付ける面倒な手順を踏む必要はありません。

@OnClick(R.id.button)
void onClickButton(Button button) {
    // ...
}

複数のボタンに同じアクションを紐付ける時は、配列形式で宣言できます。このボタン類を getId() して処理を分岐する時に使えます。

@OnClick({R.id.button_1, R.id.button_2, R.id.button_3})
void onClickButton(Button button) {
    // ...
}

ListView が選択された時のリスナーは、次のように書けます。

@OnItemClick(R.id.listview)
void itemClick(AdapterView<?> adapter, View view, int pos, long id) {
    // ...
}

ViewHolder

ListView で使う ViewHolder パターンも、Butter Knife を使えば効率的に書けます。

public class MyAdapter extends BaseAdapter {

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        ViewHolder holder;
        if (convertView == null) {
            convertView = mInflater.inflate(R.layout.list_item, parent, false);
            holder = new ViewHolder(convertView);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder)convertView.getTag();
        }

        // ...

        return convertView;
    }

    static class ViewHolder {
        @InjectView(R.id.list_item_title)     TextView titleView;
        @InjectView(R.id.list_item_thumbnail) ImageView thumbnailView;

        public ViewHolder(View view) {
            ButterKnife.inject(this, view);
        }
    }
}

Butter Knife の導入方法

Android Studio を使っていれば、build.gradle ファイルに一行追加するだけです。

dependencies {
    compile 'com.jakewharton:butterknife:6.0.0'
}

Android Annotation と比べて

以前は、Butter Knife よりも機能が豊富な Android Annotation を使っていたのですが、以下の理由で Butter Knife に乗り換えました。