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

详解Kotlin和anko融合进行Android开发

程序员文章站 2024-04-01 23:03:22
kotlin是一门基于jvm的编程语言,最近进行了关于kotlin和 anko的研究。并且结合现在的app设计模式,设想了初步的开发方式。并且准备应用在新的项目中。 ko...

kotlin是一门基于jvm的编程语言,最近进行了关于kotlin和 anko的研究。并且结合现在的app设计模式,设想了初步的开发方式。并且准备应用在新的项目中。

kotlin和anko

kotlin是大名鼎鼎的jb公司开发的jvm语言,官网地址为;

官网的介绍为:

statically typed programming language for the jvm, android and the browser

kotlin的设计思想非常的轻量,尽可能的去复用java代码,不到万不得已的时候,一般不会自己去实现一套大而全的库。这使得kotlin非常的轻量,集成到android的project并不会很明显的影响最终的打包大小。

关于kotlin的优点,自己总结了几点:

1,和java的无缝调用,这在初期不需要投入非常大的精力,即使遇到搞不定的坑,也不必担心影响业务开发的进度,直接换成java就好了。

2,大量的语法糖,使得代码非常的简洁,熟悉之后的开发效率也要高于java。例如扩展函数,简单的封装再也不需要写一大堆utils工具类,直接灵活的给某些类添加扩展方法就可以了。例如:

inline fun activity.toast(message : int) {
   toast.maketext(this, message, toast.length_short).show()
 }

这样在activity类中就多出了一个toast方法,实际上在anko中,也有大量已经写好的扩展方法,可以直接使用dsl语法去写ui。再例如when语句的写法:

when(x) {
1-> {}
2-> {}
}

很明显,相比传统的java写法,使用anko后,语言更加简洁。

switch(x) {
case 1:
 break;
case 2:
 break;
default:
 break;
}

3,更加安全,kotlin似乎比较想消灭空引用,在java中,调用一个null对象会抛出nullpointexception,在kotlin中,不能为空的对象,例如string对象,会写成:

var a: string? = "abc" 

4,良好的生态环境和开发社区。kotlin目前还是属于比较新的技术,很多人也都在尝试它的有点。包括rx系列也出了rxkotlin,既rxjava的kotlin版

kotlin和anko使用

anko的github地址为https://github.com/kotlin/anko。集成anko的步骤如下:

首先在project的build文件加入如下代码:

dependencies {
    classpath 'com.android.tools.build:gradle:2.2.3'
    classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" //这是需要你加入的
  }

allprojects {
  repositories {
    jcenter()
    maven {url 'https://dl.bintray.com/jetbrains/anko'} //这是你需要加入的
  }
}

然后,在你app moudle的build文件里面添加依赖:

compile "org.jetbrains.anko:anko-sdk15:0.9.1" // so here it's 15 too
  compile "org.jetbrains.anko:anko-appcompat-v7:0.9.1"
  compile "org.jetbrains.anko:anko-design:0.9.1"
  compile "org.jetbrains.anko:anko-recyclerview-v7:0.9.1"

根据kotlin的优势,选择使用anko进行编写,不使用xml进行编写。

这样的好处在anko的github readme文件中是这样描述的:

  1. 不安全
  2. 没有空安全
  3. 迫使你为了每一个布局去写很多相似甚至重复的代码
  4. xml在设备上浪费cpu时间和电量(应该是需要进行解析的原因) 不允许代码重用(没有完全理解,可能说的不是include标签而是自定义的layout)
  5. 至于contract接口以及实体对象,可以直接使用kotlin编写,第一为了语法简洁,第二不用写一大堆setter/getter方法。

具体的,首先编写mainactivity类,进行ui展示和事件等逻辑。

class mainactivity : appcompatactivity(), maincontract.view {
  override fun oncreate(savedinstancestate: bundle?) {
    super.oncreate(savedinstancestate)
  }
}

接下来在oncreate中编写ui布局,登录布局比较简单,就是2个输入框和一个按钮,当然为了试用多点的常见控件,我在最上方添加了toolbar。

relativelayout {

      var mtoolbar =
      toolbar(r.style.base_themeoverlay_appcompat_dark_actionbar) {
        id = id_toolbar
        title = "登录"
        backgroundcolor = contextcompat.getcolor(this@mainactivity, r.color.colorprimary)

        popuptheme = r.style.base_themeoverlay_appcompat_light
        inflatemenu(r.menu.main)

        setnavigationicon(r.mipmap.img_back_white)

        onmenuitemclick {
          menuitem ->
          val itemid = menuitem!!.itemid
          when (itemid) {
            r.id.menu_main -> {
              toast(r.string.main_toast)
            }
          }
          false
          }

        lparams {
          width = matchparent
          height = wrapcontent
        }

        setnavigationonclicklistener {
          finish()
        }
      }

      var museredit = edittext {
        id = id_user_edit
        hint = "请输入同户名"
        maxlines=1

        lparams {
          width = matchparent
          height = wrapcontent
          margin=dip(8)
          centerinparent()
        }
      }

      var mpsdedit = edittext {
        id= id_psd_edit
        hint="请输入密码"
        maxlines=1
        maxwidth = 16

        lparams {
          width = matchparent
          height = wrapcontent
          margin = dip(8)
          below(id_user_edit)
        }
      }


      var mbutton = button("登录") {
        id= id_btn_login

        onclick {
          var username = museredit.text.tostring()
          var password = mpsdedit.text.tostring()

          mpresenter!!.login(username,password)
        }

        lparams {
          width= matchparent
          height = wrapcontent
          margin = dip(8)
          below(id_psd_edit)
        }
      }
    }

代码中的id使用了常量,在kotlin中没有static的概念,但是有一个companion object(伴随对象)可以模拟实现类似static的功能。

companion object static {
    val id_toolbar: int = 1
    val id_user_edit: int = 2
    val id_psd_edit: int = 3
    val id_btn_login: int = 4
  }

可以看到,这样编写ui的代码非常的简洁。而且可读性非常的高。相信对xml写布局比较熟悉的同学都能看懂这里面代码的含义。同时官方还出了一个android stduio插件,叫做anko sdl preview。可以很方便的让开发者预览编写的效果。接下来按照mvp的思想, 编写baseview和basepresenter接口。

interface baseview<t> {
  fun setpresenter(presenter: t)
}
interface basepresenter

使用kotlin编写maincontract接口,这个接口建立起了v层和p层的通信。

interface maincontract {
  interface view : baseview<presenter> {
    fun login()
    fun loginnull()
  }

  interface presenter : basepresenter {
    fun login(username: string, password: string)
  }
}

使用java编写p层代码。

public class mainpresenter implements maincontract.presenter {

  private maincontract.view mview;

  public mainpresenter(maincontract.view view) {
    mview = view;
    mview.setpresenter(this);
  }

  @override
  public void login(string username, string password) {
    if (textutils.isempty(username) || textutils.isempty(password)) {
      mview.loginnull();
      return;
    }
    mview.login();
  }
}

这里只是模拟了下登录的逻辑,并没有去真的实现一个登录

回到mainactivity,在这里加入我们的代码。

var mpresenter : maincontract.presenter? = null
override fun setpresenter(presenter: maincontract.presenter) {
  mpresenter = presenter!!
}

实现v层应该实现的回调方法:

override fun loginnull() {
  toast("用户名密码不得为空")
}

override fun login() {
  toast("执行登录逻辑...")
}

到这里,我们就完成了kotlin和anko开发android的实例,如果想要更加熟练的使用,还需要多加练习。

附:anko的github地址为https://github.com/kotlin/anko

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。