MVVM架构中UI事件(如onClick)的处理位置与方式咨询
从MVP转MVVM?看极简UI事件(onClick)处理示例
我完全懂这种找不到极简示例的 frustration!从MVP转MVVM的时候,最容易卡在UI事件的处理上——毕竟MVP里的双向契约太直观了。我给你整个最极简的例子,不管用不用DataBinding,都能一眼明白MVVM怎么处理点击事件:
基础版(不用DataBinding)
先写ViewModel,它只负责业务逻辑,完全不关心View:
class MyViewModel : ViewModel() { // 处理按钮点击的方法 fun onButtonClicked() { // 这里写你的业务逻辑:比如请求接口、更新LiveData状态等 Log.d("MVVM Demo", "按钮被点击啦!") } }
然后是View层(比如Activity),它持有ViewModel的引用(通过ViewModelProvider保证生命周期安全),点击时直接调用ViewModel的方法:
class MyActivity : AppCompatActivity() { private lateinit var viewModel: MyViewModel override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_my) // 获取ViewModel实例 viewModel = ViewModelProvider(this)[MyViewModel::class.java] // 给按钮设置点击监听,直接调用ViewModel的业务方法 findViewById<Button>(R.id.my_button).setOnClickListener { viewModel.onButtonClicked() } } }
进阶版(用DataBinding,更贴合MVVM思想)
如果用DataBinding,连手动设置点击监听的代码都省了,直接在布局里绑定ViewModel的方法:
布局文件(activity_my.xml)
<?xml version="1.0" encoding="utf-8"?> <layout xmlns:android="http://schemas.android.com/apk/res/android"> <!-- 声明ViewModel变量 --> <data> <variable name="viewModel" type="com.example.MyViewModel" /> </data> <Button android:id="@+id/my_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="点我试试" <!-- 直接绑定ViewModel的点击方法 --> android:onClick="@{() -> viewModel.onButtonClicked()}" /> </layout>
Activity代码
class MyActivity : AppCompatActivity() { private lateinit var viewModel: MyViewModel private lateinit var binding: ActivityMyBinding override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // 初始化DataBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_my) viewModel = ViewModelProvider(this)[MyViewModel::class.java] // 把ViewModel绑定到布局 binding.viewModel = viewModel // 设置生命周期所有者,让DataBinding感知页面生命周期 binding.lifecycleOwner = this } }
核心区别对比MVP
和MVP的双向契约(View调用Presenter的接口方法,Presenter再回调View的接口)不同,MVVM里是单向依赖:
- View层只需要知道ViewModel的存在,调用它的业务方法就行
- ViewModel完全不了解View,只负责处理业务逻辑、维护数据状态
- 这种设计让ViewModel的复用性极强,而且单元测试不用Mock View接口,直接测业务逻辑就行
内容的提问来源于stack exchange,提问作者Marc Ebra
相关产品推荐
相关产品推荐

