class TestActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding = DataBindingUtil.setContentView<LayoutTestBinding>(this, R.layout.layout_test)
val adapter = CustomAdapter()
val viewModel = TestViewModel()
binding.apply {
lifecycleOwner = this@TestActivity
recycle.adapter = adapter
testViewModel = viewModel
}
viewModel.requestData()
viewModel.datas.observe(this, Observer {
adapter.submitList(it)
})
viewModel.networkStatus.observe(this, Observer {
adapter.setRequestStatus(it)
})
}
}
ViewModel
class TestViewModel() : ViewModel() {
private val dataRepository = DataRepository()
lateinit var datas: LiveData<PagedList<DataBean>>
private val sourceFactory = CustomPageDataSourceFactory(dataRepository)
//保证Obser里面的liveData是同一个
val networkStatus = Transformations.switchMap(sourceFactory.dataSource) { it.requestStatus }
fun requestData() {
datas = LivePagedListBuilder(
sourceFactory, PagedList.Config.Builder()
.setPageSize(20)
.setEnablePlaceholders(true)
.setInitialLoadSizeHint(20)
.build()
).build()
}
}
DataSource
class CustomPageDataSourceFactory(val repository: DataRepository) : DataSource.Factory<Int, DataBean>() {
val dataSource = MutableLiveData<CustomPageDataSource>()
override fun create(): DataSource<Int, DataBean> {
val customPageDataSource = CustomPageDataSource(repository)
dataSource.postValue(customPageDataSource)
return customPageDataSource
}
}
PageKeyedDataSource
class CustomPageDataSource(private val repository: DataRepository) : PageKeyedDataSource<Int, DataBean>() {
val requestStatus = MutableLiveData<RequestStatus>()
override fun loadInitial(params: LoadInitialParams<Int>, callback: LoadInitialCallback<Int, DataBean>) {
val data = repository.loadData(params.requestedLoadSize)
callback.onResult(data, null, 2)
}
override fun loadAfter(params: LoadParams<Int>, callback: LoadCallback<Int, DataBean>) {
requestStatus.postValue(RequestStatus(Status.LOADING))
Thread.sleep(3000)
requestMoreData(params, callback)
requestStatus.postValue(RequestStatus(Status.SUCCESS))
}
private fun requestMoreData(
params: LoadParams<Int>,
callback: LoadCallback<Int, DataBean>
) {
val data = repository.loadPageData(params.key, params.requestedLoadSize)
data?.let {
callback.onResult(data, params.key + 1)
}
}
override fun loadBefore(params: LoadParams<Int>, callback: LoadCallback<Int, DataBean>) {
}
}
DataRepository
class DataRepository {
private val data = ArrayList<DataBean>()
init {
for (i in 1..50) {
val bean = DataBean(i.toLong(), "name $i")
data.add(bean)
}
}
fun loadData(size: Int): List<DataBean> {
return data.subList(0, size)
}
fun loadPageData(page: Int, size: Int): List<DataBean>? {
MatrixLog.d("haha", " loadPageData $page $size")
val list = ArrayList<DataBean>()
for (i in 1..20) {
val bean = DataBean(i.toLong(), "aaaaaa $i")
list.add(bean)
}
return list
}
}
状态信息
data class DataBean(var id: Long, var name: String)
enum class Status {
LOADING,
SUCCESS,
ERROR,
}
class RequestStatus(val status: Status) {
fun isLoading(): Boolean = status == Status.LOADING
fun isSuccess(): Boolean = status == Status.SUCCESS
fun isError(): Boolean = status == Status.ERROR
}
PagedListAdapter
class CustomAdapter : PagedListAdapter<DataBean, RecyclerView.ViewHolder>(DIFF_CALLBACK) {
private var status: RequestStatus? = null
private val TYPE_ITEM = 0
private val TYPE_FOOTER = 1
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return when (viewType) {
TYPE_ITEM -> CustomViewHolder(parent)
TYPE_FOOTER -> {
FooterViewHolder(parent)
}
else -> throw IllegalArgumentException("$viewType")
}
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
when (getItemViewType(position)) {
TYPE_ITEM -> (holder as CustomViewHolder).bindTo(getItem(position))
TYPE_FOOTER -> {
(holder as FooterViewHolder)
}
}
}
override fun getItemViewType(position: Int): Int {
return if (position == itemCount - 1 && hasMore()) {
TYPE_FOOTER
} else {
TYPE_ITEM
}
}
private fun hasMore() =
if (status == null)
false
else status!!.isLoading()
override fun getItemCount(): Int {
return super.getItemCount() + if (hasMore()) 1 else 0
}
companion object {
private val DIFF_CALLBACK = object : DiffUtil.ItemCallback<DataBean>() {
override fun areItemsTheSame(
oldConcert: DataBean,
newConcert: DataBean
): Boolean =
oldConcert.id == newConcert.id
override fun areContentsTheSame(
oldConcert: DataBean,
newConcert: DataBean
): Boolean =
oldConcert == newConcert
}
}
fun setRequestStatus(status: RequestStatus) {
this.status = status
notifyDataSetChanged()
}
}
class CustomViewHolder(parent: ViewGroup) : RecyclerView.ViewHolder(
LayoutInflater.from(parent.context).inflate(R.layout.test_item, parent, false)
) {
private val nameView = itemView.findViewById<TextView>(R.id.name)
var item: DataBean? = null
fun bindTo(item: DataBean?) {
this.item = item
nameView.text = item?.name
}
}
class FooterViewHolder(parent: ViewGroup) : RecyclerView.ViewHolder(
LayoutInflater.from(parent.context).inflate(R.layout.test_footer, parent, false)
) {
}
网友评论