ViewBindingとKotlin Android Extensionsの合成ビュー


38

新しいViewBindingは、Kotlin Android Extensionsと合成ビューバインディングをどのように比較しますか?

新しいViewBindingsによって提供されるNullSafetyとTypeSafetyを別にして、ビューで合成バインディングを使用するKotlinの方法を廃止することを検討する必要があるのはなぜですか。

新しいViewBindingは、事前にBindingクラスを生成するため、パフォーマンスが向上していますか?


私は、discuss.kotlinlangでやや似た質問を作成しました。誰かがこのトピックについて考えている場合は、返信してください:)
xinaiz

1
見てみましょうKotlinシンセティック以上の引数いくつかのより多くの背景を。
Cheticamp

回答:


69

2つを確認してみましょう。


構成

Kotlin Android拡張機能

  1. 適切なレイアウト合成拡張機能をインポートします。 import kotlinx.android.synthetic.main.<layout>.*
  2. IDを使用してコード内のビューを参照しますtextView.text = "Hello, world!"。これらの拡張機能はActivitiesFragmentsとで機能しViewsます。

バインドを表示

  1. クラス内にバインディング参照を作成します。 private lateinit var binding YourClassBinding
  2. あなたの結合膨らませるbinding = YourClassBinding.inflate(layoutInflater)内部ActivityonCreate通話をsetContentView(binding.root)、またはそれを膨らませるFragmentonCreateViewにそれを返し、その後:return binding.root
  3. IDを使用したバインディングを介したコード内のビューの参照 binding.textView.text = "Hello, world!"

タイプセーフ

参照ビューは既に適切なタイプにキャストされているため、Kotlin Android ExtensionsViewBindingは定義によりタイプセーフです。


ヌルセーフティ

Kotlin Android ExtensionsViewBindingはどちらもnullセーフです。ここではViewBindingに利点はありませんKAEの場合、一部のレイアウト構成でのみビューが存在する場合、IDEはそれを指摘します。

ここに画像の説明を入力してください

したがって、それをKotlin内の他のnull許容型として扱うだけで、エラーが消えます。

ここに画像の説明を入力してください


レイアウト変更の適用

Kotlin Android拡張機能の場合、レイアウトの変更は即座に合成拡張機能の生成に変換されるため、すぐに使用できます。ViewBindingの場合、プロジェクトをビルドする必要があります


不適切なレイアウトの使用

Kotlin Android拡張機能の場合、誤ったレイアウトの合成拡張機能をインポートして、を引き起こす可能性がありNullPointerExceptionます。間違ったクラスをインポートする可能性があるため、同じことがViewBindingにも当てはまりますBinding。ただし、特にレイアウトファイルの名前がActivity/ Fragment/ Viewにちなんでいる場合は、誤ったクラス名よりも誤ったインポートを見落とす可能性が高いため、ここではViewBinding有利です。


KAEとViewBindingのまとめ

  • タイプセーフ -描画。
  • ヌルセーフティ -描画。
  • 定型コード - KAEが勝利。Kotlin Android Extensionsのドキュメントから

Kotlin Android Extensionsプラグインを使用すると、追加のコードを追加しなくても、これらのライブラリのいくつかと同じエクスペリエンスを取得できます。

  • レイアウトの変更の適用 - KAEが勝ちます。ViewBindingとは対照的に、変更は瞬時に行われます
  • 誤ったレイアウトの使用状況 - ViewBinding勝利

ViewBindingKAEの代わりになるという大きな誤解があると思います。人々は大きなキーワードを聞いて、事前に確認することなくそれらを繰り返します。確かに、ViewBindingは現在のJava開発に最適なオプションです(ButterKnifeの置き換え)。ただし、KotlinのKAEに勝る利点はほとんどありません(不適切なレイアウトの使用法のセクションを参照)。

補足: DataBindingの人はViewBindingを気に入るはずです:)


で変数を使用することについて何も言わなかったのDataBindingですか?ビュー参照を一切使わないことが重要な機能だと思います。ちなみに、<include ... />タグを使用してビューモデルを「スロー」できるという点も、大きな利点です。
Ircover

1
@Ircover問題は、KAEとViewBindingの比較についてでした。DataBindingはその質問の一部ではありません。
xinaiz

おっと、すみません)単純な誤解。
Ircover

1
@BenLewisバインディングがlateinitとして定義されている場合でも、同じ問題が発生します。つまり、KAEやViewBindingを何を使用するかを計ることはできません。フラグメントでコードを記述するときは、いくつかの厳密な規則に従う必要があります。
フラビオ

1
「レイアウト変更の適用」-ViewBindingを使用する場合、プロジェクトをビルドする必要はありません。IDを使用して新しいビューを追加した後、即座に「binding.myTextView ..」を実行できます。
Tayyab Mazhar

19

