美文网首页
RecyclerView之上拉加载下拉刷新

RecyclerView之上拉加载下拉刷新

作者: 小和尚恋红尘 | 来源:发表于2017-07-04 17:26 被阅读0次

一,下拉刷新数据

RecyclerView的控件的下拉刷新,官方提供了SwipeRefreshLayout类,用来实现下拉刷新。具体的使用方法如下:
先来看布局XML

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/activity_recycler_view_simple"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.tbwy.recyclerview.mvp.ease.RecyclerViewSimpleActivity">

    <android.support.v4.widget.SwipeRefreshLayout
        android:id="@+id/srl_refresh"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <android.support.v7.widget.RecyclerView
            android:id="@+id/rv_content"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_margin="@dimen/activity_horizontal_margin"
            app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
    </android.support.v4.widget.SwipeRefreshLayout>

</LinearLayout>

适配器Adapter的代码实现:

class RecyclerViewRefreshDataAdapter(var context: Context, var items: ArrayList<String>):RecyclerView.Adapter<RecyclerViewRefreshDataAdapter.ViewHolder>(){
    companion object{
        val TYPE_FOOTER = 1//添加Footer
        val TYPE_HEADER = 2//添加Header
        val TYPE_NORMAL = 0//两者都没有添加
        var headerView: View? = null
        var footerView: View? = null
    }
    var list = ArrayList<String>()
    init {
        list = items
    }

    /**
     * 添加头
     */
    fun setHeaderView(hv: View){
        headerView = hv
        notifyItemInserted(0)
    }

    /**
     * 添加尾
     */
    fun setFooterView(fv: View){
        footerView = fv
        notifyItemInserted(itemCount - 1)
    }

    /**
     * 添加到list起始位置
     */
    fun insertAddAll(addList: List<String>){
        list.addAll(0, addList)
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        if (getItemViewType(position) == TYPE_HEADER) return
        else if (getItemViewType(position) == TYPE_FOOTER) return
        else{
            if (holder is RecyclerViewRefreshDataAdapter.ViewHolder){
                Log.e("hjd", "position->"+ position)
                val positionTemp = if (headerView == null) position else position -1
                if (positionTemp < items.size){
                    holder.tv!!.text = items[positionTemp]
                    holder.itemView.tag= positionTemp
                }
            }
        }
    }

    override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): ViewHolder {
        if (headerView != null && viewType == TYPE_HEADER)
            return ViewHolder(headerView!!)
        if (footerView != null && viewType == TYPE_FOOTER)
            return ViewHolder(footerView!!)

        val view = LayoutInflater.from(context).inflate(R.layout.item_rc_4st, parent, false)
        view.setOnClickListener { view ->  listener?.onItemClick(view, view.tag as Int) }
        return ViewHolder(view)
    }

    override fun getItemCount(): Int{
        if (headerView != null && footerView != null)
            return items.size + 2
        else if(headerView == null && footerView == null)
            return items.size
        else
            return items.size + 1
    }

    override fun getItemViewType(position: Int): Int {
        if (headerView == null && footerView == null)
            return TYPE_NORMAL
        if(position == 0)
            return TYPE_HEADER
        if(position == itemCount-1)
            return TYPE_FOOTER
        return TYPE_NORMAL
    }

    class ViewHolder(itemTv: View):RecyclerView.ViewHolder(itemTv){
        var tv: TextView? = null

        init {
            if (headerView != itemTv && footerView != itemTv) {
                tv = itemTv.findViewById(R.id.tv) as TextView
            }
        }

    }

    override fun onDetachedFromRecyclerView(recyclerView: RecyclerView?) {
        super.onDetachedFromRecyclerView(recyclerView)
    }

    override fun onAttachedToRecyclerView(recyclerView: RecyclerView?) {
        val manager = recyclerView!!.layoutManager
        if (manager == null){
            Log.e("hjd", "layoutManager == null")
        }else {
            if (manager is GridLayoutManager) {
                val glm: GridLayoutManager = manager
                glm.spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() {
                    override fun getSpanSize(position: Int): Int {
                        if (getItemViewType(position) == TYPE_HEADER || getItemViewType(position) == TYPE_FOOTER)
                            return glm.spanCount
                        else
                            return 1
                    }
                }
            }
        }
    }

    override fun onViewAttachedToWindow(holder: ViewHolder?) {
        super.onViewAttachedToWindow(holder)
        val layoutParams = holder!!.itemView.layoutParams
        if (layoutParams != null && layoutParams is StaggeredGridLayoutManager.LayoutParams) {
            layoutParams.isFullSpan = getItemViewType(holder.layoutPosition) == TYPE_HEADER || getItemViewType(holder.layoutPosition) == TYPE_FOOTER
        }
    }


    private var listener: OnItemClickListener?=null

    fun setOnItemClickListener(l: OnItemClickListener): Unit{
        this.listener = l
    }
    interface OnItemClickListener{
        fun onItemClick(view: View, pos: Int)
    }

    fun addItem(pos: Int){
        list.add(pos, "Add item"+ pos)
        notifyItemInserted(pos)
    }

    fun delItem(pos: Int){
        list.removeAt(pos)
        notifyItemRemoved(pos)
    }
}

