[翻訳] Butter Knife (version7.0.1)

[Butter Knife](http://jakewharton.github.io/butterknife/) を翻訳してみました。　
いまさらな感じですが、全部入りが欲しかったので。

（おおむね問題ないと思いますが）一部不明な点もありましたので、
もしおかしな点がありましたらコメント頂ければと思います。

あと、[ButterKnifeZelezny](https://github.com/avast/android-butterknife-zelezny)にもリンクしておきます。

# Introduction

> Annotate fields with `@Bind` and a view ID for Butter Knife to find and automatically cast the corresponding view in your layout.
> 
```java
class ExampleActivity extends Activity {
  @Bind(R.id.title) TextView title;
  @Bind(R.id.subtitle) TextView subtitle;
  @Bind(R.id.footer) TextView footer;
> 
  @Override public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.simple_activity);
    ButterKnife.bind(this);
    // TODO Use fields...
  }
}
```
> 
Instead of slow reflection, code is generated to perform the view look-ups. Calling `bind` delegates to this generated code that you can see and debug.
The generated code for the above example is roughly equivalent to the following:
> 
```java
public void bind(ExampleActivity activity) {
  activity.subtitle = (android.widget.TextView) activity.findViewById(2130968578);
  activity.footer = (android.widget.TextView) activity.findViewById(2130968579);
  activity.title = (android.widget.TextView) activity.findViewById(2130968577);
}
```

あなたのレイアウト内の該当のビューを見つけ、自動で割り当てるため、フィールドにButter Knife用に`@Bind`とview IDでアノテートします。

```java
class ExampleActivity extends Activity {
  @Bind(R.id.title) TextView title;
  @Bind(R.id.subtitle) TextView subtitle;
  @Bind(R.id.footer) TextView footer;
 
  @Override public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.simple_activity);
    ButterKnife.bind(this);
    // TODO Use fields...
  }
}
```
時間のかかるリフレクションではなく、ビューの検索を行うコードが生成されます。　`ButterKnife#bind()`を呼び出すと、この参照できてデバッグ可能な生成コードに処理が委ねられます。

上記の例で生成されたコードは、下記とだいたい同じです。

```java
public void bind(ExampleActivity activity) {
  activity.subtitle = (android.widget.TextView) activity.findViewById(2130968578);
  activity.footer = (android.widget.TextView) activity.findViewById(2130968579);
  activity.title = (android.widget.TextView) activity.findViewById(2130968577);
}
```
## RESOURCE BINDING
>
Bind pre-defined resources with `@BindBool`, `@BindColor`, `@BindDimen`, `@BindDrawable`, `@BindInt`, `@BindString`, which binds an `R.bool` ID (or your specified type) to its corresponding field.
>
```java
class ExampleActivity extends Activity {
  @BindString(R.string.title) String title;
  @BindDrawable(R.drawable.graphic) Drawable graphic;
  @BindColor(R.color.red) int red; // int or ColorStateList field
  @BindDimen(R.dimen.spacer) Float spacer; // int (for pixel size) or float (for exact value) field
  // ...
}
```

`R.bool` ID（または、あなたが指定した型）をバインドしてくれる`@BindBool`や`@BindColor`や`@BindDimen`や`@BindDrawable`や`@BindInt`や`@BindString`を使用して、定義済みリソースを該当フィールドにバインドします。

```java
class ExampleActivity extends Activity {
  @BindString(R.string.title) String title;
  @BindDrawable(R.drawable.graphic) Drawable graphic;
  @BindColor(R.color.red) int red; // int or ColorStateList field
  @BindDimen(R.dimen.spacer) Float spacer; // int (for pixel size) or float (for exact value) field
  // ...
}
```

## NON-ACTIVITY BINDING
>
You can also perform binding on arbitrary objects by supplying your own view root.
> 
```java
public class FancyFragment extends Fragment {
  @Bind(R.id.button1) Button button1;
  @Bind(R.id.button2) Button button2;
>
  @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fancy_fragment, container, false);
    ButterKnife.bind(this, view);
    // TODO Use fields...
    return view;
  }
}
```
>
Another use is simplifying the view holder pattern inside of a list adapter.
>
```java
public class MyAdapter extends BaseAdapter {
  @Override public View getView(int position, View view, ViewGroup parent) {
    ViewHolder holder;
    if (view != null) {
      holder = (ViewHolder) view.getTag();
    } else {
      view = inflater.inflate(R.layout.whatever, parent, false);
      holder = new ViewHolder(view);
      view.setTag(holder);
    }
>
    holder.name.setText("John Doe");
    // etc...
>
    return view;
  }
>
  static class ViewHolder {
    @Bind(R.id.title) TextView name;
    @Bind(R.id.job_title) TextView jobTitle;
>
    public ViewHolder(View view) {
      ButterKnife.bind(this, view);
    }
  }
}
```
>
You can see this implementation in action in the provided sample.
Calls to `ButterKnife.bind` can be made anywhere you would otherwise put `findViewById` calls.
>
Other provided binding APIs:
　・ Bind arbitrary objects using an activity as the view root. If you use a pattern like MVC you can bind the controller using its activity with `ButterKnife.bind(this, activity)`.
　・ Bind a view's children into fields using `ButterKnife.bind(this)`. If you use `<merge>` tags in a layout and inflate in a custom view constructor you can call this immediately after. Alternatively, custom view types inflated from XML can use it in the `onFinishInflate()` callback.


またビュールートを渡せば、任意のオブジェクトでバインドすることも出来ます。

```java
public class FancyFragment extends Fragment {
  @Bind(R.id.button1) Button button1;
  @Bind(R.id.button2) Button button2;

  @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fancy_fragment, container, false);
    ButterKnife.bind(this, view);
    // TODO Use fields...
    return view;
  }
}
```

他の使い方として、リストアダプター内のビューホルダーパターンの簡素化もあります。

```java
public class MyAdapter extends BaseAdapter {
  @Override public View getView(int position, View view, ViewGroup parent) {
    ViewHolder holder;
    if (view != null) {
      holder = (ViewHolder) view.getTag();
    } else {
      view = inflater.inflate(R.layout.whatever, parent, false);
      holder = new ViewHolder(view);
      view.setTag(holder);
    }

    holder.name.setText("John Doe");
    // etc...

    return view;
  }

  static class ViewHolder {
    @Bind(R.id.title) TextView name;
    @Bind(R.id.job_title) TextView jobTitle;

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

提供されているサンプルの動きでこの実装を確かめることができます。
`ButterKnife.bind`の呼出は、`findViewById`を呼ぶであろう場所ならどこでも行えます。

その他のAPI:
　・ activityをビュールートとして使用した任意のオブジェクトとのバインド。　もしMVCのようなパターンを使用するなら、そのactivityと`ButterKnife.bind(this, activity)`を使用してコントローラーとバインドできます。
　・ ビューの子要素とフィールドを`ButterKnife.bind(this)`でバインド。　もしレイアウト内で`<merge>`タグを使用し、カスタムビューのコンストラクタでインフレートするなら、直後にこれを呼び出すことができます。　また、XMLからインフレートされたカスタムビューは`onFinishInflate()`コールバックでこれを使用できます。

## VIEW LISTS
>
You can group multiple views into a `List` or array.
>
```java
@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.
>
```java
ButterKnife.apply(nameViews, DISABLE);
ButterKnife.apply(nameViews, ENABLED, false);
```
>
`Action` and `Setter` interfaces allow specifying simple behavior.
>
```java
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);
  }
};
```
>
An Android `Property` can also be used with the `apply` method.
>
```java
ButterKnife.apply(nameViews, View.ALPHA, 0.0f);
```

複数のビューを`List`または配列にまとめることができます。

```java
@Bind({ R.id.first_name, R.id.middle_name, R.id.last_name })
List<EditText> nameViews;
```

`apply`メソッドでリスト内の全ビューを一括で操作できます。

```java
ButterKnife.apply(nameViews, DISABLE);
ButterKnife.apply(nameViews, ENABLED, false);
```

`Action`と`Setter`インターフェイスで簡単な動作が指定できます。

```java
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);
  }
};
```
Androidの`Property`も`apply`メソッドで使用できます。

```java
ButterKnife.apply(nameViews, View.ALPHA, 0.0f);
```

## LISTENER BINDING
>
Listeners can also automatically be configured onto methods.
>
```java
@OnClick(R.id.submit)
public void submit(View view) {
  // TODO submit data to server...
}
```
>
All arguments to the listener method are optional.
>
```java
@OnClick(R.id.submit)
public void submit() {
  // TODO submit data to server...
}
```
>
Define a specific type and it will automatically be cast.
>
```java
@OnClick(R.id.submit)
public void sayHi(Button button) {
  button.setText("Hello!");
}
```
>
Specify multiple IDs in a single binding for common event handling.
>
```java
@OnClick({ R.id.door1, R.id.door2, R.id.door3 })
public void pickDoor(DoorView door) {
  if (door.hasPrizeBehind()) {
    Toast.makeText(this, "You win!", LENGTH_SHORT).show();
  } else {
    Toast.makeText(this, "Try again", LENGTH_SHORT).show();
  }
}
```
>
Custom views can bind to their own listeners by not specifying an ID.
>
```java
public class FancyButton extends Button {
  @OnClick
  public void onClick() {
    // TODO do something!
  }
}

リスナーも自動でメソッドにバインドできます。

```java
@OnClick(R.id.submit)
public void submit(View view) {
  // TODO submit data to server...
}
```

リスナーのすべての引数は省略可能です。

```java
@OnClick(R.id.submit)
public void submit() {
  // TODO submit data to server...
}
```

具体的な型を明記すると、自動でキャストされます。

```java
@OnClick(R.id.submit)
public void sayHi(Button button) {
  button.setText("Hello!");
}
```

共通のイベント処理向けに、ひとつのバインドに複数IDを指定できます。

```java
@OnClick({ R.id.door1, R.id.door2, R.id.door3 })
public void pickDoor(DoorView door) {
  if (door.hasPrizeBehind()) {
    Toast.makeText(this, "You win!", LENGTH_SHORT).show();
  } else {
    Toast.makeText(this, "Try again", LENGTH_SHORT).show();
  }
}
```

カスタムビューではIDを指定せずに自身のリスナーをバインドできます。

```java
public class FancyButton extends Button {
  @OnClick
  public void onClick() {
    // TODO do something!
  }
}
```

## BINDING RESET
>
Fragments have a different view lifecycle than activities. When binding a fragment in `onCreateView`, set the views to `null` in `onDestroyView`. Butter Knife has an `unbind` method to do this automatically.
>
```java
public class FancyFragment extends Fragment {
  @Bind(R.id.button1) Button button1;
  @Bind(R.id.button2) Button button2;
>
  @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fancy_fragment, container, false);
    ButterKnife.bind(this, view);
    // TODO Use fields...
    return view;
  }
>
  @Override public void onDestroyView() {
    super.onDestroyView();
    ButterKnife.unbind(this);
  }
}
```

フラグメントは、activityとは異なるビューのライフサイクルを持っています。　`onCreateView`でフラグメントにバインドしたら、`onDestroyView`でビューに`null`をセットします。　Butter Knifeにはこれを自動で行う`unbind`メソッドがあります。

```java
public class FancyFragment extends Fragment {
  @Bind(R.id.button1) Button button1;
  @Bind(R.id.button2) Button button2;

