ButterKnifeを使ってソースコードのダイエットをする

やぎすけAdventCalendar2016 Android

Posted on Dec 7


こんにちは、やぎにいです。
やぎすけ Advent Calendar 2016の7日目です。12月も1週間が経過してしまいました。なんだか記事を書く、新しい知識を得たらどこかにメモを取る癖がついてきた気がします。
昨日は僕がTimberをLogの代わりに使用して快適ログ確認を書きました。

今日はAndroidプロジェクトを作って結構な確率で導入するライブラリで書いた3つ目のButterKnifeの使い方をまとめたいと思います。

導入

ButterKnifeを導入します。いつも通りbuild.gradleを開いて。

1
2
3
4
dependencies {
  compile 'com.jakewharton:butterknife:8.4.0'
  annotationProcessor 'com.jakewharton:butterknife-compiler:8.4.0'
}

を書いてあげてSyncすればもう導入完了です。
特にアプリケーションクラス等での初期化とかも要らないので、早速Activity等で使ってみましょう。
今回も3日目に書いたさくっとRecyclerViewを使ってリストを作成するのソースコードyagi2/RecyclerView-sampleを使って行きたいと思います。


使い方

使い方は簡単です、findViewByIdをしているものをアノテーションを用いてフィールドとしてやります。 実際にさくっとRecyclerViewを使ってリストを作成するのMainActivityで使ってみましょう。
以下のような感じです。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class MainActivity extends AppCompatActivity implements RecyclerViewAdapter.Listener {

    private RecyclerView mRecyclerView;
    // 以下省略

// を以下の通り書き換えましょう
public class MainActivity extends AppCompatActivity implements RecyclerViewAdapter.Listener {

    @BindView(R.id.recycler_view) // @BindViewアノテーションにViewのidを渡してあげる
    RecyclerView mRecyclerView;

    // 中略

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

        ButterKnife.bind(this); // この行を追加してください。

これで実行してもRecyclerViewの参照している部分で特にnull落ちもせずにアイテムが表示されたと思います。

アイテムをタップした際のコールバックメソッドにもButterKnifeを適用してみましょう

1
2
3
4
5
@Override
public void onRecyclerClicked(View v, int position) {
    TextView textView = (TextView) v.findViewById(R.id.text); // この行を
    Toast.makeText(this, textView.getText().toString(), Toast.LENGTH_SHORT).show();
}
1
2
3
4
5
@Override
public void onRecyclerClicked(View v, int position) {
    TextView textView = ButterKnife.findById(v, R.id.text); // こう変更します
    Toast.makeText(this, textView.getText().toString(), Toast.LENGTH_SHORT).show();
}

ButterKnife#findByIdを使用することに酔って、findViewByIdのときに必要だったViewのキャストが必要なくなります。
結構lintに指摘されるのでかなり便利ですね。

ButterKnifeAdapterViewHolderにも適用します。
実際にさくっとRecyclerViewを使ってリストを作成するで作ったAdapterを使ってやってみましょう。 先ほどと同じようにしてあげます。ViewHolderは以下の通りになります。

1
2
3
4
5
6
7
8
9
10
public class ViewHolder extends RecyclerView.ViewHolder {
    @BindView(R.id.text) TextView textView;

    public ViewHolder(View itemView) {
        super(itemView);
        ButterKnife.bind(this, itemView);

        textView = (TextView)itemView.findViewById(R.id.text);
    }
}

以上の通りでAdapterにもButterKniteを適用させることができます。
今回のこのソースではViewの数が少ないのであんまり効果がわからないかもしれませんが、onCreateでたくさんfindViewByIdをしている場合等、これを使うとスッキリします。


さらなる使い方

Viewのバインドについて紹介しましたが、イベントリスナーもButterKnifeで作ってあげることが出来ます。
例えばボタンを押したらトーストを表示させるような場合

1
2
3
4
5
6
findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        Toast.makeText(this, "押された!", Toast.LENGTH_LONG).show();
    }
});

このように書いてあげたりすると思いますが、ButterKnifeを使うとアノテーションでこれも処理できます。

1
2
3
4
@OnClick(R.id.button)
void buttonClick() {
    Toast.makeText(this, "押された!!", Toast.LENGTH_LONG).show();
}

こっちも見た目がスッキリしますね。
複数のボタンで同じ処理をするときはアノテーションに複数Viewidを渡します。

1
2
3
4
5
6
7
@OnClick(R.id.button1
         R.id.button2
         R.id.button3
         R.id.button4)
void buttonClick() {
    Toast.makeText(this, "押された!!", Toast.LENGTH_LONG).show();
}

結構Viewのイベントリスナーはどうやってセットしようかというのは迷うと思うのですが、ButterKnifeを使ってあげることによって見やすく書いてあげることが出来ます。
使えるアノテーションはJakeWharton/butterknife#butterknife-annotationsにある通りです。
Stringintdimenなどリソースでidを渡して設定しているものもbindすることができます。
同じ文言を使用するとかの場合にいちいちR.string.hoge_msgとか書く必要がなくなりますね。


おわりに

今回はViewなどを簡単にセットしてfindViewByIdを減らし、ソースコードをダイエットする話を書きました。
僕はこのButterKnifeに出会ってからFragmentActivityのソースをかなりダイエットさせることができました。
  実はAndroidにはデータ バインディング ライブラリが存在してそっちでも同じように書くことができるのだが、未だにButterKnifeを使っているプロジェクトが多く感じる。
でもそろそろこっちも触って置いたほうが良いんだろうなと個人的にも思っているところでした。

以上、やぎにいでした!


このエントリーをはてなブックマークに追加
comments powered by Disqus

<< Icepickを使ってActivityの破棄に備える     TimberをLogの代わりに使用して快適ログ確認 >>



2018やぎ小屋