在Activity中的代码实现为:

            Handler().postDelayed({
            srl_refresh.overScrollMode = View.OVER_SCROLL_NEVER
            srl_refresh.setColorSchemeResources(R.color.colorAccent, R.color.colorPrimary, R.color.colorPrimaryDark)
            srl_refresh.setOnRefreshListener {
                srl_refresh.isRefreshing = false
                if (addList.size <= 0){
                    loadMoreData()
                }
                mAdapter!!.insertAddAll(addList)
                mAdapter!!.notifyDataSetChanged()
                showToast("刷新数据")
            }
        }, 2000)

运行程序,效果图如下:


Paste_Image.png Paste_Image.png

这样就实现了RecyclerView的下拉刷新数据。

二,上拉加载数据

官方提供了下拉刷新的类,我们很容易就可实现下拉刷新;但是却并没有实现上拉加载的类,因此我们需要自己实现。

2.1,简单实现

要实现上拉实现,我们需要调用滑动的监听方法addOnScrollListener,在这里我们来进行判定滑动的状态以加载数据

abstract class LoadRecyclerScrollListener(mgr: LinearLayoutManager) : RecyclerView.OnScrollListener(){
    var currPage : Int = 0//当前页数
    var previousTotal : Int = 0//已经加载Item数
    var visibleItemCount : Int? = null//可见Item数
    var totalItemCount : Int? = null//总共Item数
    var fristVisibleItem : Int? = null//第一个可见Item
    var loading = true//是否加载
    var linearLayoutManager: LinearLayoutManager? = null

    init {
        linearLayoutManager = mgr
    }

    override fun onScrolled(recyclerView: RecyclerView?, dx: Int, dy: Int) {
        super.onScrolled(recyclerView, dx, dy)
        visibleItemCount = linearLayoutManager!!.childCount
        totalItemCount = linearLayoutManager!!.itemCount
        fristVisibleItem = linearLayoutManager!!.findFirstVisibleItemPosition()

        if (loading){
            if (totalItemCount!! > previousTotal){
                loading = false
                previousTotal = totalItemCount!!
            }
        }

        if (!loading && (totalItemCount!! - visibleItemCount!!) <= fristVisibleItem!!){
            currPage++
            onLoadMore(currPage)
            loading = true
        }
    }

    abstract fun onLoadMore(page: Int)//加载数据抽象类
}

