簡體   English   中英

ViewBinding 與 Kotlin Android 擴展與合成視圖

[英]ViewBinding vs Kotlin Android Extensions with synthetic views

新的ViewBinding與具有合成視圖綁定的Kotlin Android 擴展相比如何?

除了新的 ViewBindings 提供的 NullSafety 和 TypeSafety 之外,我們為什么要考慮放棄 Kotlin 在 Views 上使用合成綁定的方式?

新的 ViewBinding 是否更高效,因為它預先生成了 Binding class?

讓我們回顧一下兩者。


配置

Kotlin Android 擴展

  1. 導入適當的布局合成擴展: import kotlinx.android.synthetic.main.<layout>.*
  2. 通過 id 引用代碼中的視圖: textView.text = "Hello, world!" . 這些擴展適用於: ActivitiesFragmentsViews

視圖綁定

  1. 在 class 中創建綁定引用: private lateinit var binding YourClassBinding
  2. ActivityonCreate中膨脹你的綁定binding = YourClassBinding.inflate(layoutInflater)並調用setContentView(binding.root) ,或者在FragmentonCreateView中膨脹它然后返回它: return binding.root
  3. 通過使用其 id 綁定來引用代碼中的視圖binding.textView.text = "Hello, world!"

類型安全

Kotlin Android 根據定義,擴展ViewBinding是類型安全的,因為引用的視圖已經轉換為適當的類型。


Null安全

Kotlin Android 擴展ViewBinding都是 null 安全的。 ViewBinding 在這里沒有任何優勢 KAE的情況下,如果視圖僅存在於某些布局配置中,IDE 會為您指出:

在此處輸入圖像描述

因此,您只需將其視為 Kotlin 中的任何其他可為空的類型,錯誤就會消失:

在此處輸入圖像描述


應用布局更改

Kotlin Android Extensions的情況下,布局更改會立即轉化為合成擴展的生成,因此您可以立即使用它們。 ViewBinding的情況下,您必須構建您的項目


布局使用不正確

Kotlin Android Extensions的情況下,可能會導入不正確的布局合成擴展,從而導致NullPointerException 這同樣適用於ViewBinding ,因為我們可以導入錯誤的Binding class。 雖然,與不正確的 class 名稱相比,更可能忽略不正確的導入,特別是如果布局文件以Activity / Fragment / View命名,因此ViewBinding在這里占據上風。


KAE 與 ViewBinding 的總結

  • 類型安全- 繪制。
  • Null 安全- 繪制。
  • 樣板代碼- KAE獲勝。 來自 Kotlin Android 擴展文檔

Kotlin Android Extensions 插件允許我們獲得與其中一些庫相同的體驗,而無需添加任何額外的代碼。

  • 應用布局更改- KAE獲勝。 ViewBinding相比,更改是即時的。
  • 布局使用不正確- ViewBinding獲勝

我認為ViewBinding替代KAE存在很大的誤解。 人們聽到大關鍵字並重復它們而無需事先驗證。 當然, ViewBinding是目前 Java 開發的最佳選擇(替代ButterKnife ),但在 Kotlin 中與KAE相比沒有或幾乎沒有優勢(請參閱不正確的布局使用部分)。

旁注:我確信 DataBinding 的人會喜歡 ViewBinding :)

ViewBinding解決了kotlinx.android.synthetic的最大問題。 synthetic綁定中,如果您將內容視圖設置為布局,然后鍵入僅存在於不同布局中的 id,IDE 可讓您自動完成並添加新的導入語句。 除非開發人員專門檢查以確保他們的導入語句只導入正確的視圖,否則沒有安全的方法來驗證這不會導致運行時問題。 但是在ViewBinding中,您應該使用layout綁定 object 來訪問其視圖,因此您永遠不會調用不同布局中的視圖,如果您想這樣做,您將收到編譯錯誤而不是運行時錯誤。 這是一個例子。

我們創建了兩個布局,分別稱為activity_mainactivity_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!"
    }
}

您的代碼將無任何錯誤地編譯,但您的應用程序將在運行時崩潰。 因為在activity_main中不存在message_other id 的視圖,並且編譯器沒有檢查這一點。 但是如果你像這樣使用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在最后一行顯示錯誤。

kotlinx.android.synthetic 不再是推薦的做法,谷歌在一個提交消息“Reddit 線程之一”中說

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

Synthetics不是由 google 開發的,它是 kotlin android 擴展的一部分,由 JetBrains 制作並逐漸 google android 開發人員開始在他們的演示中替換 Synthetics 並綁定源代碼。

“現在問題來了,我們必須考慮哪一個。”

根據谷歌(視圖綁定,ButterKnife,Kotlin 合成)這些庫被許多應用程序成功使用並解決了同樣的問題。

但是對於大多數應用程序,谷歌建議嘗試視圖綁定而不是這些庫,因為視圖綁定提供了更安全、更簡潔的視圖查找。

附上參考圖像以快速清除事物。 在此處輸入圖像描述

但是,如果您想深入了解 go,您可以點擊以下鏈接。 https://medium.com/androiddevelopers/use-view-binding-to-replace-findviewbyid-c83942471fc

Kotlin Android 擴展將被 Kotlin 1.4.20 棄用,所以我建議使用 ViewBinding。

https://proandroiddev.com/migrating-the-deprecated-kotlin-android-extensions-compiler-plugin-to-viewbinding-d234c691dec7

三是這個家伙的關於性能與數據綁定和視圖綁定基於數據綁定的問題,所以,這可以幫助你。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM