LoginSignup
6
5

More than 3 years have passed since last update.

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

Last updated at Posted at 2019-09-12

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

ドキュメント

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 になります。

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 クラスが生成されています。

6
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
5