利用google官方控件实现下拉刷新和上拉加载(SwipeRefreshLayout+Paging)

版权声明:本文为程序园中猿原创文章,转载请注明出处 https://blog.csdn.net/yinxing2008/article/details/88824042

简要介绍

现在网上有各种下拉刷新控件,各种炫酷(如:SmartRefreshLayout).不过如果没有特别要求时,官方的控件就够用了,关键时,稳定,还好用.

  1. SwipeRefreshLayout 用于实现下拉刷新
  2. Paging 用于实现自动上拉加载数据,完全不用在activity中操心下一页加载的烦心事.

实现效果

主要实现代码(完整代码见Demo源代码)

  1. UserActivity.kt
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()
        userRv.adapter = adapter
        viewModel.userList.observe(this, Observer { adapter.submitList(it) })

        //设置下拉刷新转圈的颜色
//        swipeRefreshLayout.setColorSchemeColors(Color.RED,Color.BLUE,Color.GREEN)
        swipeRefreshLayout.setOnRefreshListener {
            viewModel.deleteAll()
            viewModel.initData()
            swipeRefreshLayout.isRefreshing = false
        }
    }
}
  1. activity_user.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:id="@+id/swipeRefreshLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

    <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/userRv"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:clipToPadding="false"
            app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"/>

</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
  1. UserAdapter.kt
class UserAdapter : PagedListAdapter<User, UserAdapter.ViewHolder>(UserDiffCallback()) {
    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        val data = getItem(position) ?: return
        holder.itemView.userTv.text = data.name
    }

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

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

private class UserDiffCallback : DiffUtil.ItemCallback<User>() {
    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.kt
class UserViewModel internal constructor(private val userRepository: UserRepository) : ViewModel() {
    val userList = userRepository.getUserList()
    fun deleteAll()
    {
        GlobalScope.launch {
            userRepository.deleteAll()
        }
    }
    fun initData() {
        GlobalScope.launch {
            (1..1000).forEach {
                userRepository.addUser("user$it")
            }
        }
    }
}
  1. ViewModelFactory.kt
class ViewModelFactory private constructor(
    private val userRepository: UserRepository
) : ViewModelProvider.NewInstanceFactory() {

    @Suppress("UNCHECKED_CAST")
    override fun <T : ViewModel?> create(modelClass: Class<T>): T =
        with(modelClass) {
            when {
                isAssignableFrom(UserViewModel::class.java) -> {
                    UserViewModel(userRepository)
                }
                else ->
                    throw IllegalArgumentException("Unknown ViewModel: ${modelClass.name}")
            }

        } as T


    companion object {
        private var INSTANCE: ViewModelFactory? = null

        fun getInstance() =
            INSTANCE ?: synchronized(ViewModelFactory::class.java) {
                INSTANCE ?: ViewModelFactory(
                    InjectionUtil.getUserRepository()
                )
            }
    }
}
  1. UserRepository.kt
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 deleteAll() {
        withContext(Dispatchers.IO) {
            userDao.deleteAll()
        }
    }

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

        fun getInstance(userDao: UserDao) =
            instance ?: synchronized(this) {
                instance
                    ?: UserRepository(userDao).also { instance = it }
            }
    }
}

Demo源代码

https://gitee.com/cxyzy1/pullRefreshDemo

安卓开发技术分享: https://blog.csdn.net/yinxing2008/article/details/84555061
更多技术总结好文,请关注:「程序园中猿」

猜你喜欢

转载自blog.csdn.net/yinxing2008/article/details/88824042