利用google官方控件实现下拉刷新和上拉加载(SwipeRef
2019-03-26 本文已影响13人
蓝不蓝编程
简要介绍
现在网上有各种下拉刷新控件,各种炫酷(如:SmartRefreshLayout).不过如果没有特别要求时,官方的控件就够用了,关键时,稳定,还好用.
- SwipeRefreshLayout 用于实现下拉刷新
- Paging 用于实现自动上拉加载数据,完全不用在activity中操心下一页加载的烦心事.
实现效果
image主要实现代码(完整代码见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
安卓开发技术分享: https://www.jianshu.com/p/442339952f26
更多技术总结好文,请关注:「程序园中猿」