Kotlin—Anko库的使用

Kotlin我们也学了一些基础,但怎么用我们还是不知道?今天我们从基础转向实战,在Android平台上开发Kotlin

因为这篇我们会讲到anko的知识下面贴出它的官网地址,感兴趣的可以单独去研究

https://github.com/Kotlin/anko/wiki

Start

调用第三方库使用Kotlin

这里我们以ButterKnife为例,配置ButterKnife在Kotlin的环境

首先加入kotlin的classpath

ext.kotlin_version = '1.1.2-3'
repositories {
    jcenter()
}
dependencies {
    classpath 'com.android.tools.build:gradle:2.3.1'
    classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
  
}

然后添加kotlin依赖

apply plugin: 'kotlin-android'
compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"

最后加入ButterKnife依赖,这里需要注意的是另外也添加kapt插件

apply plugin: 'kotlin-kapt'
compile 'com.jakewharton:butterknife:8.6.0'
kapt 'com.jakewharton:butterknife-compiler:8.6.0'

这样kapt会将ButterKnife的java代码转化为kotlin代码

至此环境就配置好了,当然你也可以在网上搜一搜,这里也就是做个笔记

使用anko库

Anko Dialog

对于Anko的Dialog用的最多的也Toast的使用,在Anko中使用toast是相当的简单

fun open_toast(view: View){
    toast("toast")
    longToast("long toast")
}   

然后就是AlertDialog的使用也是一看就会用的那种

fun open_alert(view: View){
alert("Hi,I'm Roy","Have you tried turning it off and on again?"){
    yesButton { toast("yes") }
    noButton { toast("no") }
}.show()

//当然你也可以使用自定义的View
alert{
    customView{
        editText()
    }
}
}

当然还有其它的弹框这里就不一一介绍,具体请看官方

Anko Intent

相比之前的Intent来说Anko提供的更加的方便,使用如下

startActivity(intentFor<AnkoActivity01>("id" to 5).singleTop())

其他的一些使用如下:

image
Anko Log

对于Log,Anko解释AndroidSDK提供的Log也是非常的简单,尽管方法需要你传递标签参数,但使用起来也是非常的简单,当然你也可以使用AnkoLogger来消除这一点

  1. 实现AnkoLogger的方式

     info("this is second log info")
    
     //这种带lambda表达式的这种会去计算Log.isLoggable(tag, Log.INFO)是否为true,为true的话才打印
     info { "this is third log info" }
    
  2. 使用其对象的方式

     val logWithASpecificTag = AnkoLogger("lypop")
     logWithASpecificTag.info { "this is Log info" }
    

第一种Tag默认是类名,第二种可以自定义其Tag

Anko helper

你可以在你的项目中使用帮助者来简化你的代码,例如Color、Dimen等,颜色透明度直接色值.opaque就可以,尺寸的话直接使用dip(dipValue)、sp(spValue)就可以。在这里面还有一个就是applyRecursively()用来控制子View的操作,如:

    verticalLayout {
        textView{
            text = "EditText01"
            backgroundColor = 0xff000.opaque
            textSize = 14f
        }
        textView {
            text = "EditText02"
            backgroundColor = 0x99.gray.opaque
            textSize = 23f
        }
    }.applyRecursively {//如果是ViewGroup的话可以使用applyRecursively来为每个Child View进行设置
        view -> when(view){
            is TextView -> view.textColor = Color.RED
        }
    }
Anko Coroutines

Anko还提供了协程的用来做一些耗时的操作,提供的操作为bg{},具体代码如下:

    async(UI){//UI线程
        val data: Deferred<MyBean> = bg {//后台线程
            // Runs in background
            MyBean()
        }

        showData(data.await()) //await方法将一直等待bg返回的数据
    }

为了防止内存泄漏我们常会使用弱引用,在Anko中使用弱引用方法如下:

   val ref: Ref<AnkoActivity05> = this.asReference()

    async(UI){
        //ref替代了this@AnkoActivity05
        ref().showData()
    }
Anko Layout

那我们先来说一下普通写Android布局有啥缺点

  1. 它不是类型安全的和不是空安全
  2. 它迫使您为每个布局都编写相同的代码
  3. 在设备上解析xml浪费CPU时间和电池
  4. 最重要的是它不允许代码重用

那Kotlin不行吗?为什么还要用anko呢?

官方解释说Kotlin那种是解决了不能编程生成UI,但是用Kotlin代码写出来的UI难以维护所以才出现了anko库,具体相应的代码还请看官网。(其实也没必要看,毕竟出来了一种库必然有其存在的原因)

