[英]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-android
、 kotlin-android-extensions
和kotlin-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.