完成监听判定后,我们在代码中直接调用,加载数据

        rv_content.addOnScrollListener(object : EndlessRecyclerScrollListener(gridLayoutManager!!){
            override fun onLoadMore(page: Int) {
                Handler().postDelayed({
                    if (addList.size <= 0){
                        loadMoreData()
                    }
                    mAdapter!!.addAll(addList)
                    mAdapter!!.notifyDataSetChanged()
                }, 2000)
            }
        })

在上面的适配器Adapter中增加添加数据的方法:

/**
     * 添加到list末尾
     */
    fun addAll(addList: List<String>){
        list.addAll(addList)
    }

运行程序,效果图为:

Paste_Image.png

这样当你向上拉的时候,就能实现数据的加载。但是这种实现没有提示,也就是没有添加页脚。效果不好。

2.2,添加页脚的实现

我们首先来自定义一个页脚的布局:

class LoadingFooter : RelativeLayout {
    private var mState = State.Normal
    private var mLoadingView: View? = null
    private var mNetworkErrorView: View? = null
    private var mTheEndView: View? = null
    private var mLoadingProgress: ProgressBar? = null
    private var mLoadingText: TextView? = null

    constructor(context: Context) : super(context) {
        init(context)
    }

    constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
        init(context)
    }

    constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
        init(context)
    }

    fun init(context: Context) {
        View.inflate(context, R.layout.view_recycler_footer, this)
        setOnClickListener(null)
        setState(State.Normal, true)
    }

    var state: State
        get() = mState
        set(status) = setState(status, true)

    fun setState(status: State, showView: Boolean) {
        if (mState == status) {
            return
        }
        mState = status
        when (status) {
            LoadingFooter.State.Normal -> {
                setOnClickListener(null)
                if (mLoadingView != null) {
                    mLoadingView!!.visibility = View.GONE
                }

                if (mTheEndView != null) {
                    mTheEndView!!.visibility = View.GONE
                }

                if (mNetworkErrorView != null) {
                    mNetworkErrorView!!.visibility = View.GONE
                }
            }
            LoadingFooter.State.Loading -> {
                setOnClickListener(null)
                if (mTheEndView != null) {
                    mTheEndView!!.visibility = View.GONE
                }

                if (mNetworkErrorView != null) {
                    mNetworkErrorView!!.visibility = View.GONE
                }

                if (mLoadingView == null) {
                    val viewStub = findViewById(R.id.loading_viewstub) as ViewStub
                    mLoadingView = viewStub.inflate()
                    mLoadingProgress = mLoadingView!!.findViewById(R.id.pg_loading) as ProgressBar
                    mLoadingText = mLoadingView!!.findViewById(R.id.tv_loaddata) as TextView
                } else {
                    mLoadingView!!.visibility = View.VISIBLE
                }
                mLoadingView!!.visibility = if (showView) View.VISIBLE else View.GONE
                mLoadingProgress!!.visibility = View.VISIBLE
            }
            LoadingFooter.State.TheEnd -> {
                setOnClickListener(null)
                if (mLoadingView != null) {
                    mLoadingView!!.visibility = View.GONE
                }

                if (mNetworkErrorView != null) {
                    mNetworkErrorView!!.visibility = View.GONE
                }

                if (mTheEndView == null) {
                    val viewStub = findViewById(R.id.end_viewstub) as ViewStub
                    mTheEndView = viewStub.inflate()
                } else {
                    mTheEndView!!.visibility = View.VISIBLE
                }

                mTheEndView!!.visibility = if (showView) View.VISIBLE else View.GONE
            }
            LoadingFooter.State.NetWorkError -> {
                if (mLoadingView != null) {
                    mLoadingView!!.visibility = View.GONE
                }

                if (mTheEndView != null) {
                    mTheEndView!!.visibility = View.GONE
                }

                if (mNetworkErrorView == null) {
                    val viewStub = findViewById(R.id.network_error_viewstub) as ViewStub
                    mNetworkErrorView = viewStub.inflate()
                } else {
                    mNetworkErrorView!!.visibility = View.VISIBLE
                }
                mNetworkErrorView!!.visibility = if (showView) View.VISIBLE else View.GONE
            }
            else -> {
            }
        }
    }

    enum class State {
        Normal, TheEnd, Loading, NetWorkError
    }
}

