当Kotlin遇上MVP、RecyclerView,故事就开始了

Kotlin相对于Java来说,代码量减少很多,代码变得更简洁了,况且Kotlin现在由Google负责,在Andorid上作为主推语言,所以Kotlin的发展前景还是不可限量的。

Kotlin的基本语法就不做介绍了,网上也有很多优秀的博客,请自行搜索.今天就重点介绍Kotlin+MVP+RecyclerView的使用

Activity中初始化

在xml中定义好控件设定好id后,在Activity中直接使用

    /**
     * 设置按钮的点击事件
     */
    fun initView() {

        //直接使用控件id设置监听
        btn1.setOnClickListener {
            click1()
        }

        btn2.setOnClickListener(this)

    }

    /**
     * 点击事件
     * 批量处理,通过when函数
     */
    override fun onClick(v: View?) {
        when (v?.id) {
            R.id.btn2 -> click2()
            else -> {
                //失败处理
            }
        }
    }

点击事件里的具体实现稍后再看,现在先看下initPresenter函数

    /**
    * 延迟加载
    * lateinit:只能用在var类型,可初始化多次,延迟加载
    */
    private lateinit var presenter: RegisterContract.Presenter

    /**
     * 初始化Presenter
     * 把RegisterContract.View、Context传进入
     */
    fun initPresenter() {
        //创建Presenter对象
        presenter = RegisterPresenter(this, this)
    }

点击事件click1函数实现

    /**
     * 创建对象并提交信息
     */
    fun click1() {

        //直接通过 对象() 创建对象
        var userInfo = UserInfo()
        userInfo.name = "xiaoming"
        userInfo.sex = "woman"
        userInfo.num = 25
        userInfo.height = 178

        //提交对象信息
        presenter.submitRegisterInfo(userInfo)
    } 

从click1函数可以发现,创建对象没有 “new” 关键字,直接 “对象()” 就可以。

以上代码是不是感觉少了点什么,没错!逗号不需要写了。

具体的MVP代码

协调器RegisterContract
和java区别不大,只是参数变成了(变量名:类型)、修饰符变成 fun

/**
 * Created by yunzhao.liu on 2018/3/7
 */
interface RegisterContract {

    /**
     * 负责更新Activity的UI
     */
    interface View {
        fun registerSuccess(info: String)

        fun registerFailure(msg: String)
    }

    /**
     * 连接View和Model的桥梁
     */
    interface Presenter {
        fun submitRegisterInfo(info: UserInfo)
    }

    /**
     * 负责提供数据
     */
    interface Model {
        fun getRegisterInfo(info: UserInfo, listener: OnListener)
    }
}

连接View和Model桥梁的RegisterPresenter

class RegisterPresenter : RegisterContract.Presenter {

    private var view: RegisterContract.View
    private var context: Context
    private var mode: RegisterMode

    /**
     * Presenter的构造函数
     */
    constructor(view: RegisterContract.View, context: Context) {
        this.view = view
        this.context = context
        //创建RegisterMode对象
        this.mode = RegisterMode()
    }

    /**
     * 提交注册信息
     */
    override fun submitRegisterInfo(info: UserInfo) {
        mode.getRegisterInfo(
                info, object : OnListener {//匿名接口

                override fun onSuccess(response: String?) {
                    //!!为空判断,如果是null就返回null
                    view.registerSuccess(response!!)
                }

                override fun onFailure(msg: String?) {
                    if (msg != null) {
                        view.registerFailure(msg)
                    }
                }
            }
        )
    }
}

提供数据的RegisterMode

/**
 * Created by yunzhao.liu on 2018/3/7
 */
class RegisterMode : RegisterContract.Model {

    /**
     * 获取注册数据
     */
    override fun getRegisterInfo(info: UserInfo, listener: OnListener) {

        listener.onSuccess("姓名:${info.name} "
                + "- 年龄:${info.age}"
                + "- 身高:${info.height}"
                + "- 性别:${info.sex}"
                + "- 班号:${info.num}")

        Handler().postDelayed(Runnable {
            listener.onFailure("failure")
        }, 3000)

    }
}

在Activity中实现 RegisterContract.View 的方法

    override fun registerSuccess(info: String) {
        toast(info)
    }

    override fun registerFailure(msg: String) {
        toast(msg)
    }

toast是什么鬼?稍后解释

具体Kotlin+RecyclerView代码

