📜  如何使用MVVM和Room Database构建杂货Android应用?(1)

📅  最后修改于: 2023-12-03 14:52:03.498000             🧑  作者: Mango

如何使用MVVM和Room Database构建杂货Android应用?

MVVM是一种软件架构设计模式,有利于分离应用程序的UI层和业务逻辑层。Room Database是一个在SQLite上提供了一个抽象层,使得开发者可以使用面向对象的代码来访问数据库。在本文中,我们将使用MVVM和Room Database来构建一个杂货清单应用程序。

1. 创建杂货清单项目

首先,我们需要创建一个新的Android Studio项目并将其命名为“GroceryList”。选择Empty Activity作为模板,并单击Finish按钮。在这个应用程序中,我们将使用ViewModel来控制用户界面和数据交互。它会绑定到Activity或Fragment的生命周期,以确保数据正确地退出应用程序。

2. 添加房间数据库依赖关系

现在,我们需要在build.gradle文件中添加Room Database的依赖项。在您的app模块中,打开build.gradle并在dependencies块中添加以下行:

implementation "androidx.room:room-runtime:2.2.6"
annotationProcessor "androidx.room:room-compiler:2.2.6"

此外,我们需要在build.gradle文件的android部分中添加以下行来启用Java 8的Lambda表达式:

compileOptions {
  sourceCompatibility JavaVersion.VERSION_1_8
  targetCompatibility JavaVersion.VERSION_1_8
}

这是为了确保我们可以在ViewModel中使用Java 8的Lambda表达式。

3. 创建实体类

我们需要先创建实体类,作为表的映射。

@Entity(tableName = "grocery_items")
data class GroceryItem(
    @PrimaryKey(autoGenerate = true)
    var id: Int,
    var name: String,
    var quantity: Int
)

表名为grocery_items,包括三个字段。id为主键,自动生成。name和quantity为属性。

4. 创建Dao

创建用于访问数据库的数据访问对象(DAO)接口:

@Dao
interface GroceryItemDao {
    @Insert
    suspend fun insertGroceryItem(groceryItem: GroceryItem)

    @Update
    suspend fun updateGroceryItem(groceryItem: GroceryItem)

    @Delete
    suspend fun deleteGroceryItem(groceryItem: GroceryItem)

    @Query("SELECT * FROM grocery_items")
    suspend fun getAllGroceryItems(): List<GroceryItem>
}

我们定义了四个方法:插入,更新,删除和从表中检索所有元素。我们使用@Insert、@Update和@Delete注释来指定相应的操作。@Query注释允许我们手动指定查询语句以检索所有元素。

5. 创建Database

现在,创建Room Database:

@Database(entities = [GroceryItem::class], version = 1)
abstract class AppDatabase : RoomDatabase() {
    abstract fun groceryItemDao(): GroceryItemDao
}

@Database注释指定了表集。我们在这里仅指定一个表GroceryItem。version指定的是数据库版本号。 每当我们改变了@Database注释之后的代码,我们都需要在AppDatabase子类中将version递增。数据库将会执行一些自动升级脚本,这将会影响您的模式。

6. 实例化Database

为了让我们的应用程序使用数据库,我们需要实例化AppDatabase。

val appDatabase = Room.databaseBuilder(
    applicationContext,
    AppDatabase::class.java, "grocery.db"
).build()

我们使用Room.databaseBuilder()方法和AppDatabase类来初始化数据库。这里我们给它一个dbName参数为"grocery.db"。

7. 创建ViewModel

创建一个用于保存和管理UI相关数据的ViewModel:

class GroceryListViewModel(private val db: AppDatabase) : ViewModel() {

    private val groceryItemDao = db.groceryItemDao()

    val groceryItemListLiveData: LiveData<List<GroceryItem>> =
        groceryItemDao.getAllGroceryItems().asLiveData()

    fun addGroceryItem(groceryItem: GroceryItem) {
        viewModelScope.launch(Dispatchers.IO) {
            groceryItemDao.insertGroceryItem(groceryItem)
        }
    }

