Kotlin:Android开发技巧

Kotlin作为Android开发第一语言,然而身边做Android的大多还是使用java。Android转到Kotlin的趋势是必然的,公司隔壁部门已经全部使用Kotlin开发,我们在以后新的项目里,也会以Kotlin为主。关于Kotlin的知识,博主只是在去年下半年的时候看过官网的教程,也读了《Kotlin for Android Developers》,并写了一个练手项目,不过大半年过去了,要把以前学过的知识重新拿起来有点儿不易,于是总结了一些Kotlin在Android开发中的常用技巧。

Kotlin 基础技巧

单例

Kotlin是一种非常简单的语言,单例也是如此,这里列出两种常用的单例格式: 第一种:通过伴生对象+委托实现单例

class App : MultiDexApplication() {
    companion object {
        var INSTANCE: APP by Delegates.notNull()
    }
    override fun onCreate() {
        INSTANCE = this
    }
}

如上代码,在伴生对象中声名变量,并使用netNull委托避免Kotlin中的空异常检查,然后在onCreate中赋值

第二种:Kotlin关键字object

object CommonParam {
    var TAG = ""
}

Kotlin的写法是不是很简单粗暴。

Kotlin 委托

Kotlin中支持委托,有类委托、标准委托、也可以自定义委托。同学们可以看我之前的一篇博客:Kotlin委托

run、with、apply、alse、let、takeIf、repeat

字段

作用

T.run(block: () -> R)

运行函数并返回函数运行结果

T.with(receiver: T, block: T.() -> R)

receiver作为block函数的this,返回函数运行结果

T.apply(block: T.() -> Unit)

运行函数,返回调用者自身

T.also(block: (T) -> Unit)

调用者作为函数it,执行函数并返回调用者自身

T.let(block: (T) -> R)

调用者作为block函数的this,返回函数运行结果

T.tabkeIf(predicate: (T) -> Boolean)

调用者满足函数的条件则返回自身,否则返回null

T.takeUnless(predicate: (T) -> Boolean)

与tabkeIf相反

repeat(times: Int, action: (Int) -> Unit)

从0遍历times,并运行action

拓展函数

Kotlin 可以对一个类的属性和方法进行扩展,且不需要继承或使用 Decorator 模式。 扩展是一种静态行为,对被扩展的类代码本身不会造成任何影响。 这里列出几个常用的拓展函数:

/**
 * Map<K, V?>类型转换为Array<out Pair<K, V>>类型
 */
fun <K, V : Any> Map<K, V?>.toVarargArray(): Array<out Pair<K, V>> =
        map({ Pair(it.key, it.value!!) }).toTypedArray()

/**
 * ImageView加载网络图片
 */
fun ImageView.loadImage(url: String) {
    CommonModule.picasso.load(url).into(this)
}

/**
 * anko.db框架中,数据库查询解析
 */
fun <T : Any> SelectQueryBuilder.parseList(parser: (Map<String, Any?>) -> T): List<T> =
        parseList(object : MapRowParser<T> {
            override fun parseRow(columns: Map<String, Any?>): T = parser(columns)
        })
fun <T : Any> SelectQueryBuilder.parseOpt(parser: (Map<String, Any?>) -> T): T? =
        parseOpt(object : MapRowParser<T> {
            override fun parseRow(columns: Map<String, Any?>): T = parser(columns)
        })

Anko 框架

Anko Commons

Anko Intent helpers:

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

Anko Dialogs

toast("Hi there!")  // Toast
snackbar(view, "Hi there!")     // snacbar
alert("Hi, I'm Roy", "Have you tried turning it off and on again?") {       // alert
    yesButton { toast("Oh…") }
    noButton {}
}.show()
selector("Where are you from?", countries, { dialogInterface, i ->          // selector
    toast("So you're living in ${countries[i]}, right?")
})

AnkoLogger

class SomeActivity : Activity(), AnkoLogger {
    private fun someMethod() {
        info("London is the capital of Great Britain")
        debug(5) // .toString() method will be executed
        warn(null) // "null" will be printed
    }
}

Colors

0xff0000.opaque     // 转变为不透明的颜色
0x99.gray.opaque    // 转变为不透明的灰色
0xabcdef.withAlpha(0xCF) == 0xCFabcdef      // 设置透明度