  @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fancy_fragment, container, false);
    ButterKnife.bind(this, view);
    // TODO Use fields...
    return view;
  }

  @Override public void onDestroyView() {
    super.onDestroyView();
    ButterKnife.unbind(this);
  }
}
```

## OPTIONAL BINDINGS
>
By default, both `@Bind` and listener bindings are required. An exception will be thrown if the target view cannot be found.
To suppress this behavior and create an optional binding, add a `@Nullable` annotation to the field or method.
Note: Any annotation named `@Nullable` can be used for this purpose. It is encouraged to use the `@Nullable` annotation from Android's "support-annotations" library, see [Android Tools Project](http://tools.android.com/tech-docs/support-annotations).
>
```java
@Nullable @Bind(R.id.might_not_be_there) TextView mightNotBeThere;
>
@Nullable @OnClick(R.id.maybe_missing) void onMaybeMissingClicked() {
  // TODO ...
}
```

通常、`@Bind`とリスナーバインドの両方とも対象のビューが必要です。　対象のビューが見つからないと例外が発生します。　例外を抑止し、必須ではないバインドを作成するには、フィールドまたはメソッドに`@Nullable`アノテーションを追加します。

注意：`@Nullable`が指定されたどのアノテーションも、この用途で使用できます。　アンドロイドの"support-annotations"ライブラリの`@Nullable`アノテーションの使用が推奨されています。　[Android Tools Project](http://tools.android.com/tech-docs/support-annotations)を参照してください。

```java
@Nullable @Bind(R.id.might_not_be_there) TextView mightNotBeThere;