进行Adapter的实现,此Adapter完成了页脚的数据适配:

abstract class BaseLoadMoreAdapter<T>(context: Context) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
    private var mFooterViewParent: FrameLayout? = null//脚布局容器
    private var mFooterView: View? = null//脚布局
    private var isShowFooter = false//是否显示脚布局
    private var itemsList = ArrayList<T>()//脚布局
    private var mContext: Context? = null

    companion object{
        val TYPE_LOAD_MORE = Int.MIN_VALUE + 1//脚布局类型
    }

    init {
        mContext = context
    }

    /**
     * 添加数据
     */
    fun addAll(items: ArrayList<T>){
        itemsList.addAll(items)
        this.notifyDataSetChanged()
    }

    /**
     * 添加数据
     */
    fun addAllInsert(items: ArrayList<T>){
        itemsList.addAll(0, items)
        this.notifyDataSetChanged()
    }

    /**
     * 清除数据
     */
    fun clear(){
        itemsList.clear()
    }

    fun getAllData(): ArrayList<T>{
        return itemsList
    }


    override fun getItemViewType(position: Int): Int {
        if (isShowFooter && position == itemCount - getFooterCount())
            return TYPE_LOAD_MORE
        return mySelfItemViewType(position)
    }

    /**
     * 返回正常类型的布局标记
     */
    private fun mySelfItemViewType(position: Int): Int{
        return super.getItemViewType(position)//父类默认返回的就是0
    }

    private fun getFooterCount(): Int {
        if (isShowFooter)
            return 1
        else
            return 0
    }

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder?, position: Int) {
        if (position != itemCount - getFooterCount()){
            mySelfOnBindViewHolder(holder, position)
        }
    }

    override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): RecyclerView.ViewHolder {
        if (viewType == TYPE_LOAD_MORE){
            if (mFooterViewParent == null){
                mFooterViewParent = FrameLayout(mContext)
                parent!!.addView(mFooterViewParent)
                if (mFooterView != null){
                    mFooterViewParent!!.addView(mFooterView)
                }
            }
            return ViewHodlerLoadMore(mFooterViewParent)
        }
        return mySelfViewHolder(parent, viewType)
    }

    override fun getItemCount(): Int {
        val count = if (itemsList.size == 0) 0 else itemsList.size
        return count + getFooterCount()
    }

    /**
     * 设置脚布局
     */
    fun setFooterView(footerView: View){
        mFooterView = footerView
        isShowFooter = true
        if (mFooterViewParent != null && mFooterViewParent!!.childCount == 0){
            mFooterViewParent!!.addView(mFooterView)
        }
    }

    /**
     * 移除脚布局
     */
    fun removeFooterView(){
        isShowFooter = false
        notifyDataSetChanged()
//        mFooterViewParent.removeView(footerView)
    }

    /**
     * 实现加载空间的VIewHolder
     */
    class ViewHodlerLoadMore(itemView: View?) : RecyclerView.ViewHolder(itemView)

    /**
     * 实现自己的VIewHolder
     */
    abstract fun mySelfViewHolder(parent: ViewGroup?, viewType: Int): RecyclerView.ViewHolder

    /**
     * 为控件赋值
     */
    abstract fun mySelfOnBindViewHolder(holder: RecyclerView.ViewHolder?, position: Int)
}

在来实现完成了Item适配的Adapter:

open class LoadMoreAdapter(context: Context) : BaseLoadMoreAdapter<String>(context){
    private var mContext: Context? = null
    private var mItems= ArrayList<String>()
    init {
        mContext = context
        refreshData()
    }
    override fun mySelfViewHolder(parent: ViewGroup?, viewType: Int): RecyclerView.ViewHolder {
        val view = LayoutInflater.from(mContext).inflate(R.layout.item_rc_4st, parent, false)
        return ViewHolderMore(view)
    }