    fun updateGroceryItem(groceryItem: GroceryItem) {
        viewModelScope.launch(Dispatchers.IO) {
            groceryItemDao.updateGroceryItem(groceryItem)
        }
    }

    fun deleteGroceryItem(groceryItem: GroceryItem) {
        viewModelScope.launch(Dispatchers.IO) {
            groceryItemDao.deleteGroceryItem(groceryItem)
        }
    }
}

我们用db参数初始化数据库,使用Dao方法获取groceryItemListLiveData,它将存储在此表中的所有项目列表。此LiveData是在后台线程(IO线程)上访问数据库后执行的。

我们使用Kotlin协程来执行插入,更新和删除操作。他们在IO线程上运行。

8. 修改Activity

现在,我们需要更新MainActivity与GroceryListViewModel交互。MainActivity中包括RecyclerView以显示GroceryItem列表,以及EditText和Button以添加新的GroceryItems。

MainActivity:

class MainActivity : AppCompatActivity() {
    private lateinit var groceryListAdapter: GroceryListAdapter
    private lateinit var groceryListViewModel: GroceryListViewModel

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val appDatabase = Room.databaseBuilder(
            applicationContext,
            AppDatabase::class.java, "grocery.db"
        ).build()

        groceryListViewModel = ViewModelProvider(
            this,
            ViewModelProvider.AndroidViewModelFactory(application)
        ).get(GroceryListViewModel::class.java)

        groceryListAdapter = GroceryListAdapter(mutableListOf())

        recyclerView.apply {
            adapter = groceryListAdapter
            layoutManager = LinearLayoutManager(this@MainActivity)
        }

        groceryListViewModel.groceryItemListLiveData.observe(
            this,
            Observer { it ->
                it?.let {
                    groceryListAdapter.updateGroceryItemList(it)
                }
            }
        )

        addButton.setOnClickListener {

            val name = editText.text.toString().trim()

            if (name.isNotEmpty()) {
                groceryListViewModel.addGroceryItem(
                    GroceryItem(0, name, 0)
                )

                editText.text.clear()
            }
        }

        groceryListAdapter.onGroceryItemClick = { item ->

            val dialogView = LayoutInflater.from(this).inflate(R.layout.dialog_grocery_item, null)

            dialogView.itemNameEditText.setText(item.name)
            dialogView.itemQuantityEditText.setText(item.quantity.toString())

            AlertDialog.Builder(this)
                .setTitle("Edit Grocery Item")
                .setView(dialogView)
                .setPositiveButton("SAVE") { _, _ ->

                    val name = dialogView.itemNameEditText.text.toString().trim()
                    val quantity = dialogView.itemQuantityEditText.text.toString().trim().toIntOrNull()
                        ?: 0

                    if (name.isNotEmpty()) {
                        groceryListViewModel.updateGroceryItem(
                            GroceryItem(item.id, name, quantity)
                        )
                    }
                }
                .setNegativeButton("CANCEL", null)
                .create().show()
        }

        groceryListAdapter.onGroceryItemDeleteClick = { item ->
            groceryListViewModel.deleteGroceryItem(item)
        }
    }
}

在onCreate方法中,我们实例化GroceryListViewModel和GroceryListAdapter,以及RecyclerView、EditText和Button。设置adapter和layoutManager。

我们使用observe()方法监听groceryItemListLiveData的变化,以便更新RecyclerView。它将显示所有GroceryItem对象。如果GroceryItem对象更改,则它们将自动刷新。

点击添加按钮时,我们添加新的GroceryItem并清除EditText。

当单击RecyclerView中的元素时,它会弹出一个对话框,您可以编辑该项的名称和数量。单击“SAVE”按钮时,将会更新此项。

9. 构建和运行应用程序

我们已经完成所有必要的步骤。现在,我们只需构建并运行我们的应用程序。Gradle将下载所有依赖项并生成应用程序的APK文件。最后,它将在连接的设备或模拟器上安装应用程序。

这就是它了!您现在已经学会了如何使用MVVM和Room Database构建杂货Android应用程序。现在是时候探索这些概念的更深入的用法并将其引入新的应用程序中。