导入
在AndroidStudio中安装kotlin插件,AndroidStudio 3.0-pre 已经自带kotlin
project-build.gradle
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext.kotlin_version = '1.1.3'
ext.anko_version = '0.10.1'
repositories {
jcenter()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
allprojects {
repositories {
jcenter()
maven { url "http://dl.bintray.com/kotlin/kotlin-dev" }
}
}
app-build.gradle
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
android {
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
}
}
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
compile "org.jetbrains.anko:anko-sdk25:$anko_version"
compile "org.jetbrains.anko:anko-sdk25-coroutines:$anko_version"
compile "org.jetbrains.anko:anko-appcompat-v7:$anko_version"
}
利用Kotlin开发Android常见小记
1.去掉findViewById
通过build.gradle中加入apply plugin: 'kotlin-android-extensions' 来实现。
布局文件activity_main.xml中的一部分
<Button
android:id="@+id/btn_base_click"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="基础控件语法" />
Activity.kt 中使用
import kotlinx.android.synthetic.main.activity_main.*
//直接通过xml-id 进行使用
btn_base_click.setOnClickListener(this)
2.使用Anko-Layouts来写布局?
like this
verticalLayout {
val name = editText()
button("Say Hello") {
onClick { toast("Hello, ${name.text}!") }
}
}
由于多年的xml 布局经验,我还是直接用==xml 布局方便==,虽然xml 在parse资源过程中会带来一些性能消耗,但是无关大雅。
3.Anko-Commons中如何实现activity之间跳转
A->B
定义:
inline fun <reified T: Activity> Context.startActivity(vararg params: Pair<String, Any>)
Use-withData:
startActivity<YOUR_ACTIVITY>(DATA_KEY to DATA)
Use-noData:
startActivity<YOUR_ACTIVITY>()
A->B->A
定义
inline fun <reified T: Activity> Activity.startActivityForResult(requestCode: Int, vararg params: Pair<String, Any>)
Use-withData:
startActivityForResult<YOUR_ACTIVITY>(requestCode = 1,DATA_KEY to DATA)
Use-noData:
startActivityForResult<YOUR_ACTIVITY>(requestCode = 1)
4.如何创建单例
在kotlin直接用object 关键字创建,就是一个单例
object Single {
fun getData(): String {
return "this a single object"
}
}
5.如何创建java-bean data类
创建一个最简单的data 类
data class JavaBean(var name: String, var sex: String) {
}
说到这里讲一讲构造函数,构造函数分为主构造函数和次构造函数。
主构造函数,如果需要对进行更改可以调用init方法
data class Data(var name){
init{
//进行一些初始化或者其他操作
}
}
次构造函数:。如果类有一个主构造函数(无论有无参数),每个次构造函数需要直接或间接委托给主构造函数,用this关键字
data class Data(var name){
init{
//进行一些初始化或者其他操作
}
constructor(name: String, age: Int) :this(name) {
}
}
}
6.如何定义静态常量
在某个类中
class Constant{
companion object {
val DATA = "data"
}
}
Use : var data = Constant.DATA
7.Kotlin-stdlib自带的高阶函数
- apply
定义
/**
* Calls the specified function [block] with `this` value as its receiver and returns `this` value.
*/
@kotlin.internal.InlineOnly
public inline fun <T> T.apply(block: T.() -> Unit): T { block(); return this }
使用
object.apply{
可以使用该object 任何方法,返回该object
}
var applyTextView = TextView(this).apply {
text = "我是测试apply 方法, textview"
textColor = Color.BLUE
textSize = 16F
}
- with
定义
/**
* Calls the specified function [block] with the given [receiver] as its receiver and returns its result.
*/
@kotlin.internal.InlineOnly
public inline fun <T, R> with(receiver: T, block: T.() -> R): R = receiver.block()
使用
with(object){
可以使用该object任何方法,返回block
}
var withTextView = TextView(this)
with(withTextView) {
text = "我是测试with 方法的 textview"
textColor = Color.BLUE
textSize = 18f
}
- let
定义
/**
* Calls the specified function [block] with `this` value as its argument and returns its result.
*/
@kotlin.internal.InlineOnly
public inline fun <T, R> T.let(block: (T) -> R): R = block(this)
使用
object.let{//将object 转换成it对象,然后通过it 对象进行其他操作}
withTextView.let {
it.text = "通过let 进行更改"
}
- run
定义
/**
* Calls the specified function [block] with `this` value as its receiver and returns its result.
*/
@kotlin.internal.InlineOnly
public inline fun <T, R> T.run(block: T.() -> R): R = block()
使用object.run{之行一段代码}
"我是测试run方法的 textview".run { toUpperCase() }
- to
该函数主要用于Pair类型的赋值,如map,set等
val map = mapOf("a" to 1,"b" to 2)
- lazy
延迟加载,只有当使用的时候才进行加载
val lazyText by lazy {
TextView(this).apply {
text = "我是测试lazy 方法的 textview".run { toUpperCase() }
textColor = Color.BLUE
textSize = 18f
}
}
//when view.addView(lazyText) this textView will load
8.Anko-Commons 其他封装的函数
- toast
Toasts.kt类中对toast提供了下面2类进行封装
android.app.Fragment
android.content.Context
toast() //对应LENGTH_SHORT
longToast() //对应LENGTH_LONG
AndroidDialog.kt文件中做了很多扩张方法。
- alert 创建对话框
alert{
title = "真的可以这样用嘛"
message = "好像真的可以啊"
okButton {
toast("确认button")
}
cancelButton {
toast("取消button")
}
}.show()
- indeterminateProgressDialog 旋转进度,默认点击其他view 消失
indeterminateProgressDialog(message = "正在加载", title = "我是title") {
}.show()
- progressDialog 百分比进度条
val pd = progressDialog(message = "正在加载", title = "我是title")
with(pd){
incrementProgressBy(20)
show()
}
- ContextUtilsKt.kt 中find 方法
其中
Activity,Dialog,Fragment,View均扩展该方法
find<YourView>(R.id.xxx)
var btn = find<Button>(R.id.btn_list_click)
封装库中扩展函数千千万,需要慢慢用,慢慢看。
9.如何理解kotlin中的inline 内联函数
每一个函数都是一个对象,并且会捕获一个闭包。
传统函数调用顺序
a()->b()->c()
a()执行完成之后,返回到内存地址,然后执行下一个函数指令,开始调用b(),当b()执行完成之后,回到内存地址,然后开始执行c()函数的指令,存在一个出栈压栈的过程,在空间和时间上都有一定的消耗。
这种情况下,内联函数的出现,即增加了少许空间,但是减少了时间上的消耗。直接在函数体内部执行下一个函数体。
自定义一个内联函数
a.函数体没有其他操作
inline fun testInline(block: () -> Unit) = block()
Use:
testInline{
println("this is block body")
}
b.函数体中有其他操作
inline fun testInline(times:Int,block:(Int)->Unit){
for (index in 0..times - 1) {
block(index)
}
}
Use: print : 0-9
testInline(10){
println(it)
}
注:如果内联函数有多个block 可以用noline 去指定那一个不内联。reified来具体化参数类型
10.如何使用扩展函数,来扩展自己的Android-Utils
先来认识什么是扩展函数
简单点来说,就是真对已有的类,扩展一些新的方法,而不改变原类本身。
写一个最简单的扩展
fun Activity.sayHelloWorld() {
toast("Hello World")
}
Use:for every Activity
sayHelloWorld()
可选参数和默认值
fun Activity.toast(message: CharSequence, duration: Int = Toast.LENGTH_SHORT){
Toast.makeText(this, message, duration)
}
Use:
toast("HelloWorld!!")
toast("HelloWorld!!", Toast.LENGTH_LONG)
reified具体化参数,类传递
fun <reified : Activity> Activity.to() {
toast(this.toString())
}
Use:
to<YourActivity>()
11.Kotlin哪些让人向往的高阶操作函数
-
map
返回一个每一个元素根据给定的函数转换所组成的List,将集合的每一个元素it进行传递下去。
val datas = listOf(1,3,5,7,9)
datas.map{
it+2
}
//print: datas = [3,5,7,9,11]
- **filter** 过滤操作,过滤所有符合给定函数条件的元素。
val datas = listOf(1,3,5,7,9)
datas.filter{
it>5
}
//print:datas = [7,9]
- **sort** 返回一个自然排序后的list。
- **sortBy**返回一个根据指定函数排序后的list。
- **sortDescending** 降序
- **forEach**遍历所有元素,并执行给定的操作。
##### [Kotlin学习资料](https://www.gitbook.com/book/wangjiegulu/kotlin-for-android-developers-zh/details)