    override fun mySelfOnBindViewHolder(holder: RecyclerView.ViewHolder?, position: Int) {
        (holder!! as ViewHolderMore).tv.text = mItems[position]
    }

    class ViewHolderMore(itemView: View?): RecyclerView.ViewHolder(itemView){
        var tv = itemView!!.findViewById(R.id.tv) as TextView
    }

    fun refreshData(){//刷新数据
        mItems = getAllData()
        notifyDataSetChanged()
    }
}

创建一个进行加载数据的接口:

interface OnLoadMore {
    fun onLoadMore(view: View)
}

重写滑动监听方法:

open class LoadMoreOnScrollViewListener(min: Int) : RecyclerView.OnScrollListener(), OnLoadMore{
    enum class LayoutManagerType{
        LinearLayoutManager,
        GridLayoutManager,
        StaggeredGridLayoutManager
    }

    private var lastPositions: IntArray? = null
    private var lastVisibleItemPosition: Int? = 0
    private var currScrollStatus = 0
    private var minPositionToEndless = 1

    private var layoutManagerType: LayoutManagerType? = null

    init {
        minPositionToEndless = min
    }

    override fun onScrollStateChanged(recyclerView: RecyclerView?, newState: Int) {
        super.onScrollStateChanged(recyclerView, newState)

        currScrollStatus = newState
        val layoutManager = recyclerView!!.layoutManager
        val visibleItemCount = layoutManager.childCount
        val totalItemCount = layoutManager.itemCount
        if (visibleItemCount > 0 && currScrollStatus == RecyclerView.SCROLL_STATE_IDLE
                && lastVisibleItemPosition!! >= totalItemCount - minPositionToEndless){
            onLoadMore(recyclerView)
        }
    }

    override fun onScrolled(recyclerView: RecyclerView?, dx: Int, dy: Int) {
        super.onScrolled(recyclerView, dx, dy)

        val layoutManager = recyclerView!!.layoutManager
        if (layoutManagerType == null){
            if (layoutManager is LinearLayoutManager)
                layoutManagerType = LayoutManagerType.LinearLayoutManager
            else if(layoutManager is GridLayoutManager)
                layoutManagerType = LayoutManagerType.GridLayoutManager
            else if (layoutManager is StaggeredGridLayoutManager)
                layoutManagerType = LayoutManagerType.StaggeredGridLayoutManager
            else
                throw RuntimeException("unsupported LayoutManager used, Valid ones are LinearLayoutManager, GridLayoutManager and StaggeredGridLayoutManager")
        }

        when(layoutManagerType){
            LayoutManagerType.LinearLayoutManager ->{lastVisibleItemPosition = (layoutManager as LinearLayoutManager).findLastVisibleItemPosition()}
            LayoutManagerType.GridLayoutManager ->{lastVisibleItemPosition = (layoutManager as GridLayoutManager).findLastVisibleItemPosition()}
            LayoutManagerType.StaggeredGridLayoutManager ->{
                val staggeredGridLayoutManager = layoutManager as StaggeredGridLayoutManager
                if (lastPositions == null){
                    lastPositions = kotlin.IntArray(staggeredGridLayoutManager.spanCount)
                }
                staggeredGridLayoutManager.findLastVisibleItemPositions(lastPositions)
                lastVisibleItemPosition = findMax(lastPositions!!)
            }
        }
    }

    fun findMax(posArr: IntArray): Int{
        return posArr.indices.max()?: posArr[0]
    }

    override fun onLoadMore(view: View) {
    }
}

接下来就是在代码中进行使用了:

class LoadMoreDefineActivityActivity : AppCompatActivity() {

