安卓Jetpack版MVVM最简demo(ViewModel+LiveData+Room+Paging+RecyclerView)

简要介绍

本demo按照MVVM方式实现最简单的数据展示(支持自动分页加载)和删除的demo,用于展示一个完整的MVVM架构.

  1. 包含:ViewModel+LiveData+Room+Paging
  2. 语言:Kotlin
  3. 采用kotlin coroutines实现数据库操作
  4. 不包含databinding(对方比较之后,觉得databinding不够灵活而且还存在一些问题,具体百度搜索.不过demo里其实也附带了一个包含databinding的例子)

代码实现(只贴出重点代码,完整代码见源代码)

  1. UserActivity
class UserActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_user)
        val viewModel =  obtainViewModel(UserViewModel::class.java)
        val adapter = UserAdapter()
        adapter.setOnItemClick { user ->
            viewModel.delUser(user.id)
        }
        userRv.adapter = adapter
        viewModel.userList.observe(this, Observer { adapter.submitList(it) })
    }

}
  1. UserAdapter
class UserAdapter : PagedListAdapter(UserDiffCallback()) {
    private lateinit var onItemClick: (user: User) -> Unit
    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        val data = getItem(position) ?: return
        holder.itemView.userTv.text = data.name
        holder.itemView.setOnClickListener { onItemClick(data) }
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val view = LayoutInflater.from(parent.context).inflate(R.layout.item_user, parent, false)
        return ViewHolder(view)
    }

    infix fun setOnItemClick(onClick: (user: User) -> Unit) {
        this.onItemClick = onClick
    }

    class ViewHolder(itemView: View?) : RecyclerView.ViewHolder(itemView!!)
}

private class UserDiffCallback : DiffUtil.ItemCallback() {
    override fun areContentsTheSame(oldItem: User, newItem: User): Boolean {
        return oldItem.id == newItem.id
    }

    override fun areItemsTheSame(oldItem: User, newItem: User): Boolean {
        return oldItem == newItem
    }
}
  1. UserViewModel
class UserViewModel internal constructor(private val userRepository: UserRepository) : ViewModel() {
    val userList = userRepository.getUserList()

    fun delUser(id: Int) {
        GlobalScope.launch {
            userRepository.delUser(id)
        }
    }
}
  1. UserRepository
class UserRepository private constructor(private val userDao: UserDao) {

    fun getUserList() = userDao.getUserList().toLiveData(Config(
            pageSize = 30,
            enablePlaceholders = true))

    suspend fun addUser(name: String) {
        withContext(Dispatchers.IO) {
            val user = User(0, name)
            userDao.add(user)
        }
    }

    suspend fun delUser(id: Int) {
        withContext(Dispatchers.IO) {
            val user = User(id, "")
            userDao.del(user)
        }
    }

    companion object {
        @Volatile
        private var instance: UserRepository? = null

        fun getInstance(userDao: UserDao) =
                instance ?: synchronized(this) {
                    instance
                            ?: UserRepository(userDao).also { instance = it }
                }
    }
}
  1. UserDao
@Dao
interface UserDao {
    @Query("SELECT * FROM User")
    fun getUserList(): DataSource.Factory

    @Insert
    fun add(user: User)

    @Insert
    fun add(users: List)

    @Delete
    fun del(user:User)
}

Demo源代码

https://gitee.com/cxyzy1/mvvmDemo/tree/master/app_paging_no_databinding

安卓开发技术分享: https://www.jianshu.com/p/442339952f26
更多技术总结好文,请关注:「程序园中猿」

你可能感兴趣的:(安卓Jetpack版MVVM最简demo(ViewModel+LiveData+Room+Paging+RecyclerView))