Kotlin+Retrofit+RxJava+MVP封裝(三)

前言

Kotlin+Retrofit+RxJava+MVP封裝(一)
Kotlin+Retrofit+RxJava+MVP封裝(二)

對BaseListActiviy的封裝

因為在實際開發的項目中,列表是經常用到的,所以我在這里將其封裝了一下,介紹一下思路
1.在封裝時,我們想到在基類里面應該囊括了BaseListPresenter,和與期對應的Bean和Model實現類;
2.綁定默認的布局,設定RecyclerView樣式,上拉和下拉所要加載的數據;
3.集合BaseAdapter,能夠直接引入Item布局,Item點擊事件以及Item中控件的數據綁定,涉及到了BaseViewHolder;
4.繼承BaseListActivity,重寫其中必要的方法。
詳細理解以下代碼,所注意地方我會在代碼中說明:

abstract class BaseListActivity<H,A:BaseBean,B:BaseListModelImpl<A>>: BaseActivity<BaseListView, BaseListPresenter<A,B>>(), BaseListView ,getModelImpl<A,B>{

    var mAdapter: BaseListAdapter<H>?=null
    var mList:ArrayList<H>?= ArrayList()


    override fun bindLayout(): Int {
//綁定RecyclerView布局
        return R.layout.activity_list
    }

    override fun initData() {
     //初始化RecyclerView
        val layoutManager = LinearLayoutManager(this)
        layoutManager.orientation = LinearLayoutManager.VERTICAL
        mRecyclerview.layoutManager=layoutManager

        mRecyclerview.setRefreshProgressStyle(ProgressStyle.BallSpinFadeLoader)
        mRecyclerview.setLoadingMoreProgressStyle(ProgressStyle.Pacman)
        mRecyclerview.setArrowImageView(R.drawable.iconfont_downgrey)
    }

    override fun initListener() {
        mRecyclerview.setLoadingListener(object : XRecyclerView.LoadingListener{//RecyclerView的上拉和下拉
            override fun onLoadMore() {
                mPresenter!!.getMoreData()
            }

            override fun onRefresh() {
                mPresenter!!.getRefreshData()
            }

        })
        if(mAdapter==null){
            mAdapter= object :BaseListAdapter<H>(mList!!,getItemLayout()){//初始化adapter
                override fun convert(helper: BaseViewHolder, item: H, position: Int, size: Int) {
                    fitDates(helper, item, position, size)//item數據綁定
                }
            }
            mRecyclerview.adapter=mAdapter
            mRecyclerview.refresh()

        }else{
            mAdapter!!.notifyDataSetChanged()
        }

        mAdapter!!.setOnRecyclerViewItemChildClickListener(object : BaseListAdapter.OnRecyclerViewItemChildClickListener {//item點擊事件的接口回調
            override fun onItemChildClick(adapter: BaseListAdapter<*>, view: View, position: Int) {
                onItemClick(view, position)

            }
        })

    }


    override fun loadMore(data: ArrayList<*>) {//下拉加載需要加載的數據
        mList!!.addAll(data as ArrayList<H>)
        mAdapter!!.notifyDataSetChanged()
        mRecyclerview.loadMoreComplete()
    }

    @Suppress("UNCHECKED_CAST")
    override fun showRefresh(data: ArrayList<*>) {//上拉刷新需要寫入的數據
        mList!!.clear()
        mList!!.addAll(data as ArrayList<H>)
        mAdapter!!.notifyDataSetChanged()
        mRecyclerview.refreshComplete()
    }

    override fun hasNoMoreData() {//沒有更多數據
        mRecyclerview.setNoMore(true)
        mAdapter!!.notifyDataSetChanged()
    }

    override fun createPresenter(): BaseListPresenter<A,B>{
        return BaseListPresenter(this,this)//返回BaseListPresenter,其中A是繼承BaseBean的Bean文件,B是Model的實現類
    }

    abstract fun getItemLayout():Int//得到item布局


    protected abstract fun fitDates(helper: BaseViewHolder, bean: H, position: Int, size: Int)//數據匹配

    protected open fun onItemClick(v: View, position: Int) {

    }//item點擊事件

}

如上所示,封裝好BaseListActivity過后,一些列表界面就比較好寫了,例如:

ListView.png

實現以上界面,就下面幾行代碼就搞定了,是不是很方面簡單。

class MoneyDetailActivity: BaseListActivity<MoneyDetailBean.PageResultsBean,MoneyDetailBean,MoneyDetailModelImpl>() {


    var mo:MoneyDetailModelImpl?= MoneyDetailModelImpl()

    override fun getMyModelImpl(): MoneyDetailModelImpl {
       return mo!!
    }


    override fun getItemLayout(): Int {
        return R.layout.item
    }

    override fun fitDates(helper: BaseViewHolder, bean: MoneyDetailBean.PageResultsBean, position: Int, size: Int) {
        helper.setText(R.id.text,bean.title)
    }
}

關于BaseListPresenter就不用再重寫了,直接使用

class BaseListPresenter<A:BaseBean,B:BaseListModelImpl<A>>(private val listViews: BaseListView,getModelImpl: getModelImpl<A, B>): BasePresenter<BaseListView>() {

    var listmodel: BaseListModel?=null
    init {
        listmodel= getModelImpl.getMyModelImpl()
    }


    //得到更多數據
    fun getMoreData(){
        listmodel!!.getMoreData()
    }
    //得到刷新數據
    fun getRefreshData(){
        listmodel!!.getRefreshDta()
        listmodel!!.loadComplete(object : BaseListModel.LoadComplete{
            override fun hasNoMoreData() {
                listViews.hasNoMoreData()
            }

            override fun getDataRefresh(mDatas: ArrayList<*>) {
                listViews.showRefresh(mDatas)
            }

            override fun getDataFailed(baseBean: BaseBean) {

            }

            override fun getDataMore(mDatas: ArrayList<*>) {
                listViews.loadMore(mDatas)
            }

        })
    }
}

關于BaseListModelImpl,因為service和Bean都不一樣,所以重寫請求成功和需要請求的接口即可,

open class BaseListModelImpl<S:BaseBean>: BaseModel<S>(), BaseListModel {
    override fun ServiceParams(params: HashMap<String, String>): Observable<S> {

        return Observable.never()

    }

    var PAGE:Int?=1
    var loadListeners:BaseListModel.LoadComplete?=null
    var isMore:Boolean?=true

    override fun getMoreData() {
        PAGE = PAGE!!.plus(1)
        isMore=true
        PostParams()
    }

    override fun getRefreshDta() {
        PAGE=1
        isMore=false
        PostParams()
    }

    override fun showNetError() {

    }

    override fun showDataError() {

    }

    override fun loadComplete(loadedListener: BaseListModel.LoadComplete) {
        if(this.loadListeners==null){
            this.loadListeners=loadedListener

        }
    }

    override fun FailedOperation(e: Throwable?) {

    }

    override fun SuccessOperation(o: BaseBean) {
        
    }

    override fun Params(): HashMap<String, String>? {
        ClearHashMap()
        mParams!!.put("page", PAGE.toString())
        return mParams
    }
}

關于BaseViewHolder和BaseAdapter我就不詳細介紹了,可以在源代碼中看到。
源碼地址

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容