    private var rcAdapter: LoadMoreAdapter? = null
    private var itemList = ArrayList<String>()
    private var addList = ArrayList<String>()
    private var loadingFooter: LoadingFooter? = null
    private val pageCount = 10
    private var lastPosition = 0//上一次的加载数量

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_recycler_view_simple_refresh_data)
        initData()
    }

    fun initData(){
        loadMoreData(20, itemList, "数据")
        rcAdapter = LoadMoreAdapter(this)
        rv_content.layoutManager=LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
        rv_content.adapter = rcAdapter
        rv_content.addItemDecoration(DividerItemDecoration(this, DividerItemDecoration.VERTICAL))

        srl_refresh.overScrollMode = View.OVER_SCROLL_NEVER
        srl_refresh.setColorSchemeResources(R.color.colorAccent, R.color.colorPrimary, R.color.colorPrimaryDark)
        srl_refresh.setOnRefreshListener {//下拉刷新
            srl_refresh.isRefreshing = false
            val insertData = ArrayList<String>()
            loadMoreData(5, insertData, "下拉刷新数据")
            rcAdapter!!.addAllInsert(insertData)
        }

        rv_content.addOnScrollListener(object : LoadMoreOnScrollViewListener(1){
            override fun onLoadMore(view: View) {
                super.onLoadMore(view)
                getData(false)
            }
        })

        if (loadingFooter == null && itemList.isNotEmpty() ){
            loadingFooter = LoadingFooter(this)
            rcAdapter!!.setFooterView(loadingFooter!!)
        }

        getData(true)
    }

    private fun getData(isFirst: Boolean) {
        if (itemList.isEmpty())
            return
        if (loadingFooter!!.state == LoadingFooter.State.Loading || (!isFirst && loadingFooter!!.state == LoadingFooter.State.TheEnd))
            return
        if (!isFirst) {
            loadingFooter!!.state = LoadingFooter.State.Loading
        }else{
            rcAdapter!!.addAll(itemList)
        }
        Handler().postDelayed({
            if (isFirst)
                rcAdapter!!.clear()
            addList = getServerData()
            if (addList.size < pageCount){
                loadingFooter!!.setState(LoadingFooter.State.TheEnd, true)
            }else{
                loadingFooter!!.state = LoadingFooter.State.Normal
            }

            if (addList.isNotEmpty()){
                rcAdapter!!.addAll(addList)
                lastPosition += addList.size
            }
        }, 1000)
    }

    private fun loadMoreData(number: Int, list: ArrayList<String>, string: String) {
        (0..number-1).mapTo(list) {string+ "Item " + it}
    }

    private fun getServerData(): ArrayList<String>{
        val end = if (lastPosition + pageCount > itemList.size) itemList.size else lastPosition + pageCount
        val tempArr = ArrayList<String>()
        (lastPosition..end-1).mapTo(tempArr) { itemList[it] }
        return tempArr
    }
}

运行程序,效果图如下:

Paste_Image.png Paste_Image.png

三,引用第三方框架

从上面来看自己写的话,太浪费时间了,如果是自己进行学习的话,那就另说了。下面给推荐一个框架BRVAH,里面集成了分割线,Item动画,数据刷新,Adapter...;在此网站中下载Demo,将里面的library引入自己的项目中
我们用此框架来实现数据刷新,看Adapter代码:

class RecyclerViewRefreshDataOthersAdapter(layoutResId: Int, items: ArrayList<String>) : BaseQuickAdapter<String, BaseViewHolder>(layoutResId, items){
    override fun convert(helper: BaseViewHolder?, item: String?) {
        helper!!.addOnClickListener(R.id.tv)
        helper.setText(R.id.tv, item)
    }
}

在来看Activity中的使用:

class RecyclerViewRefreshDataOthersActivity : BaseKotlinActivity() {
    private var itemList= ArrayList<String>()
    private var rcAdapter: RecyclerViewRefreshDataOthersAdapter? = null

