【Android】分享一次DataBinding的诡异踩坑经历(点击事件无效)

1,766 阅读1分钟

诡异问题

DataBinding想必大家已经很熟悉了。就在今天,我写了一个demo,然而遇到了一个匪夷所思的问题,Button的点击事件怎么也设置不了。翻遍了百度谷歌,也没有搜到什么有用的结果,最后还是得靠自己。

布局很简单,就一个TextView与一个Button

完整代码如下(大家来找茬)

布局xml:

<layout>
    <data>
        <variable
            name="viewModel"
            type="top.littlefogcat.databinding.MyViewModel" />
    </data>

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

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{String.valueOf(viewModel.time)}" />

        <Button
            android:id="@+id/btnGetTime"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="@{()->viewModel.getTime()}"
            android:text="Get Time" />

    </LinearLayout>
</layout>

MainActivity:

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

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = DataBindingUtil.setContentView<ActivityMainBinding>(this, R.layout.activity_main)
            .apply {
                viewModel = MyViewModel()
                lifecycleOwner = this@MainActivity
            }
    }

}

ViewModel:

class MyViewModel {
    val time = MutableLiveData<Long>().apply { value = System.currentTimeMillis() }

    fun getTime() {
        time.value = System.currentTimeMillis()
    }
}

乍一看是没什么问题啊! 哪怕翻来覆去的看也没什么问题啊!可是为什么点击这个Button就没反应呢?折腾了一个晚上,终于在不经意间发现了真相。

(无奖竞猜:造成这个情况的原因是什么?)

谜底揭晓

当我不经意间用中键点击ButtononClick表达式中的viewModel.getTime()函数,好家伙,给我跳转到了MyViewModel类中的time变量上去了

再看看MyViewModel

class MyViewModel {
    val time = MutableLiveData<Long>().apply { value = System.currentTimeMillis() }

    fun getTime() {
        time.value = System.currentTimeMillis()
    }
}

敢情getTime()自动被覆盖成了time变量的get函数了!?还有没有天理有没有王法了?

于是,修改一下getTime()的函数名,就不要以“get”开头了,就叫currentTime()吧。

class MyViewModel {
    val time = MutableLiveData<Long>().apply { value = System.currentTimeMillis() }

    fun currentTime() {
        time.value = System.currentTimeMillis()
    }
}

然后改一下Button

<Button
    android:id="@+id/btnGetTime"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:onClick="@{()->viewModel.currentTime()}"
    android:text="Get Time" />

这下再运行,点击事件就正常了。