@Nullable @OnClick(R.id.maybe_missing) void onMaybeMissingClicked() {
  // TODO ...
}
```


## MULTI-METHOD LISTENERS
>
Method annotations whose corresponding listener has multiple callbacks can be used to bind to any one of them. Each annotation has a default callback that it binds to. Specify an alternate using the `callback` parameter.
>
```java
@OnItemSelected(R.id.list_view)
void onItemSelected(int position) {
  // TODO ...
}
>
@OnItemSelected(value = R.id.maybe_missing, callback = NOTHING_SELECTED)
void onNothingSelected() {
  // TODO ...
}
```

リスナー用のメソッドのアノテーションには、バインドできる複数のコールバックがあります。　それぞれのアノテーションにはデフォルトのバインド対象のコールバックがあり、`callback`パラメータでその他のものを指定します。

```java
@OnItemSelected(R.id.list_view)
void onItemSelected(int position) {
  // TODO ...
}

@OnItemSelected(value = R.id.maybe_missing, callback = NOTHING_SELECTED)
void onNothingSelected() {
  // TODO ...
}
```

## BONUS
>
Also included are `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.
>
```java
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.

また、依然としてビューactivityやダイアログ上でビューを探さざるを得ないコードを簡素化する`findById`メソッドもあります。　それは戻り値の型を推測するためジェネリクスを使用し、自動でキャストします。

```java
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);
```

`ButterKnife.findById`をスタティック インポートして活用しましょう。


## Download
>
[Butter Knife v7.0.1 JAR](http://repo1.maven.org/maven2/com/jakewharton/butterknife/7.0.1/butterknife-7.0.1.jar)
>
The source code to the library and sample application as well as this website is [available on GitHub](http://github.com/JakeWharton/butterknife). The Javadoc is also [available to browse](http://jakewharton.github.io/butterknife/javadoc/index.html).

[Butter Knife v7.0.1 JAR](http://repo1.maven.org/maven2/com/jakewharton/butterknife/7.0.1/butterknife-7.0.1.jar)

ライブラリとサンプルアプリケーションのソースは、このサイトと同じく[GitHubで利用可能](http://github.com/JakeWharton/butterknife)です。　Javadocも[閲覧できます](http://jakewharton.github.io/butterknife/javadoc/index.html)。

## MAVEN
>
If you are using Maven for compilation you can declare the library as a dependency.
>
```xml
<dependency>
  <groupId>com.jakewharton</groupId>
  <artifactId>butterknife</artifactId>
  <version>7.0.1</version>
