简要介绍
现在网上有各种下拉刷新控件,各种炫酷(如:SmartRefreshLayout).不过如果没有特别要求时,官方的控件就够用了,关键时,稳定,还好用.
- SwipeRefreshLayout 用于实现下拉刷新
- Paging 用于实现自动上拉加载数据,完全不用在activity中操心下一页加载的烦心事.
实现效果
主要实现代码(完整代码见Demo源代码)
- 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
        }
    }
}- 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>- 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
    }
}- 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")
            }
        }
    }
}- 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()
                )
            }
    }
}- 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
更多技术总结好文,请关注:「程序园中猿」










