新手新手新手,这个MVP是真的头疼,看了一天,终于是有点入门了,赶紧拿小本本写下来
先来说说对MVP三个部分的理解
M
- M即Model,负责提供数据,处理数据,保存数据等等,一些网络请求之类的都在这个部分
- 所以Model部分是用来控制数据的
V
- V即View,负责显示,负责处理界面的部分
- 一般的android studio项目的xml文件以及Activity(在Activity里面得到控件,进行控制控件,即控制界面)
- 所以View部分就是用来控制界面的
P
- P即Presenter,负责处理逻辑
- 据百度翻译,这个词的意思有“主持人”的意思
- 这么理解吧,当View其中的一个控件需要展示某个数据或者根据某些数据做些改变的话,就会把这个需求提交给主持人
- 主持人拿着这个请求去让Model处理一下,拿到一个结果,主持人分析这个结果,然后再让View做相应的展示
- 下面是我手动画的一个图来说明这三者的关系
接下来用代码实际上手操作一下吧
我要实现的功能很简单,两个Button,一个textView,两个button的点击分别让textView显示不同的内容
- Model部分
- 先想想我的model需要处理什么数据
- 需要判断是哪个按键,然后再生成字符串,再返回出去
- 这里我模拟了一下网络请求,即生成字符串的代码写在一个线程里面
- 然后模拟了一下网络请求失败和请求成功
- 这两种情况之后生成的字符串是不一样的
- 分别根据不同的情况写了一个回调接口
//接口声明
interface IModleData {
//回调接口
interface CallBackListener{
fun creatSuccess(s:String)
fun creatFailed(s:String)
}
//处理数据的方法声明
fun creatData(s:String,i:Int,callback:IModleData.CallBackListener)
}
//model接口实现类
class ModleData:IModleData{
override fun creatData(s:String,callback:IModleData.CallBackListener){
Thread(Runnable {
Thread.sleep(1000*3)
var i = resultofCreat()
if(i > 50){
callback.creatSuccess(s)
}else{
callback.creatFailed(s)
}
}).start()
}
private fun resultofCreat(): Int {
var r = Random(System.currentTimeMillis())
val i = r.nextInt(100)
return i
}
}
- View部分
- view这里我做了一个等待控件的展示
- 以及设置text
- View的接口
interface IView {
fun creatText(s:String)
fun Showprogress()
fun disShowprogress()
fun showtext(s:String)
}
//View的实现类
class MainActivity : AppCompatActivity(),IView,View.OnClickListener{
//拿到主持人的引用
private var presenter:Presenter? = null
private var button1:Button? = null
private var button2:Button? = null
private var text:TextView? = null
private var progressBar:ProgressBar? = null
private val SHOWPROGRESS:Int = 1
private val DISSHOWPROGRESS:Int = 2
private val SHOWTEXT:Int = 3
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
button1 = findViewById(R.id.mainButton_01)
button1!!.setOnClickListener(this)
button2 = findViewById(R.id.mainButton_02)
button2!!.setOnClickListener(this)
text = findViewById(R.id.maintext_01)
progressBar = findViewById(R.id.mainProgressBar)
progressBar!!.visibility = View.INVISIBLE
//通过构造方法将Activity传到主持人,当在model里面调用回调方法的话就会出发这个Activity的监听
presenter = Presenter(this)
}
override fun onClick(v: View?) {
when(v!!.id){
R.id.mainButton_01 -> {
creatText("这是一")
}
R.id.mainButton_02 -> {
creatText("这是二")
}
}
}
@SuppressLint("HandlerLeak")
internal val handler:Handler = object :Handler(){
override fun handleMessage(msg: Message?) {
super.handleMessage(msg)
when(msg!!.what){
SHOWPROGRESS -> {
progressBar!!.visibility = View.VISIBLE
}
DISSHOWPROGRESS -> {
progressBar!!.visibility = View.INVISIBLE
}
SHOWTEXT -> {
text!!.text = msg.obj.toString()
}
}
}
}
//因为showtext的主持人调用在线程里面,所以要发送到handler里面进行设置文字
override fun showtext(s:String){
var me:Message = Message.obtain()
me.what = SHOWTEXT
me.obj = s
handler.sendMessage(me)
}
override fun creatText(s: String){
presenter!!.creatData(s)
}
//因为Showprogress的回调在一个线程里面,所以这里的监听要发送到handler里面进行设置
override fun Showprogress() {
var me:Message = Message.obtain()
me.what = SHOWPROGRESS
handler.sendMessage(me)
}
//因为disShowprogress的回调在一个线程里面,所以这里的监听要发送到handler里面进行设置
override fun disShowprogress() {
var me:Message = Message.obtain()
me.what = DISSHOWPROGRESS
handler.sendMessage(me)
}
}
- Presenter部分
- 拿到View的请求去询问model,然后model根据不同的处理结果去回调callback的方法
- 这里的callback传入的是刚才activity的this,所以在这里调用的话会触发activity里面的监听
- 这里回调不清楚的同学可以去百度一下回调的原理,或者再去看看上面的代码结合下面的代码理解一下
- Presenter接口
interface IPresenter {
fun creatData(s:String)
}
- Presenter实现类
class Presenter:IPresenter,IModleData.CallBackListener{
private var view:IView
private var modle:ModleData
//这里的构造方法是拿到view的引用和model的引用
constructor(view:IView){
this.view = view
modle = ModleData()
}
//因为Presenter实现了IModleData.CallBackListener这个接口,所以传入this就可以监听到model的回调
override fun creatData(s:String) {
view.Showprogress()
modle.creatData(s,this)
}
override fun creatSuccess(s:String){
view.disShowprogress()
view.showtext(s+"成功")
}
override fun creatFailed(s:String){
view.disShowprogress()
view.showtext(s+"失败")
}
}
- 啊……..嘘…….累死,总算差不多理清了,再来总结一下吧
- view先去请求Presenter
- Presenter再去请求model,并传入Presenter自身作为参数
- 因为Presenter实现了IModleData.CallBackListener这个接口,所以model处理完成之后就可以去根据情况去通过刚才Presenter传入的this去回调IModleData.CallBackListener这个接口的方法
- 这个时候Presenter实现的IModleData.CallBackListener的接口的监听方法就会得到model回调的数据,再去对View做相应的处理
差不多了,博主目前就是这个水平,有错误的地方还请大家积极指出来
- 最后帖上git地址