下面重点来看下Kotlin与RecyclerView的使用

    /**
     * 初始化RecyclerView相关数据
     */
    fun initRecyclerViewData() {

        //获取列表数据
        val list = getList()
        //创建Adapter对象
        var adapter = RegisterAdapter(this, list)
        //给RecyclerView设置Adater
        recycler_view.adapter = adapter
        //设置LayoutManager
        recycler_view.layoutManager = (LinearLayoutManager(this))

        //RecyclerView条目点击(自定义回调函数)
        adapter.setOnItemClickLitener(object : RegisterAdapter.OnItemClickListener{
            override fun onItemClick(position: Int) {
                toast("点击位置是:$position")
            }
        })
    }

定义 RegisterAdapter 类
注释很清楚了,就不多做解释了

/**
 * Created by yunzhao.liu on 2018/3/7
 */
class RegisterAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder> {

    private var context: Context
    private var list: ArrayList<Product>
    private var inflater: LayoutInflater

    constructor(context: Context, list: ArrayList<Product>) {
        this.context = context
        this.list = list
        this.inflater = from(context)
    }

    /**
     * 条目数
     */
    override fun getItemCount(): Int {
        //为空就返回0
        return list?.size
    }

    /**
     * 获取布局类型
     */
    override fun getItemViewType(position: Int): Int {
        val product: Product = list.get(position)
        when (product.type) {
            2 -> return 2
            4, 5, 8 -> return 2
            else -> {
                return 1
            }
        }
    }

    /**
     * 创建多布局ViewHolder
     */
    override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): RecyclerView.ViewHolder {
        return when (viewType) {
            1 -> {
                OneViewHolder(inflater.inflate(R.layout.recycler_item_one, parent, false))
            }
            2 -> {
                TwoViewHolder(inflater.inflate(R.layout.recycler_item_two, parent, false))
            }
            else -> {
                OneViewHolder(inflater.inflate(R.layout.recycler_item_one, parent, false))
            }
        }
    }

    /**
     * 绑定ViewHolder
     */
    override fun onBindViewHolder(holder: RecyclerView.ViewHolder?, position: Int) {
        val product = list[position]
        //获取条目类型
        when(getItemViewType(position)){
            2,4,5,8->{
                //强势转换 as ,安全转换 as?, 类型判断:is
                var twoViewHolder:TwoViewHolder = holder as TwoViewHolder
                twoViewHolder.name.text = product.name
                twoViewHolder.price.text = "${product.price}"
                twoViewHolder.item_root.setOnClickListener {
                    itemClick!!.onItemClick(position)
                }
            }
            else ->{
                var oneViewHolder:OneViewHolder = holder as OneViewHolder
                oneViewHolder.name.text = product.name
                oneViewHolder.price.text = product.price.toString()
                oneViewHolder.item_root.setOnClickListener {
                    itemClick!!.onItemClick(position)
                }
            }
        }
    }

    /**
     * 获取控件ID --> 一种方式
     */
    class OneViewHolder(view:View):RecyclerView.ViewHolder(view){
        var item_root:LinearLayout = view.item_root
        var name:Button = view.name
        var price:Button = view.price
    }

    /**
     * 获取控件ID --> 一种方式
     */
    class TwoViewHolder : RecyclerView.ViewHolder{
        var item_root:LinearLayout
        var name:Button
        var price:Button

        constructor(view: View) : super(view){
            name = view.name
            price = view.price
            item_root= view.item_root
        }
    }

    /**
     * 条目点击 --> 接口回调
     */
    private var itemClick: OnItemClickListener?=null

    interface OnItemClickListener{
        fun onItemClick(position: Int)
    }

    fun setOnItemClickLitener(itemClick: OnItemClickListener) {
        this.itemClick = itemClick
    }

}  

扩展函数

在上面细心的同学已经看见了,我们使用toast(mag:String)这个方法,它就是我们定义的扩展函数。我们只需要创建一个Koltin的类,然后按照下面这种格式就可以自定义自己的扩展函数

fun 函数扩展的对象.扩展函数的名称(扩展函数的参数,可以为null){
    body
}

这是我自定义的扩展函数

/**
 * 对Context的扩展函数
 */
fun Context.toast(message: String, duration: Int = Toast.LENGTH_SHORT) {
    Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
}

/**
 * 对Log的扩展函数
 */
fun Log.log(message: String) {
    Log.d("liuyz", message)
}

/**
 * 对Log的扩展函数
 */
fun Log.log(tag: String = "liuyz", message: String) {
    Log.d(tag, message)
}

/**
 * 对EditText监听的扩展
 */
fun EditText.setTextChangedListener(body: (key: String) -> Unit) {
    addTextChangedListener(object : TextWatcher {
        override fun afterTextChanged(s: Editable?) {

        }

        override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {

        }

        override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
            body(s.toString())
        }
    })
}

源码下载

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值