Android架构组件中的 MVVM(Model-View-ViewModel)模式是实现 UI 和业务逻辑分离的有效方式。通过数据绑定(Data Binding),你可以更简洁地更新 UI,减少样板代码。下面是 MVVM 模式在 Android 中的实战应用以及一些数据绑定的技巧。
1. MVVM架构简介
- Model:负责数据的获取和处理,通常与数据库或网络进行交互。
 - View:用户界面,展示数据并接收用户输入。
 - ViewModel:连接 Model 和 View,负责处理 UI 逻辑并准备数据供 View 使用。
 
2. Android数据绑定库
Android 数据绑定库允许你将 UI 组件与应用的数据源绑定在一起。通过数据绑定,你可以减少在 Activity 或 Fragment 中的代码量。
3. 创建 MVVM 项目
以下是一个基本的 MVVM 项目的结构和实现步骤:
- 添加依赖
在build.gradle文件中添加数据绑定和其他必要的依赖: 
            
            
              groovy
              
              
            
          
          android {
    ...
    buildFeatures {
        dataBinding true
    }
}
dependencies {
    implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.4.0"
    implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.4.0"
    // 其他依赖
}
        - 创建 Model
创建一个简单的 Model 类,例如 User: 
            
            
              bash
              
              
            
          
          data class User(val name: String, val age: Int)
        - 创建 ViewModel
创建一个 UserViewModel 类,继承自 ViewModel,并使用 LiveData 来持有数据。 
            
            
              kotlin
              
              
            
          
          import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
class UserViewModel : ViewModel() {
    private val _user = MutableLiveData<User>()
    val user: LiveData<User> get() = _user
    fun setUser(name: String, age: Int) {
        _user.value = User(name, age)
    }
}
        - 创建布局文件
在布局文件中使用数据绑定。创建一个 activity_main.xml 文件: 
            
            
              xml
              
              
            
          
          <layout xmlns:android="http://schemas.android.com/apk/res/android">
    <data>
        <variable
            name="viewModel"
            type="com.example.app.UserViewModel" />
    </data>
    <LinearLayout
        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="@{viewModel.user.name}" />
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{String.valueOf(viewModel.user.age)}" />
        <EditText
            android:id="@+id/nameInput"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="Enter name" />
        <EditText
            android:id="@+id/ageInput"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="Enter age" />
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Submit"
            android:onClick="@{() -> viewModel.setUser(nameInput.text.toString(), Integer.parseInt(ageInput.text.toString()))}" />
    </LinearLayout>
</layout>
        - 在 Activity 中绑定 ViewModel
在MainActivity中进行数据绑定和 ViewModel 的初始化: 
            
            
              kotlin
              
              
            
          
          import android.os.Bundle
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.databinding.DataBindingUtil
import com.example.app.databinding.ActivityMainBinding
class MainActivity : AppCompatActivity() {
    private lateinit var binding: ActivityMainBinding
    private val viewModel: UserViewModel by viewModels()
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
        binding.viewModel = viewModel
        binding.lifecycleOwner = this
        // 观察用户数据变化
        viewModel.user.observe(this) { user ->
            // 这里可以处理用户数据变化,例如更新 UI
        }
    }
}
        4. 数据绑定技巧
- 双向数据绑定:可以在布局中使用 
@={}语法实现双向绑定。例如,对于输入框,可以直接绑定到 ViewModel 的属性,这样在输入框中输入的值会自动更新到 ViewModel 中。 
            
            
              xml
              
              
            
          
          <EditText
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="@={viewModel.user.name}" />
        - 格式化数据:可以使用格式化函数来处理数据,例如将数字格式化为字符串。
 
            
            
              xml
              
              
            
          
          android:text="@{String.valueOf(viewModel.user.age)}"
        - 自定义 Binding Adapter:如果需要对某个属性进行特殊处理,可以创建自定义的 Binding Adapter。
 
            
            
              kotlin
              
              
            
          
          @BindingAdapter("app:customText")
fun setCustomText(view: TextView, text: String?) {
    view.text = "Custom: $text"
}
        5. 总结
使用 MVVM 结合数据绑定能够显著提升 Android 应用的可维护性和可读性。通过将 UI 逻辑与数据处理分开,你可以更容易地进行单元测试和代码重用。数据绑定的技巧也能帮助你减少样板代码,提升开发效率。