簡體   English   中英

Kotlin 帶有擴展方法的數據綁定

[英]Kotlin databinding with extension methods

我正在嘗試在 Android 的數據綁定中使用 Kotlin 擴展方法。 例如; 調用 onclick 處理程序。 所以我做了這段代碼:

posttest_list_item.xml

<?xml version="1.0" encoding="utf-8"?>

<data>
    <import type="android.view.View"/>
    <import type="com.example.test.post.posttest.PostTestItemViewModelExtensionKt" />
    <variable
        name="viewModel"
        type="com.example.test.post.posttest.PostTestItemViewModel" />
</data>
<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:paddingLeft="16dp"
    android:paddingRight="16dp"
    android:clickable="true"
    android:onClick="@{(view) -> viewModel.clicked(view)}"
    >
[...]

PostTestItemViewModel.kt

open class PostTestItemViewModel : ViewModel() {
    val postTitle = MutableLiveData<String>()
    val postBody = MutableLiveData<String>()

   /**
    * Binds the required properties/entities to this ViewModel
    */
   fun bind(post: Post) {
       postTitle.value = post.title
       postBody.value = post.body
   }
}

PostTestItemViewModelExtension.kt

fun PostTestItemViewModel.clicked(v: View) {
    this.postTitle.value = "clicked"
}

因此,當我將 clicked 方法放置在視圖模型中時,它會按應有的方式完美運行。 但是,當我將其創建為擴展方法時,編譯時出現以下錯誤:

e: [kapt] 發生異常:android.databinding.tool.util.LoggedErrorException:發現數據綁定錯誤。 在 class 中找不到方法 clicked(android.view.View)...PostItemViewModel

我已經嘗試過不同的方法,例如將android:onclick標記更改為PostTestItemViewModelExtensionKt而不是viewModel 不幸的是,所有的事情似乎都不起作用。 所以看起來擴展方法是在數據綁定發生后生成的。 有沒有辦法解決這個問題,還是我仍然做錯了什么? 還是無法綁定擴展方法?

我正在使用 Kotlin 版本 1.2.71、gradle 3.2.0,並將databinding { enabled = true }kapt { generateStubs = true }添加到 my.gradle,並添加插件kotlin-androidkotlin-android-extensionskotlin-kapt定義。

不幸的是,你不能使用擴展方法作為onClick回調。

Kotlin中的擴展方法是作為Java靜態方法創建的,而Android框架則是期望實例方法。

請注意,在Android Studio中,您可以將Kotlin類反編譯為Java,以查看生成的Java代碼。

所以,今天(2022 年)我在我的一個項目中有相同的用例,我能夠找到一種方法來使用數據綁定和自定義適配器為 android 視圖實現自定義點擊偵聽器。

用例是:

點擊事件不應被觸發兩次或防止用戶誤點擊

我創建了一個名為 ViewExtensions.kt 的文件並添加了以下代碼

 class DebouncingOnClickListener(
      private val intervalMillis: Long,
      private val doClick: (() -> Unit)
    ) : View.OnClickListener {

    override fun onClick(v: View) {
        if (enabled) {
            enabled = false
            v.postDelayed(ENABLE_AGAIN, intervalMillis)
            doClick()
        }
    }

    companion object {
        @JvmStatic
        var enabled = true
        private val ENABLE_AGAIN =
            Runnable { enabled = true }
    }
}

@BindingAdapter("singleClick")
fun View.setSingleClick(doClick: () -> Unit) =
    setOnClickListener(
        DebouncingOnClickListener( 
            intervalMillis = 5000, //5ms delay for click event
            doClick = doClick
        )
    )

debouncing click 用於延遲給定時間的點擊,在 xml 中調用如下所示的點擊事件

 <androidx.appcompat.widget.AppCompatButton
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Click Me"
        app:singleClick="@{()->fragment.clicked()}" />

現在我可以在片段和視圖模型中監聽點擊事件,並且點擊會延遲給定的時間。

因此,用戶不能意外地多次單擊該視圖。

參考資料: https://proandroiddev.com/ensure-single-click-on-android-butterknife-did-it-right-48ef56153c78

暫無
暫無

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

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