Dimensions

dip(dipValue)       // dip转换为px
sp(spValue)         // sp转换为px
px2dip/px2sp        // px转换为dip或者sp

Anko Layouts

对于Anko Layouts的话,就相当于把xml的形式以DSL写在代码里,看起来很方便,不过楼主还是习惯了xml的方式,AnkoLayouts使用的比较少,想用的小伙伴们可以自行百度学习吧。

Anko SQLite

Anko提供了很方便的sql接口

class MyDatabaseOpenHelper(ctx: Context) : ManagedSQLiteOpenHelper(ctx, "MyDatabase", null, 1) {
    companion object {
        private var instance: MyDatabaseOpenHelper? = null

        @Synchronized
        fun getInstance(ctx: Context): MyDatabaseOpenHelper {
            if (instance == null) {
                instance = MyDatabaseOpenHelper(ctx.getApplicationContext())
            }
            return instance!!
        }
    }

    override fun onCreate(db: SQLiteDatabase) {
        // Here you create tables
        db.createTable("Customer", true, 
                    "id" to INTEGER + PRIMARY_KEY + UNIQUE,
                    "name" to TEXT,
                    "photo" to BLOB)
    }

    override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
        // Here you can upgrade tables, as usual
        db.dropTable("User", true)
    }
}

// Access property for Context
val Context.database: MyDatabaseOpenHelper
    get() = MyDatabaseOpenHelper.getInstance(getApplicationContext())

然后在需要用数据的地方,执行增删改查就好

database.use {
    // `this` is a SQLiteDatabase instance
}

作 者:ChanghuiN 原文链接:http://www.hchstudio.cn/article/2018/d4ae/ 版权声明:非特殊声明均为本站原创作品,转载时请注明作者和原文链接。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏java架构师

Stream篇(1)

最近在看一个写的很好的博客,为了加深记忆,把自认为重要的东西,一边看,一边记在这里 一、什么是流、字节序列、字节 一条河中有一条鱼游过,这条鱼就是一个字节,这个...

2987
来自专栏性能与架构

Mysql order by排序优化

1. 加大max_length_for_sort_data参数的设置 在MySQL中,排序算法分为两种,一是只加载排序字段到内存,排序完成后再到表中取其他字段,...

3595
来自专栏技术栈大杂烩

Python: 函数与方法的区别 以及 Bound Method 和 Unbound Method

随着我们越来越频繁使用Python, 我们难免会接触到类, 接触到类属性和方法.但是很多新手包括我, 不知道方法 和 函数 的区别,这次简单来讨论下, 如果有哪...

2891
来自专栏灯塔大数据

每周学点大数据 | No.41 join 操作

No.41期 join 操作 Mr. 王:第一个话题就是 join 操作。 join 操作在数据库中还是非常常见的。 小可:这个 join 指的是笛卡儿积操...

3857
来自专栏Ldpe2G的个人博客

Graphviz4S ---- 在Scala中使用DOT语言绘图的开源工具

2086
来自专栏自由而无用的灵魂的碎碎念

通过写Java代码来对MyEclipse进行注册

import java.io.BufferedReader; import java.io.IOException; import java.io...

1314
来自专栏恰童鞋骚年

剑指Offer面试题:27.最小的k个数

  这道题是典型的TopK问题,其最简单的思路莫过于把输入的n个整数排序,排序之后位于最前面的k个数就是最小的k个数。这种思路的时间复杂度是O(nlogn),但...

1462
来自专栏古时的风筝

模拟实现Spring中的注解装配

在Spring中,XML文件中的bean配置是实现Spring IOC的核心配置文件,在早版本的Spring中,只能基于XML配置文件,配置各个对象之间的依赖关...

2235
来自专栏小樱的经验随笔

BZOJ 3038: 上帝造题的七分钟2【线段树区间开方问题】

3038: 上帝造题的七分钟2 Time Limit: 3 Sec  Memory Limit: 128 MB Submit: 1469  Solved: 63...

2644
来自专栏Golang语言社区

Golang标准库学习——buffio包 ---转

import "bufio" bufio包实现了有缓冲的I/O。它包装一个io.Reader或io.Writer接口对象,创建另一个也实现了该接口,且同时还提...

37111

扫码关注云+社区

领取腾讯云代金券