一、实现目标
在Android应用中使用MVVM架构实现按钮点击后,通过数据绑定更新TextView显示数字的功能
二、学习目标
初步了解MVVM框架和其相关组件并完成一个简单的实践
三、MVVM简介
MVVM实践中通常涵盖了以下几个关键组件:
ViewModel: ViewModel是MVVM中的一部分,负责管理与UI相关的数据和业务逻辑。它存储和处理UI所需的数据,以确保数据的一致性和可观察性。
LiveData: LiveData是一个用于在应用程序组件之间进行观察者模式通信的生命周期感知型数据持有类。LiveData可以与ViewModel一起使用,确保数据的变化能够在UI组件的生命周期范围内被观察和更新。
Data Binding: 数据绑定是Android中的一个库,允许您在布局文件中声明性地将界面组件与应用程序的数据源绑定。通过数据绑定,可以简化UI更新的代码,并实现更紧密的视图和数据之间的关联。
Lifecycle: Lifecycle是Android架构组件之一,用于处理应用程序组件(如Activity和Fragment)的生命周期管理。在MVVM中,ViewModel可以与Lifecycle配合使用,确保在合适的生命周期阶段进行数据的加载和清理。
四、实现
1. 添加依赖: 首先,在你的build.gradle
文件中添加以下依赖:
kts
android {
...
buildFeatures {
dataBinding = true
}
}
dependencies {
...
implementation ('androidx.lifecycle:lifecycle-viewmodel:2.4.0')
implementation ('androidx.lifecycle:lifecycle-livedata:2.4.0')
}
2. 创建ViewModel类:
这里就是实现了一个很简单的功能,数字++
java
public class MyViewModel extends ViewModel {
private MutableLiveData<Integer> count = new MutableLiveData<>(0);
public LiveData<Integer> getCount() {
return count;
}
public void incrementCount() {
count.setValue(count.getValue() + 1);
}
}
3. 创建Activity: 在Activity的onCreate方法中设置数据绑定,关联ViewModel和布局。
这里先提供完整的代码,再分行解释
java
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityMainBinding mbinding= DataBindingUtil.setContentView(this,R.layout.activity_main);
MyViewModel viewModel=new ViewModelProvider(this).get(MyViewModel.class);
mbinding.setViewModel(viewModel);
mbinding.setLifecycleOwner(this);
}
}
首先:
java
ActivityMainBinding mbinding= DataBindingUtil.setContentView(this,R.layout.activity_main);
这里我们没有再使用activity的setContentView了而是使用DataBindingUtil.setContentView(this, R.layout.activity_main)这个方法。
这个方法会将给定的布局文件 R.layout.activity_main
与当前的 Activity(this)
进行关联,这个值给到mbinding变量,之后即可通过mbinding变量访问布局文件中的各种视图组件
java
MyViewModel viewModel=new ViewModelProvider(this).get(MyViewModel.class);
ViewModelProvider
是 Android 架构组件中用于创建和管理 ViewModel
实例的类。在构造函数中传递 this
表示使用当前的 Activity
作为 ViewModel
的拥有者(owner)
使用 get
方法并传入 MyViewModel.class
,以获取与 MyViewModel
类相关联的 ViewModel
实例。
将获取到的 ViewModel
实例赋值给 viewModel
变量。这个 viewModel
对象就是与当前 Activity
相关联的 MyViewModel
对象,可以通过它来访问和管理与 UI 相关的数据和逻辑。
java
mbinding.setViewModel(viewModel);
这行代码是在使用 Data Binding 来将 ViewModel
与布局文件关联起来。
kotlin
mbinding.setLifecycleOwner(this);
这里是在设置 Data Binding 的生命周期所有者(Lifecycle Owner)。这是在确保 LiveData 与视图(Activity 或 Fragment)的生命周期绑定,以便在适当的生命周期阶段观察并更新数据。
4. 创建布局文件:
xml
<layout
xmlns:android="http://schemas.android.com/apk/res/android"
>
<data>
<variable name="viewModel"
type="com.example.mvvmtest3.MyViewModel"/>
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@{String.valueOf(viewModel.count)}"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="@{()->viewModel.incrementCount()}"/>
</LinearLayout>
</layout>
可以看到
首先 ,整个布局被layout包裹住,为的是在原本的LinearLayout同级添加一个data
标签,并在其中添加了一个name为viewModel、type为MyViewModel的variable
标签
其次,我们没有给textview和button设置id,而是设置的text属性和onclick属性
五、总结
初次接触MVVM框架,虽然对于理论部分还不是非常了解,但是已经可以感受到设计者的一个动机:将数据的管理和业务逻辑从 UI 分离出来。但是其实MVC,MVP模式也都有这个动机,MVC的view和model可以直接通信,MVP的view和model是独立的,但是并没有用到数据绑定。
而在这个例子中,MVVM模式相比MVP模式不一样的双向绑定还是没有体现出来,后续或许我会补充别的例子。
以及我发现我对一些经典的设计模式也不太了解,所以开始看head first设计模式,或许会补充一些读后感。