注:仅作为个人笔记,如浏览有疑问,可评论、私信或参考他人文章
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
}
}