ViewBinding が使えるようになった！

Android Studio 3.6 Canary 11 で ViewBinding を使えるようになりました :clap: 

[ドキュメント](https://developer.android.com/topic/libraries/view-binding)  


## ViewBinding とは?
簡易版 DataBinding のようなイメージで、`findViewById` を省略でき、Null Safe & Type Safe になっています。
DataBinding とは異なり、マッピングや双方向バインディングはできません。


```
private lateinit var binding: ActivityMainBinding

@Override
fun onCreate(savedInstanceState: Bundle) {
    super.onCreate(savedInstanceState)
    binding = ActivityMainBinding.inflate(layoutInflater)
    setContentView(binding.root)

    binding.button.setOnClickListener { 
       // Do something
    }
}

```


## ViewBinding を使う場面  

> In most cases, view binding replaces findViewById.

`findViewById` や Kotlin Android Extensions の置き換えが考えられます。
Kotlin Android Extensions を使う場合、id がそのまま変数名になっていたので、id を snake_case にすると View の変数名も snake_case になってました。
ViewBinding では id を snake_case にしても ViewBinding 経由で View を取得する際は lowerCamelCase になります。
<br />

> Note: If you have already enabled data binding in a module, you don't need to enable view binding for that module.

DataBinding 経由で View にアクセスできるので、DataBinding を使用していれば ViewBinding を使うことはおそらくないはずです。  


## ViewBinding の現状の問題点  

- 一部のライブラリでサポートされていない  
出たばかりなので、groupie など一部のライブラリがサポートされていません    
- Activity のコンストラクタに渡せない  
Activity のコンストラクタにレイアウトリソースを渡すことができますが、ViewBinding との併用ができなさそうです…  
(できる方法があれば教えていただきたい…)  

## おまけ : ViewBinding が生成するコード  

```
public final class ActivityVideoDetailBinding implements ViewBinding {
  @NonNull
  private final CoordinatorLayout rootView;

  @NonNull
  public final FrameLayout detailContainer;

  @NonNull
  public final FrameLayout playerContainer;

  private ActivityVideoDetailBinding(@NonNull CoordinatorLayout rootView,
      @NonNull FrameLayout detailContainer, @NonNull FrameLayout playerContainer) {
    this.rootView = rootView;
    this.detailContainer = detailContainer;
    this.playerContainer = playerContainer;
  }

  @Override
  @NonNull
  public CoordinatorLayout getRoot() {
    return rootView;
  }

  @NonNull
  public static ActivityVideoDetailBinding inflate(@NonNull LayoutInflater inflater) {
    return inflate(inflater, null, false);
  }

  @NonNull
  public static ActivityVideoDetailBinding inflate(@NonNull LayoutInflater inflater,
      @Nullable ViewGroup parent, boolean attachToParent) {
    View root = inflater.inflate(R.layout.activity_video_detail, parent, false);
    if (attachToParent) {
      parent.addView(root);
    }
    return bind(root);
  }

  @NonNull
  public static ActivityVideoDetailBinding bind(@NonNull View rootView) {
    // The body of this method is generated in a way you would not otherwise write.
    // This is done to optimize the compiled bytecode for size and performance.
    String missingId;
    missingId: {
      FrameLayout detailContainer = rootView.findViewById(R.id.detailContainer);
      if (detailContainer == null) {
        missingId = "detailContainer";
        break missingId;
      }
      FrameLayout playerContainer = rootView.findViewById(R.id.playerContainer);
      if (playerContainer == null) {
        missingId = "playerContainer";
        break missingId;
      }
      return new ActivityVideoDetailBinding((CoordinatorLayout) rootView, detailContainer,
          playerContainer);
    }
    throw new NullPointerException("Missing required view with ID: ".concat(missingId));
  }
}
```

ただ `findViewById` をして変数で持っていてくれる Binding クラスが生成されています。