欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

使用Kotlin实现Android中的MVP模式

程序员文章站 2024-03-15 20:16:12
...

在前面的文章浅谈Android中的MVP模式中,对于MVP模式进行了简要的介绍,随着Kotlin成为Android的官方开发语言,Kotlin的应用会变的更加广泛,本文将尝试使用Kotlin实现MVP模式,在了解MVP模式的同时,进一步了解Kotlin的语法特点。

这个demo实现的功能仍是用户输入一个字符串,通过点击按钮实现将字符串变为大写。

使用Kotlin实现Android中的MVP模式

和Java版的结构类似,此处将这个功能模块分为五个部分,如下图

使用Kotlin实现Android中的MVP模式

其中:

  • Activity用于展示内容
  • biz是业务逻辑层,用于避免在Model中进行逻辑处理
  • model是模型层
  • presenter是表示器层,用于处理Model和View之间的交互
  • view中封装了一些接口,和activity共同组成了视图层
下面,我将详细介绍这五个部分分别是如何实现的

1)Model

创建一个Model,命名为MyModel.kt(kotlin文件使用kt后缀,后文省略对于文件名的说明)

package com.steveyg.hellokotlin.helloworld.mvp.model

/**
 * Created by steveyg on 17/5/23.
 */

class MyModel {

    var str: String? = null

}
和Java比起来,kotlin的对象简洁很多,一般可以省去get和set方法,对于对象更多的操作可以参考Kotlin中的面向对象,然后我们定义响应的biz,首先是一个方法的接口

package com.steveyg.hellokotlin.helloworld.mvp.biz

/**
 * Created by steveyg on 17/5/23.
 */

interface IMyBiz {
    fun exec(str: String, listener: OnExecListener)
}
然后增加一个listener

package com.steveyg.hellokotlin.helloworld.mvp.biz

import com.steveyg.hellokotlin.helloworld.mvp.model.MyModel

/**
 * Created by steveygyg on 17/5/23.
 */

interface OnExecListener{
    fun execSuccess(model:MyModel) {}
}
最后实现那个接口,通过kotlin.run实现异步操作

package com.steveyg.hellokotlin.helloworld.mvp.biz

import com.steveyg.hellokotlin.helloworld.mvp.model.MyModel

/**
 * Created by steveyg on 17/5/23.
 */

class MyBiz : IMyBiz {
    override fun exec(str: String, listener: OnExecListener) {
        Thread() {
            kotlin.run {
                Thread.sleep(500)
                var model = MyModel()
                var result: String = str.toUpperCase()
                model.str = result;
                listener.execSuccess(model)
            }
        }.run()
    }

}

2)View层

在View层中,首先定义了一个布局文件,里面有一个提示语,一个输入框和一个按钮:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin">

    <TextView
        android:layout_alignTop="@+id/edit"
        android:layout_alignBottom="@+id/edit"
        android:gravity="center"
        android:id="@+id/text"
        android:layout_width="wrap_content"
        android:layout_height="30dp"
        android:text="TEXT : " />

    <EditText
        android:id="@+id/edit"
        android:layout_marginRight="10dp"
        android:layout_marginLeft="10dp"
        android:layout_toRightOf="@+id/text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <Button
        android:id="@+id/submit"
        android:text="submit"
        android:layout_marginTop="10dp"
        android:layout_below="@+id/edit"
        android:layout_centerHorizontal="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
</RelativeLayout>

接着,我们定义一个接口IMyView,里面定义了视图层需要进行的操作:

package com.steveyg.hellokotlin.helloworld.mvp.view

import com.steveyg.hellokotlin.helloworld.mvp.model.MyModel

/**
 * Created by steveyg on 17/5/23.
 */

interface IMyView{
    fun getStr(): String
    fun showSuccess(model:MyModel)
}

getStr()用来获取输入框中的文字,showSuccess()用于展示最后的结果。接着,在Activity中实现相应的方法

package com.steveyg.hellokotlin.helloworld.mvp.activity

import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.widget.Toast
import com.steveyg.hellokotlin.R
import com.steveyg.hellokotlin.helloworld.mvp.model.MyModel
import com.steveyg.hellokotlin.helloworld.mvp.presenter.MyPresenter
import com.steveyg.hellokotlin.helloworld.mvp.view.IMyView
import kotlinx.android.synthetic.main.mvp_layout.*

/**
 * Created by steveyg on 17/5/23.
 */

class MVPActivity : AppCompatActivity(), IMyView {
    override fun showSuccess(model: MyModel) {
        Toast.makeText(this, model.str, Toast.LENGTH_LONG).show()
    }

    override fun getStr(): String {
        return edit.text.toString()
    }

    var mPresenter: MyPresenter? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.mvp_layout)
        init()
    }

    fun init() {
        mPresenter = MyPresenter(aaa@qq.com this)
        submit.setOnClickListener {
            mPresenter?.exec()
        }
    }
}

3)Presenter层

Presenter层主要是让View和Model进行交互,因此我们定义一个执行相应功能的方法:

package com.steveyg.hellokotlin.helloworld.mvp.presenter

import android.os.Handler
import com.steveyg.hellokotlin.helloworld.mvp.biz.IMyBiz
import com.steveyg.hellokotlin.helloworld.mvp.biz.MyBiz
import com.steveyg.hellokotlin.helloworld.mvp.biz.OnExecListener
import com.steveyg.hellokotlin.helloworld.mvp.model.MyModel
import com.steveyg.hellokotlin.helloworld.mvp.view.IMyView


/**
 * Created by steveyg on 17/5/23.
 */

class MyPresenter(view: IMyView) {
    var myBiz: IMyBiz = MyBiz()
    var myView: IMyView? = null
    var mHandler: Handler = Handler()

    init {
        myBiz = MyBiz()
        myView = view
    }

    fun exec() {
        myBiz.exec(myView?.getStr() as String, object : OnExecListener {
            override fun execSuccess(model: MyModel) {
                System.out.println("aaaaaaaaa")
                mHandler.post(Runnable {
                    kotlin.run {
                        myView?.showSuccess(model)
                    }
                })
            }
        })

    }

}
至此,通过Kotlin实现的MVP就完成了,其中用到的Kotlin相关语法主要包括类和对象,接口与继承、匿名内部类以及多线程。文中的代码可见github