    private val pageSize = 10//页数据量
    private var currCount = 0//当前数据量
    private val totalCount = 30//全部数据量
    private var isError = true//加载数据是否出错

    override fun getLayoutResoucesId(): Int {
        return R.layout.activity_recycler_view_simple_refresh_data
    }

    override fun init() {
        super.init()
        initData()
    }

    fun initData(){
        loadMoreData(10, itemList, "数据")
        rcAdapter = RecyclerViewRefreshDataOthersAdapter(R.layout.item_rc_4st, itemList)
        rcAdapter!!.openLoadAnimation(BaseQuickAdapter.SLIDEIN_RIGHT)//进入动画
        rv_content.layoutManager=LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
        rv_content.adapter = rcAdapter

        srl_refresh.setColorSchemeResources(R.color.colorAccent, R.color.colorPrimary, R.color.colorPrimaryDark)
        Handler().postDelayed({
            srl_refresh.setOnRefreshListener {//下拉刷新
                val insertData = ArrayList<String>()
                loadMoreData(10, insertData, "下拉刷新数据")
                rcAdapter!!.setNewData(insertData)
                rcAdapter!!.setEnableLoadMore(true)
                srl_refresh.isRefreshing = false
            }
        }, 1000)

        rcAdapter!!.setOnLoadMoreListener({
            srl_refresh.isEnabled = false
            rv_content.postDelayed({
                if(rcAdapter!!.data.size < pageSize){
                    rcAdapter!!.loadMoreEnd(true)//true is gone,false is visible
                }else{
                    if (currCount >= totalCount){
                        rcAdapter!!.loadMoreEnd(true)
                    }else{
                        if (!isError){
                            val loadData = ArrayList<String>()
                            loadMoreData(5, loadData, "上拉加载数据")
                            rcAdapter!!.addData(loadData)
                            currCount = rcAdapter!!.data.size
                            rcAdapter!!.loadMoreComplete()
                        }else{
                            isError = false
                            rcAdapter!!.loadMoreFail()
                        }
                    }
                }
                srl_refresh.isEnabled = true
            }, 1000)
        })
    }

    private fun loadMoreData(number: Int, list: ArrayList<String>, string: String) {
        (0..number-1).mapTo(list) {string+ "Item " + it}
    }
}

运行程序,效果实现。

补充

第三方中点击事件的使用,看代码:

class RecyclerViewRefreshDataOthersAdapter(layoutResId: Int, items: ArrayList<String>) : BaseQuickAdapter<String, BaseViewHolder>(layoutResId, items){
    override fun convert(helper: BaseViewHolder?, item: String?) {
        helper!!.addOnClickListener(R.id.tv)
                .addOnClickListener(R.id.btn)
        helper.setText(R.id.tv, item)
        helper.setText(R.id.btn, item)
    }
}

上面的代码给TextViewButton添加了点击事件,这两个属于子条目中的子控件。来看一下点击事件的实现:

rv_content.addOnItemTouchListener(object : OnItemClickListener(){
            //这个属于item的点击事件
            override fun onSimpleItemClick(adapter: BaseQuickAdapter<*, *>?, view: View?, position: Int) {
                showToast("pos->"+ position)
                Log.e("hjd", "pos->"+ position)
            }
            // 这个是子Item中子控件的点击事件
            override fun onItemChildClick(adapter: BaseQuickAdapter<*, *>?, view: View?, position: Int) {
                when(view?.id){
                    R.id.tv -> {
                        showToast("tv->"+ position)
                        Log.e("hjd", "tv->"+ position)
                    }
                    R.id.btn -> {
                        showToast("btn->"+ position)
                        Log.e("hjd", "btn->"+ position)
                    }
                }
            }
        })

四,参考文章

1,第三方框架BRVAH
2,RecyclerView上拉加载更多菜鸟自用,大神绕道

相关文章

网友评论

      本文标题:RecyclerView之上拉加载下拉刷新

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