美文网首页android UI系列专题
kotlin 整合RecyclerView 上拉刷新 下拉加载

kotlin 整合RecyclerView 上拉刷新 下拉加载

作者: Jamesbond_5521 | 来源:发表于2020-05-21 11:07 被阅读0次

    使用代码如下

    RefreshListView(refreshLayout,recyclerView).apply {
         recyclerView.layoutManager = LinearLayoutManager(this@RecyclerViewTestActivity)
         onProcess = {
            RetrofitServiceManager.create(PosApi::class.java).getList(page,pageSize).get()
         }
         register(String::class.java,R.layout.test_item){holder, data ->
            (holder[R.id.textView] as TextView).text = data
          }
    }
    

    代码构建如下

    //加载更多的滑动监听
    abstract class onLoadMoreListener : RecyclerView.OnScrollListener() {
        private var countItem = 0
        private var lastItem = 0
        private var isScolled = false //是否可以滑动
        private var layoutManager: RecyclerView.LayoutManager? = null
    
        /**
         * 加载回调方法
         * @param countItem 总数量
         * @param lastItem  最后显示的position
         */
        protected abstract fun onLoading(countItem: Int, lastItem: Int)
        override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
            //拖拽或者惯性滑动时isScolled设置为true
            isScolled = newState == RecyclerView.SCROLL_STATE_DRAGGING || newState == RecyclerView.SCROLL_STATE_SETTLING
        }
    
        override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
            if (recyclerView.layoutManager is LinearLayoutManager) {
                layoutManager = recyclerView.layoutManager
                countItem = layoutManager!!.itemCount
                lastItem =  (layoutManager as LinearLayoutManager?)!!.findLastCompletelyVisibleItemPosition()
            }
            if (isScolled && countItem != lastItem && lastItem == countItem - 1) {
                onLoading(countItem, lastItem)
            }
        }
    }
    //每项不同类型的视图实体
    data  class ItemBindView<T:Any>(val itemLayout:Int,val setItemValue: ((holder: JsonViewHolder, data: T) -> Unit)?)
    //默认的下拉视图类型
    class FotterItem()
    //返回的数据对象
    class ListData{
        var count:Int = 0
        var data:MutableList<Any> = mutableListOf()
    }
    //上拉,下拉初始化类
    class RefreshListView(val refreshLayout: SwipeRefreshLayout,val recyclerView:RecyclerView){
        var pageSize = 20
        var page = 1
        var count = 0
        var datas:MutableList<Any> = mutableListOf()
        var onBefor:((isRefresh:Boolean)->Unit)? = null
        var onProcess:((isRefresh:Boolean)->ListData)? = null
        var onComplet:((isRefresh:Boolean)->Unit)? = null
    
        val context:Context = recyclerView.context
        private var registers:MutableMap<Any,Any> = mutableMapOf()
        private var types:MutableList<Any> = mutableListOf()
        private fun notifyDataSetChanged(){
            recyclerView.adapter?.notifyDataSetChanged()
        }
    
        init {
            //下拉刷新的圆圈是否显示
            refreshLayout.apply {
                isRefreshing = false
                setColorSchemeResources(
                    android.R.color.holo_blue_light,
                    android.R.color.holo_red_light,
                    android.R.color.holo_orange_light
                )
                setProgressBackgroundColorSchemeResource(android.R.color.white)
                setOnRefreshListener {
                    start(true)
    
                }
            }
            recyclerView.apply {
                addOnScrollListener(object : onLoadMoreListener() {
                    override fun onLoading(countItem: Int, lastItem: Int) {
                        if (page * pageSize < count) {
                           start(false)
                        }
                    }
                })
                adapter = object : RecyclerView.Adapter<JsonViewHolder>() {
                    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): JsonViewHolder {
                        val itemBindView = itemBindView(viewType)
                        val view: View =
                            LayoutInflater.from(context).inflate(itemBindView.itemLayout, parent, false)
                        return JsonViewHolder(view)
                    }
    
                    override fun getItemCount(): Int {
                        return datas.size
                    }
                    /**
                     * 获取itemBindView
                     */
                    private fun itemBindView(viewType: Int): ItemBindView<Any> {
                        val clas = types[viewType]
                        val itemBindView = registers[clas] as ItemBindView<Any>
                        return itemBindView
                    }
    
                    override fun onBindViewHolder(holder: JsonViewHolder, position: Int) {
                        if(position == 19){
                            Log.i("xiaochangyan",position.toString())
                        }
    
    
                        val itemBindView = itemBindView(getItemViewType(position))
                        val json = datas[position]
                        if(JSON.toJSON(json) is JSONObject)
                        holder.initJsonValue(JSON.toJSON(json) as JSONObject)
                        itemBindView.setItemValue?.invoke(holder, json)
                    }
    
                    override fun getItemViewType(position: Int): Int {
                        val data = datas[position]
                        val clas = data::class.java
                        return types.indexOf(clas)
                    }
                }
            }
            register(FotterItem::class.java,R.layout.foot_layout,null)
        }
        private fun start(isRefresh: Boolean){
            onBefor?.invoke(isRefresh)
            //更正页脚
            if(isRefresh){
                page = 1
            }else{
                page+=1
            }
            GlobalScope.launch(Dispatchers.IO){
                var list:ListData? = null
                try {
                    list = onProcess?.invoke(isRefresh)
                }catch (e:java.lang.Exception){
                    e.printStackTrace()
                }
                withContext(Dispatchers.Main){
                    refreshLayout.isRefreshing = false
                    list?.let {
                        count = it.count//设置记录条数
                        if(isRefresh){
                            datas.clear()
                        }else{
                            if(datas.last() is FotterItem){
                                datas.removeAt(datas.lastIndex)
                            }
                        }
                        datas.addAll(it.data)
                        if (page * pageSize < count) {
                            datas.add(FotterItem())
                        }
                        notifyDataSetChanged()
                    }
                    onComplet?.invoke(isRefresh)
                }
            }
        }
        fun <T:Any> register(clas:Class<T>,itemLayout:Int,setItemValue: ((holder: JsonViewHolder, data: T) -> Unit)?){
            registers[clas] = ItemBindView(itemLayout,setItemValue)
            types.add(clas)
        }
    }
    /**
     * 统一一个以json为实体的ViewHolder
     */
    class JsonViewHolder(view: View) : RecyclerView.ViewHolder(view) {
    
        val map = mutableMapOf<String, View?>()
        operator fun get(id:Int): View?{
            if(map.containsKey(id.toString())){
                return map[id.toString()]
            }
            val view = itemView.findViewById<View?>(id)
            map[id.toString()] = view
            return view
        }
        operator fun get(tag:String): View?{
            if(map.containsKey(tag)){
                return map[tag]
            }
            val view = itemView.findViewWithTag<View?>(tag) ?: return null
            map[tag] = view
            return view
        }
    
        operator fun set(tag:String,value:String){
            val view: View = this[tag] ?: return
            when{
                view is TextView -> view.text = value
                view is EditText -> view.setText(value)
            }
        }
        fun initJsonValue(jsonObject: JSONObject){
            for (key in jsonObject.keys){
                if(this[key] ==null)continue
                this[key] = when{jsonObject[key]==null->"" else ->jsonObject[key].toString()}
            }
        }
    }
    /**
     * 简单的适配器扩展
     */
    fun RecyclerView.initAdapter(list: JSONArray, layout:Int, setItemValue: ((holder: JsonViewHolder, data: JSONObject) -> Unit)?){
        this.adapter = object :RecyclerView.Adapter<JsonViewHolder>(){
            override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): JsonViewHolder {
                val view: View = LayoutInflater.from(this@initAdapter.context).inflate(layout, parent, false)
                return JsonViewHolder(view)
            }
            override fun getItemCount(): Int {
                return list.size
            }
            override fun onBindViewHolder(holder: JsonViewHolder, position: Int) {
                val json = list.getJSONObject(position)
                holder.initJsonValue(json)
                setItemValue?.invoke(holder,json)
            }
        }
    }
    
    /**
     * 简单的适配器扩展
     */
    fun <T> RecyclerView.initAdapter(list: MutableList<T>, layout:Int, setItemValue: ((holder: JsonViewHolder, data: T) -> Unit)?){
        this.adapter = object :RecyclerView.Adapter<JsonViewHolder>(){
            override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): JsonViewHolder {
                val view: View = LayoutInflater.from(this@initAdapter.context).inflate(layout, parent, false)
                return JsonViewHolder(view)
            }
            override fun getItemCount(): Int {
                return list.size
            }
            override fun onBindViewHolder(holder: JsonViewHolder, position: Int) {
                val json = list.get(position)
                holder.initJsonValue(JSON.toJSON(json) as JSONObject)
                setItemValue?.invoke(holder,json)
            }
        }
    }
    fun RecyclerView.notifyDataSetChanged(){
        this.adapter?.notifyDataSetChanged()
    }
    
    

    其他资源

    //api
    @GET("WGHQ.PayTest/CYPosApi/getList")
    fun getList(@Query("page")page:Int,@Query("pageSize")pageSize:Int):Deferred<ListData>
    //itemLayout
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">
        <TextView
            android:id="@+id/textView"
            android:layout_width="match_parent"
            android:gravity="center"
            android:layout_height="50dp"/>
        <View style="@style/MMViewLine"/>
    </LinearLayout>
    

    相关文章

      网友评论

        本文标题:kotlin 整合RecyclerView 上拉刷新 下拉加载

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