Kotlin:Android开发技巧

代码星冰乐

专注成就未来

首页 归档 关于

Kotlin:Android开发技巧

May 12, 2018 | ChanghuiN | Kotlin | 阅读
文章目录
  1. 1. Kotlin 基础技巧
    1. 1.1. 单例
    2. 1.2. Kotlin 委托
    3. 1.3. run、with、apply、alse、let、takeIf、repeat
    4. 1.4. 拓展函数
  2. 2. Anko 框架
    1. 2.1. Anko Commons
    2. 2.2. Anko Layouts
    3. 2.3. Anko SQLite

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


由于版权原因,请阅读原文 --> Kotlin:Android开发技巧

关注我们

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

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

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

Kotlin 基础技巧

单例

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

1
2
3
4
5
6
7
8
class App : MultiDexApplication() {
companion object {
var INSTANCE: APP by Delegates.notNull()
}
override fun onCreate() {
INSTANCE = this
}
}

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

第二种:Kotlin关键字object

1
2
3
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 模式。
扩展是一种静态行为,对被扩展的类代码本身不会造成任何影响。
这里列出几个常用的拓展函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/**
* 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:

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

Anko Dialogs

1
2
3
4
5
6
7
8
9
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

1
2
3
4
5
6
7
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

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

Dimensions

1
2
3
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接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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())

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

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

关注我们

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

分享
AndroidKotlin
classpath* 和 classpath使用遇到的问题死磕Java之聊聊ThreadLocal源码(基于JDK1.8)
微信关注我们
分类
  • Android8
  • Go4
  • Java59
  • Kafka,Java1
  • Kotlin2
  • Linux1
  • MapReduce1
  • Python2
  • Raft1
  • Redis1
  • ThreadPoolExecutor1
  • go1
  • 工具1
  • 总结8
  • 旅游日记1
标签
Nginx ChanghuiN haifeiWu Android Java 设计模式 hexo Kotlin 算法 MySQL 源码解析 Python Redis golang web Kafka 配置中心 总结 性能优化 旅游日记 Shell Go 问题排查 译文 Docker Spring Boot 工具 学习笔记 WebFlux 性能测试 go 散列表 源码 netty Raft
最近文章
  • Kafka的日志复制机制
  • 从20到21
  • go 并发编程
  • 【译】了解Linux CPU负载-您何时应该担心?
  • Zookeeper 与分布式锁
  • 基于Redis的分布式锁到底安全吗?
  • 【译】Raft 学生指南
  • ThreadPoolExecutor 的简单梳理
  • MapReduce 的简单实现
  • 使用 Map 实现策略模式
福利专区
    免费SSL证书
      阿里云红包
        腾讯云专属福利
        Copyright © 2021 代码星冰乐. Powered by ChanghuiN. 版权所有 晋ICP备15001365号
        特别感谢: 云服务器服务商 、 CDN 服务商