verticalLayout {
    padding = dip(30)
    button("say"){
        onClick {toast("Hello,${if (it is TextView) it.text else ""}") }
    }
    button(R.string.app_name)
    button{
        textResource = R.string.app_name
    }.lparams { //如果指定了 lparams 但是没有指定 width 或者 height,那么默认是 “wrapContent”
        width = matchParent
        topMargin = dip(10)
        horizontalMargin = dip(5)
   
    }
}

Activity没有显示调用setContentView,anko会自动为Activity设置Content View

这里列举了button的三种创建形式和为其设置参数
当然在Activity/Fragment也会使用xml布局,anko也为我们提供了简单的创建控件对象的方式

  1. 对象的名字就是控件的ID
  2. 使用find<TextView>(R.id.name)也可以

可以看出这几种都比Android的findViewById要舒适的多

当然代码中还可能会有

  1. include

     include<View>(R.layout.something) {
         backgroundColor = Color.RED
     }.lparams(width = matchParent) { margin = dip(12) }
    
  2. 自定义View

     inline fun ViewManager.myView(init: MyView.() -> Unit): MyView {
         return ankoView({ MyView(it) }, 0, init)
     }
    
     class MyView(ctx: Context) : View(ctx) {
         fun test() {
     
         }
     }
    

使用的时候和上面使用方法一样直接用myView{}

但是非常遗憾的是没有预览界面,虽然anko提供了支持插件,但非常遗憾的是仅支持AndroidStudio2.4+

这样我们就创建了一个简单的布局

fun Context.sendSMS(number: String, text: String = ""): Boolean {
    try {
        val intent = Intent(Intent.ACTION_VIEW, Uri.parse("sms:$number"))
        intent.putExtra("sms_body", text)
        startActivity(intent)
        return true
    } catch (e: Exception) {
        e.printStackTrace()
        return false
    }
}
Anko SQLite

在之前使用SQLiteOpenHelper,通常调用getReadableDatabase()或getWritableDatabase(),但是您必须确保在接收的SQLiteDatabase上调用close()方法。如果您从多个线程中使用它,则必须了解并发访问。 所有这一切都很艰难。
这就是为什么Android开发人员不太喜欢默认的SQLite API,而是更喜欢使用相当昂贵的包装器,如ORMs。

Anko提供了ManagedSQLiteOpenHelper 可以无缝替代默认的,当操作完毕之后就会自动关闭,在使用的时候需要去继承ManagedSQLiteOpenHelper

class MySqlHelper(ctx: Context = MyApplication.getApplication(),
              name: String? = "db",
              factory: SQLiteDatabase.CursorFactory? = null,
              version: Int = 1) : ManagedSQLiteOpenHelper(ctx, name, factory, version) {

我们如果想让它成为线程安全的可以

    companion object {
        @Volatile private var helper: MySqlHelper? = null

        fun getInstance(): MySqlHelper {
            if (null == helper) {
                synchronized(MySqlHelper::class) {
                    if (null == helper) {
                        helper = MySqlHelper()
                    }
                }
            }
            return helper!!
        }
}

然后我们就可以使用Anko提供的数据库操作了

fun queryAll(): List<Gps> = use {
    select(Gps.TABEL_NAME).exec {
        parseList(classParser<Gps>()) //查询使用parserXX方法需要存在查询字段的相应构造方法
    }
}

fun queryLonAfter(id: Long): List<Double> = use {
    select(Gps.TABEL_NAME, Gps.LON).whereArgs("${Gps._ID} > {id}", "id" to id)
            .exec {
                parseList(DoubleParser)
            }
}

fun deleteById(id: Long){
    use {
        delete(Gps.TABEL_NAME, "${Gps._ID} = {id}", "id" to id)
    }
}

fun updateById(id: Long) {
    use {
        update(Gps.TABEL_NAME, Gps.PROVIDER to "lbs").whereArgs("${Gps._ID} = {id}", "id" to id).exec()
    }
}

这里使用use来包裹,当里面的代码执行完毕就会自动关闭数据库

至此,Anko就讲解完毕,更多的内容还请阅读官方,Thanks♪(・ω・)ノ

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,185评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,445评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,684评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,564评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,681评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,874评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,025评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,761评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,217评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,545评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,694评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,351评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,988评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,778评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,007评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,427评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,580评论 2 349

推荐阅读更多精彩内容