ViewBindingの最大の問題を解決しましたkotlinx.android.synthetic。ではsynthetic、あなたがレイアウトにあなたのコンテンツビューを設定した場合、その後、唯一異なるレイアウトに存在するIDを入力結合、IDEを使用すると、オートコンプリート、新たなインポート文を追加することができます。開発者がimportステートメントが正しいビューのみをインポートすることを確認するために特に確認しない限り、これがランタイムの問題を引き起こさないことを確認する安全な方法はありません。しかし、中にViewBindingあなたが使用する必要がありますlayout異なるレイアウトで表示するために呼び出すあなたように、その見解を決してアクセスしないように結合オブジェクトを、あなたはこれをしたい場合は、コンパイルエラーではないランタイムエラーを取得します。ここに例があります。

私たちは、と呼ばれる2つのレイアウトを作成activity_mainし、activity_otherそのように:

activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                android:layout_width="match_parent"
                android:layout_height="match_parent">

    <TextView
        android:id="@+id/message_main"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        />

</RelativeLayout>

activity_other.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                xmlns:tools="http://schemas.android.com/tools"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                >

    <TextView
        android:id="@+id/message_other"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        />

</RelativeLayout>

次のようにアクティビティを記述したとします。

import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import kotlinx.android.synthetic.main.activity_other.*

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        //Application will crash because "message_other" doesn't exist in "activity_main"
        message_other.text = "Hello!"
    }
}

コードはエラーなしでコンパイルされますが、アプリケーションは実行時にクラッシュします。message_otherIDを持つビューがに存在activity_mainせず、コンパイラがこれをチェックしなかったためです。しかし、次のViewBindingように使用した場合:

class MainActivity : AppCompatActivity() {
    private lateinit var binding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)
        //This code will never compile and the IDE shows you an error
        binding.message_other.text = "Hello!"
    }
}

コードはコンパイルされずAndroid Studio、最終行にエラーが表示されます。


1
また、LayoutInflaterを使用してビューを拡張し、変数を介してその定義済みフィールドを参照することもできます。
NapoleonTheCake

4
これは実際のシナリオでは起こりそうにありません。
Bencri

1
この例は意味がありません。使い方を間違えました。なぜ間違ったもの(activity_other)をインポートするのですか?誤って使用するすべてのフレームワークは問題を引き起こす可能性があります。
Android開発者

2

kotlinx.android.syntheticは、推奨されなくなったプラクティスであり、Googleが1つのコミットメッセージ「Redditスレッドの1つ

https://android-review.googlesource.com/c/platform/frameworks/support/+/882241 "

Syntheticsはgoogleによって開発されたものではなく、JetBrainsによって作成されたkotlin android拡張機能の一部であり、徐々にgoogle android開発者はデモとソースコードでSyntheticsをViewBindinsに置き換え始めました。

「さて、問題を考えましょう。どちらを考慮に入れなければなりませんか。」

グーグル(ビューバインディング、バターナイフ、コトリン合成)によると、これらのライブラリは多くのアプリで正常に使用され、同じ問題を解決しています。

ただし、ほとんどのアプリでは、これらのライブラリではなくビューバインディングを試すことをお勧めします。ビューバインディングは、より安全で簡潔なビュールックアップを提供するためです。

添付の参照画像で、物事をすばやくクリアできます。 ここに画像の説明を入力してください

ただし、詳細を知りたい場合は、以下のリンクをクリックしてください。 https://medium.com/androiddevelopers/use-view-binding-to-replace-findviewbyid-c83942471fc


2
1.常にnullセーフ-インフレの前またはビューのライフサイクルの終了後にビューバインディングを使用するとクラッシュします。2.現在のレイアウトのIDのみを参照する-それは事実ですが、IDEは指定されたIDをインポートするレイアウトから指摘するので、大きな問題ではありません。3. KotlinとJavaのサポート-不正な引数。Android開発でKotlinを使用できる場合は、Javaを使用する理由。4.必要なコードの量-Kotlin合成の量が最も少なく、表では非常に少ないはずです。
xinaiz

@xinaizインフレートする前にそれを使用する理由、それが問題に直面することを確実にするために、それ以外の場合はそれを使用する正しい方法に従ってください。反対票を投じてコメントを投稿する前にリンクを確認しましたか 。medium.com
androiddevelopers /

はい、少し前に読んだことがあります。私は膨らませる前にそれを使っていません、それは可能だと言っているだけです。「正しい方法」はリスクがあることを意味しますよね?また、or after view lifecycle ends一部スキップしましたか?
xinaiz

@xinaiz 2.しかし、プロジェクトが大きい場合は間違ったIDを使用する可能性があり、プロジェクトに取り組んでいるマルチ開発者が同じリソース名を使用する可能性もあります。3.はい。javaとkotlinの両方を使用する必要のあるプロジェクト要件がある可能性があります(プロジェクトがすでにJavaで開発されており、kotlinとの統合が開始されている場合は、間違いなく役立ちます) Gradleにはすでに存在しているので、コードが少なくて済みます。
SourabhTech

1
4.への対応。どのライブラリ?デフォルトでは有効になっています。apply plugin: 'kotlin-android-extensions'vs についての議論viewBinding { enabled = true }です。大した違いはありません。
xinaiz
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.