</dependency>
```

あなたがコンパイルにMavenを使用している場合は、依存関係としてライブラリを宣言できます。

```xml
<dependency>
  <groupId>com.jakewharton</groupId>
  <artifactId>butterknife</artifactId>
  <version>7.0.1</version>
</dependency>
```

## GRADLE
>
```groovy
compile 'com.jakewharton:butterknife:7.0.1'
```
Be sure to suppress this lint warning in your `build.gradle`.
>
```groovy
lintOptions {
  disable 'InvalidPackage'
}
```
Some configurations may also require additional exclusions.
>
```groovy
packagingOptions {
  exclude 'META-INF/services/javax.annotation.processing.Processor'
}
```


```groovy
compile 'com.jakewharton:butterknife:7.0.1'
```

build.gradle内でlint警告を抑制してください。

```groovy
lintOptions {
  disable 'InvalidPackage'
}
```

構成によっては、追加で除外設定が必要な場合があります。

```groovy
packagingOptions {
  exclude 'META-INF/services/javax.annotation.processing.Processor'
}
```

## IDE CONFIGURATION
>
Some IDEs require additional configuration in order to enable annotation processing.
　・　IntelliJ IDEA — If your project uses an external configuration (like a Maven `pom.xml`) then annotation processing should just work. If not, try [manual configuration](http://jakewharton.github.io/butterknife/ide-idea.html).
　・　Eclipse — Set up [manual configuration](http://jakewharton.github.io/butterknife/ide-eclipse.html).

いくつかのIDEでは、アノテーションを有効にするために追加の構成が必要です。

　・　IntelliJ IDEA - プロジェクトが（Mavenの`pom.xml`のような）外部の設定を使用している場合、アノテーションは動作するでしょう。　そうでない場合は[手動での設定](http://jakewharton.github.io/butterknife/ide-idea.html)を試してみてください。
　・　Eclipse — [手動で設定](http://jakewharton.github.io/butterknife/ide-eclipse.html)してください。


## PROGUARD
>
Butter Knife generates and uses classes dynamically which means that static analysis tools like ProGuard may think they are unused. In order to prevent them from being removed, explicitly mark them to be kept. To prevent ProGuard renaming classes that use `@Bind` on a member field the `keepclasseswithmembernames` option is used.
>
```
-keep class butterknife.** { *; }
-dontwarn butterknife.internal.**
-keep class **$$ViewBinder { *; }
>
-keepclasseswithmembernames class * {
    @butterknife.* <fields>;
}
>
-keepclasseswithmembernames class * {
    @butterknife.* <methods>;
}
```

Butter Knifeは動的にクラスを生成し使用します。　これはProGuardのような静的解析ツールが、それらのクラスが未使用だと見なすかもしれないことを意味します。　それらが除去されないように明示します。　メンバーに`@Bind`アノテーションを使用しているクラスに対するProGuardによるリネームを防止するため、`keepclasseswithmembernames`オプションを使います。

```
-keep class butterknife.** { *; }
-dontwarn butterknife.internal.**
-keep class **$$ViewBinder { *; }

-keepclasseswithmembernames class * {
    @butterknife.* <fields>;
}

-keepclasseswithmembernames class * {
    @butterknife.* <methods>;
}
```