美文网首页
kotlin--Flow结合Room运用

kotlin--Flow结合Room运用

作者: aruba | 来源:发表于2021-09-20 21:05 被阅读0次

    kotlin结合Room在实际项目中的运用

    架构还是MVVM,DataBinding+ViewModel+LiveData的组合

    效果:

    1.首先添加Room依赖

    添加kapt插件:

    plugins {
        id 'com.android.application'
        id 'kotlin-android'
        id 'kotlin-kapt'
    }
    
        def room_version = "2.3.0"
        implementation "androidx.room:room-runtime:$room_version"
        implementation "androidx.room:room-ktx:$room_version"
        kapt "androidx.room:room-compiler:$room_version"
    
    2.创建数据库相关类

    entity:

    package com.aruba.flowapplyapplication.database.entity
    
    import androidx.room.Entity
    import androidx.room.PrimaryKey
    
    /**
     * Created by aruba on 2021/9/20.
     */
    @Entity
    data class UserInfo(
        @PrimaryKey val id: Int,
        var userName: String,
        var age: Int
    )
    

    Dao,之前我们需要使用异步任务操作Dao,kotlin则可以使用挂起函数,标识使用协程操作:

    package com.aruba.flowapplyapplication.database.dao
    
    import androidx.room.Dao
    import androidx.room.Insert
    import androidx.room.OnConflictStrategy
    import androidx.room.Query
    import com.aruba.flowapplyapplication.database.entity.UserInfo
    import kotlinx.coroutines.flow.Flow
    
    /**
     * Created by aruba on 2021/9/20.
     */
    @Dao
    interface UserInfoDao {
        //id重复的替换
        @Insert(onConflict = OnConflictStrategy.REPLACE)
        suspend fun insert(userInfo: UserInfo)
    
        //返回Flow,由于Flow需要使用collect,该函数为挂起函数,所以不需要加suspend了
        @Query("SELECT * FROM userinfo")
        fun getUserInfoList(): Flow<List<UserInfo>>
    }
    

    Database:

    package com.aruba.flowapplyapplication.database
    
    import android.content.Context
    import androidx.room.Database
    import androidx.room.Room
    import androidx.room.RoomDatabase
    import com.aruba.flowapplyapplication.database.dao.UserInfoDao
    import com.aruba.flowapplyapplication.database.entity.UserInfo
    
    private const val DB_NAME: String = "my.db"
    
    /**
     * Created by aruba on 2021/9/20.
     */
    @Database(entities = [UserInfo::class], version = 1, exportSchema = true)
    abstract class MyDatabase : RoomDatabase() {
    
        abstract fun getUserDao(): UserInfoDao
    
        companion object {
            private var instance: MyDatabase? = null
    
            fun getInstance(): MyDatabase {
                checkNotNull(instance) { "init has not been called" }
                return instance as MyDatabase
            }
    
            fun init(context: Context) {
                synchronized(this) {
                    instance ?: Room.databaseBuilder(
                        context,
                        MyDatabase::class.java, DB_NAME
                    ).build().let { instance = it }
                }
            }
        }
    }
    
    3.定义ViewModel

    使用LiveData对三个EditText进行双向绑定

    package com.aruba.flowapplyapplication.viewmodel
    
    import android.view.View
    import androidx.lifecycle.MutableLiveData
    import androidx.lifecycle.ViewModel
    import androidx.lifecycle.viewModelScope
    import com.aruba.flowapplyapplication.database.MyDatabase
    import com.aruba.flowapplyapplication.database.dao.UserInfoDao
    import com.aruba.flowapplyapplication.database.entity.UserInfo
    import kotlinx.coroutines.Dispatchers
    import kotlinx.coroutines.flow.Flow
    import kotlinx.coroutines.flow.collect
    import kotlinx.coroutines.flow.flowOn
    import kotlinx.coroutines.launch
    import androidx.databinding.ObservableField
    
    
    /**
     * Created by aruba on 2021/9/20.
     */
    class UserInfoViewModel : ViewModel() {
        val id = MutableLiveData<String>()
        val name = MutableLiveData<String>()
        val age = MutableLiveData<String>()
    
        private val userInfoDao: UserInfoDao by lazy {
            MyDatabase.getInstance().getUserDao()
        }
    
        fun insert(v: View) {
            if (id.value == null || name.value == null || age.value == null) {
                return
            }
    
            val userInfo = UserInfo(id.value!!.toInt(), name.value!!, age.value!!.toInt())
            viewModelScope.launch(Dispatchers.IO) {
                userInfoDao.insert(userInfo)
            }
        }
    
        fun getUserInfo(): Flow<List<UserInfo>> {
            return userInfoDao
                .getUserInfoList()
                .flowOn(Dispatchers.IO)
        }
    
    }
    
    4.定义RecyclerViewAdapter
    package com.aruba.flowapplyapplication.adapter
    
    import android.view.LayoutInflater
    import android.view.ViewGroup
    import androidx.databinding.DataBindingUtil
    import androidx.recyclerview.widget.RecyclerView
    import com.aruba.flowapplyapplication.R
    import com.aruba.flowapplyapplication.database.entity.UserInfo
    import com.aruba.flowapplyapplication.databinding.ItemUserinfoBinding
    
    /**
     * Created by aruba on 2021/9/20.
     */
    class UserInfoAdapter() : RecyclerView.Adapter<UserInfoAdapter.MyViewHolder>() {
        private var data = ArrayList<UserInfo>()
    
        class MyViewHolder(val binding: ItemUserinfoBinding) : RecyclerView.ViewHolder(binding.root)
    
        fun setData(data: List<UserInfo>) {
            this.data.clear()
            this.data.addAll(data)
            notifyDataSetChanged()
        }
    
        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
            val binding: ItemUserinfoBinding = DataBindingUtil.inflate(
                LayoutInflater.from(parent.context),
                R.layout.item_userinfo,
                parent, false
            )
    
            return MyViewHolder(binding)
        }
    
        override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
            holder.binding.userInfo = data[position]
        }
    
        override fun getItemCount(): Int {
            return data.size
        }
    }
    
    5.Fragment中实例化ViewModel,以及进行数据绑定等操作
    package com.aruba.flowapplyapplication
    
    import android.os.Bundle
    import androidx.fragment.app.Fragment
    import android.view.LayoutInflater
    import android.view.View
    import android.view.ViewGroup
    import androidx.databinding.DataBindingUtil
    import androidx.lifecycle.ViewModelProvider
    import androidx.lifecycle.lifecycleScope
    import androidx.recyclerview.widget.LinearLayoutManager
    import com.aruba.flowapplyapplication.adapter.UserInfoAdapter
    import com.aruba.flowapplyapplication.database.MyDatabase
    import com.aruba.flowapplyapplication.databinding.FragmentRoomBinding
    import com.aruba.flowapplyapplication.viewmodel.UserInfoViewModel
    import kotlinx.coroutines.flow.collect
    
    class RoomFragment : Fragment() {
    
        override fun onCreateView(
            inflater: LayoutInflater, container: ViewGroup?,
            savedInstanceState: Bundle?
        ): View? {
            //初始化数据库
            MyDatabase.init(requireContext())
            
            val inflate = DataBindingUtil.inflate<FragmentRoomBinding>(
                layoutInflater,
                R.layout.fragment_room,
                container,
                false
            )
    
            //实例化ViewModel
            val userInfoViewModel = ViewModelProvider(
                this,
                ViewModelProvider.AndroidViewModelFactory(requireActivity().application)
            ).get(UserInfoViewModel::class.java)
            inflate.userInfoViewModel = userInfoViewModel
            inflate.recyclerview.adapter = UserInfoAdapter()
            inflate.recyclerview.layoutManager = LinearLayoutManager(context)
            inflate.lifecycleOwner = viewLifecycleOwner
    
            //开启协程对数据库的表进行监听
            lifecycleScope.launchWhenCreated {
                //每当UserInfo表发生变化,Flow都会把UserInfo列表发射出去,那么我们
                //在collect中就可以获取到
                userInfoViewModel.getUserInfo().collect {
                    (inflate.recyclerview.adapter as UserInfoAdapter).setData(it)
                }
            }
            return inflate.root
        }
    
    }
    
    项目地址:https://gitee.com/aruba/flow-apply-application.git

    相关文章

      网友评论

          本文标题:kotlin--Flow结合Room运用

          本文链接:https://www.haomeiwen.com/subject/feumgltx.html