Kotlin的简单MVP框架

注:仅作为个人笔记,如浏览有疑问,可评论、私信或参考他人文章

Base类

BaseActivity

Activity的基类,封装了初始化P层的方法,以及内存溢出处理

abstract class BaseActivity<V:IBaseView,P:BasePresenter<V>>: AppCompatActivity(),IBaseView {
    var pre:P? = null
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(getLayout())
        pre = initPresenter()
        pre?.attachView(this as V)
        initData()
    }

    abstract fun getLayout(): Int
    abstract fun initPresenter(): P?
    abstract fun initData()

	//防止内存溢出
    override fun onDestroy() {
        super.onDestroy()
        pre?.detachView()
        pre = null
    }
}
BaseFragment

Fragment的基类,Fragment也是一个View,所以它要想获取数据,同样的也需要一个Presenter进行获取数据,大体结构同BaseActivity

abstract class BaseFragment<V:IBaseView,P : BasePresenter<V>> : Fragment(),IBaseView{

    var pre : P? = null

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return View.inflate(context, getLayout(), null)
    }

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        //写在这个方法里防止报空指针或者找不到控件ID的异常
        pre = initPresenter()
        pre?.attachView(this as V)
        initData()
    }

    abstract fun initPresenter(): P?
    abstract fun getLayout(): Int
    abstract fun initData()

	//防止内存溢出
    override fun onDestroy() {
        super.onDestroy()
        pre?.detachView()
        pre = null
    }
}
BasePresenter类

封装了绑定和解绑数据的方法

abstract class BasePresenter<V : IBaseView> : IContract.IPresenter {
    var iBaseView: V? = null

    fun attachView(iBaseView: V) {
        this.iBaseView = iBaseView
    }

    fun detachView() {
        this.iBaseView = null
    }
}

接口:

两个类

//IBaseView
interface IBaseView {}

//契约接口
interface IContract {
    //View 层接口
    interface IMainView : IBaseView {
        //MainActivity的方法
        fun getData(json: String)
    }

    interface IHomeFragView : IBaseView {
        //设置数据
        fun setData(json: String)
    }

    //Presenter 接口
    interface IPresenter {
        fun getInfo()
    }
}

Activity(以MainActivity为例)

布局
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".activity.MainActivity">

	<!--动态放入Fragment
	可以使用Viewpager等
	这里不写那么复杂了-->
    <FrameLayout
        android:id="@+id/fram"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</androidx.constraintlayout.widget.ConstraintLayout>
MainActivity

MainActivity 定义了一个变量TAG,Log输出用
如果MainActivity不需要从网络获取数据 或者从不用Model层获取数据的话(这活儿让Fragment去干),就不需要创建MainPresenter类了
因为,Presenter存在的意义就是连接Model和View,如果View不需要Model,那么也就不需要Presenter了

class MainActivity : BaseActivity<IContract.IMainView, MainPresenter>(), IContract.IMainView {

    private val TAG = "MainActivity"

    override fun getLayout(): Int = R.layout.activity_main

    override fun initPresenter(): MainPresenter? = MainPresenter()

    override fun initData() {
        //TODO("Not yet implemented")
        pre?.getInfo()
        //动态添加Fragment的代码
        val beginTransaction = supportFragmentManager.beginTransaction()
        beginTransaction.replace(R.id.fram, HomeFragment())
        beginTransaction.commit()
    }

    override fun getData(json: String) {
        //TODO("Not yet implemented")
        //解析从Presenter获取到的数据
        Log.d(TAG, "现在执行的是$TAG 的getData方法")
        //var xxx = Gson().fromjson(json, XXX::class.java)  xxxx.adapter = Adapter() xxxx.layoutManager = LLM(this)
    }
}
MainPresenter

MainPresenter类 实现接口,传值然后回调MainActivity的方法

class MainPresenter : BasePresenter<IContract.IMainView>() {
    override fun getInfo() {
        //TODO("Not yet implemented")
        //NetUtils.instance.create()...onNext
        iBaseView?.getData("从 onNext 获取到的json数据")
        //onError
    }
}

Fragment(以HomeFragment为例)

HomeFragment类

同样定义一个常量TAG用来打印,在initData中调用presenter的方法,然后让presenter回调至setData方法

class HomeFragment : BaseFragment<IContract.IHomeFragView, HomeFragPresenter>(),
    IContract.IHomeFragView {

    private val TAG = "HomeFragment"

    override fun initPresenter(): HomeFragPresenter? = HomeFragPresenter()

    override fun getLayout(): Int = R.layout.frag

    override fun initData() {
        //TODO("Not yet implemented")
        //调用Presenter获取数据的方法
        pre?.getInfo()
    }

    override fun setData(json: String) {
        //TODO("Not yet implemented")
        //解析从Presenter获取到的数据
        Log.d(TAG, "现在执行的是$TAG 的setData方法,下一步是解析从presenter获取到的数据,设置适配器等")
        //var xxx = Gson().fromjson(json, XXX::class.java)  xxxx.adapter = Adapter() xxxx.layoutManager = LLM(this)
    }
}
HomeFragment的Presenter

实现通用接口,从网络/Model层获得到数据之后回调HomeFragment的方法

class HomeFragPresenter : BasePresenter<IContract.IHomeFragView>() {
    override fun getInfo() {
        //TODO("Not yet implemented")
        //NetUtils.instance.create()...onNext  json = t.string
        iBaseView?.setData("从 onNext 获取到的json数据")
        //onError
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值