美文网首页安卓开发安卓开发
利用google官方控件实现下拉刷新和上拉加载(SwipeRef

利用google官方控件实现下拉刷新和上拉加载(SwipeRef

作者: 蓝不蓝编程 | 来源:发表于2019-03-26 16:42 被阅读13次

    简要介绍

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

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

    实现效果

    image

    主要实现代码(完整代码见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://www.jianshu.com/p/442339952f26
    更多技术总结好文,请关注:「程序园中猿」

    相关文章

      网友评论

        本文标题:利用google官方控件实现下拉刷新和上拉加载(SwipeRef

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