美文网首页
Jetpack-Paging

Jetpack-Paging

作者: T_Carbon | 来源:发表于2020-05-14 15:06 被阅读0次
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)
) {

}

相关文章

  • Jetpack-Paging

    ViewModel DataSource PageKeyedDataSource DataRepository 状...

网友评论

      本文标题:Jetpack-Paging

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