Android-Kotlin全攻略

作为一名Android开发者,觉得很有必要学习Kotlin这门语言,学成之后,希望融入到开发中。

Kotlin是什么?

kotlin是一种在Java虚拟机上运行的静态类型编译语言,它也可以编译成为JavaScript源代码,它主要是由俄罗斯圣彼得堡的JetBrains开发团队所发展出来的编程语言,其名称来自于圣彼得堡附近的科特林岛。2012年1月,著名期刊《Dr. Dobb’s Journal》中Kotlin被认定为该月的最佳语言

在Android中使用

声明Activity

1
2
3
4
5
6
class MyActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity)
}
}

创建点击事件

1
2
3
4
val fab = findViewById(R.id.fab) as FloatingActionButton
fab.setOnClickListener {
...
}

创建项目点击事件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
private val mOnNavigationItemSelectedListener
= BottomNavigationView.OnNavigationItemSelectedListener { item ->
when (item.itemId) {
R.id.navigation_home -> {
mTextMessage.setText(R.string.title_home)
return@OnNavigationItemSelectedListener true
}
R.id.navigation_dashboard -> {
mTextMessage.setText(R.string.title_dashboard)
return@OnNavigationItemSelectedListener true
}
}
false
}

Kotlin语法大全

类别属性

用于控制作用域

1
2
3
4
public
internal
protected
private

含义:

  • public:全局可见,默认类型
  • internal: 在当前模块中可见
  • protected: 在当前类的一级子类中可见,如果子类载被继承,不可见
  • private: 在当前类中可见

    常量与变量

  • 使用val为常量,定义后无法修改

    1
    2
    val a: Int = 1 //定义一个Int类型的常量,值为1
    val b = 2 //自动检测类型
  • 使用var为变量,定义后可修改

    1
    2
    var x = 5 //定义一个Int类型的变量,值为5
    x = 1 //修改值为1

数值类型

字符串不属于数值类型,是一个独立的数据类型

  • Double64
  • Float32
  • Long64
  • int32
  • Short16
  • Byte8

List

  • 只读list

    1
    val list= listOf("a","b","c")
  • 可变list

    1
    2
    val mulList= mutableListOf("a","b")
    mulList.add("c")
  • 只读list转为可变list

    1
    2
    val list= listOf("a","b","c")
    val mulList=list.toMutableList()

Map

  • 只读map

    1
    val map = mapOf("a" to 1, "b" to 2, "c" to 3)
  • 可变map

    1
    val mulMap = mutableMapOf("a" to 1,"b" to 2)
  • 只读map转为可变map

    1
    2
    val map = mapOf("a" to 1,"b" to 2)
    val mulMap = map.toMutableMap()
  • 访问map

    1
    2
    val map = mapOf("a" to 1, "b" to 2, "c" to 3)
    println(map["a"])

位操作符

1
2
3
4
5
6
7
8
val a=22
a.shl(1)//左移一位
a.shr(1)//右移一位
a.ushr(1)//无符号右移一位
a.and(11)//与
a.or(22)//或
a.xor(23)//异或
a.inv()//反向

延迟属性

1
2
3
val p: String by lazy {
//计算该字符串
}

创建单例

1
2
3
4
5
object UserData{
fun foo(){
println("foo")
}
}

不为空缩写

只需要添加一个?

1
2
val files=File("Test").listFiles()
println(files?.size)

判空执行缩写

如果非空返回本身,如果空返回默认值,使用?:

1
2
val files=File("Test").listFiles()
println(files?.size?:"empty")

不为空执行

1
2
3
4
val value=""
value?.let{
...
}

对象多调

对于一个对象,可以调用多次该方法,使用with

1
2
3
4
5
6
7
8
9
10
11
12
13
class  Test{
fun run(){}
fun jump(){}
fun see(){}
}

val test=Test()
with(test){
run()
val a=1
jump()
see()
}

可空值null检测

如果需要返回null,要加个?否则会报错

1
2
3
4
5
6
7
fun sum(vararg v:Int):Int?{
var a=0
for (b in v){
a+=b
}
return null
}

When表达式

进行条件判断,也可以用于if多重判断

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
when(a){
1 -> print("1")
2 -> print("2")
in 3..10 -> print("3~10")
!in 8..9 -> print("no in 8~9")
is Int -> print("int 类型")
else ->{
print("no")
}
}
when{
a<10 -> print("<10")
a>100 -> print(">100")
else ->{
print("no")
}
}

函数

使用fun定义函数

1
2
3
4
5
6
fun sum(a:Int , b:Int): Int{
return a+b;
}

//简写
fun sum(a:Int , b:Int) = a + b

匿名函数

1
2
3
4
val c : (Int,Int) ->Int ={a,b ->a+b}

>>>>>> println(c(1,2))
=====> 3

可变参数

可变参数可以使用varag关键字

1
2
3
4
5
6
7
fun sum(vararg v:Int):Int{
var a=0
for (b in v){
a+=b
}
return a
}

函数扩展

能够扩展类的新功能,而无需继承该类

1
2
3
4
5
6
fun String.sayHello(): String{
return "$this Hello"
}

>>>>>> println( "Rhyme" . sayHello() )
=====> Rhyme Hello

函数默认值

1
2
3
fun sum(a:Int = 1,b:Int = 2):Int{
return a+b
}

运算符重载

能够重写运算符方法

1
2
3
4
5
6
7
8
9
10
11
12
13
class Point{
var x: Int? = null
var y: Int? = null
operator fun plus(other: Point): String{
return "${this.x!! + other.x!!} + ${this.y!! + other.y!!}"
}
}

>>>>>> val point = Point()
>>>>>> point.x=1
>>>>>> point.y=2
>>>>>> println( point + point )
=====> 2 + 4

区间

区间表达式可以使用..表示

1
2
3
4
5
6
7
8
9
10

for(i in 0..20) println(i)

// 0 2 4 6 ...
for(i in 0..20 step 2) println(i)

// 20 19 18 ...
for(i in 20 downTo 1) println(i)

for(i in 20 downTo 1) println(i)

解包引数

集合中可以引入另一个集合形成新的集合,只要在另一个集合前面加个*

1
2
3
4
>>>>>> val st= arrayOf("Hello","World")
>>>>>> val list = listOf("args: ", *st)
>>>>>> println(list)
=====> args: ,Hello,World

函数嵌套

一个函数里面可以声明另一个函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
fun String.sayHello(): String {

fun validate(value: String):String{
if (value.isEmpty()){
return "isEmpty"
}
return "$value Hello"
}

return validate(this)
}

>>>>>> println( "" . sayHello() )
=====> isEmpty

解构声明

for遍历中可以获得position

1
2
3
4
5
6
7
8
9
var string=""
val list= arrayOf("Hello","World")

for ((index,element) in list.withIndex()){
string+="$index $element"
}

>>>>>> println( string )
=====> 0 Hello1 World

抽象类

需要被继承,默认是open的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
abstract class Person{
abstract fun say()
open fun run(){}
fun jump(){}
}

class Man: Person() {
override fun say() {
//完全重写父类的方法
}

override fun run() {
super.run() //调用父类的方法
super.jump() //调用父类的方法
}
// jump 重写不了
}

构造函数

kotlin中类可以有一个主构造函数以及多个构造函数,如果主构造函数没有注解或可见性说明,则关键字constructor可省略,如果构造函数没有其它方法,打括号可省略

  • 主构造函数

    1
    2
    3
    4
    class User(
    val userId:Int,
    val userName:String
    )
  • 二级构造函数

    1
    2
    3
    4
    5
    6
    7
    8
    class User(
    val userId:Int,
    val userName:String
    ){
    constructor(userName: String) : this(1, userName)

    constructor(userId: Int):this(userId,"rhyme")
    }

DTOs(POJOs/POCOs)

创建数据对象只要简单的一行代码

1
data class User(val name:String,val age:Int)

会为User类提供以下的功能

  • 所有属性的getters(对于var定义还有setters)
  • equals()
  • hashCode()
  • toString()
  • copy()
  • 所有属性的 component1()component2()……等等(component为声明属性对应的顺序去获取对应的值,例如:component1()User.name的值)

Kotlin编码规范

Kotlin语言跟java语言的编码规范类似,遵循驼峰命名法

  • 类与对象名称以大写字母开头并使用驼峰:

    1
    2
    3
    open class DeclarationProcessor{}

    object EmptyDeclarationProcessor : DeclarationProcessor(){}
  • 函数,属性与局部变量的名称以小写字母开头,使用驼峰而不使用下划线

    1
    2
    3
    fun processDeclarations() {  }

    var declarationCount = 1
  • 测试方法的名称,可以使用反引号括起来的带空格的方法名(Android中不支持这样的方法,要使用下划线)

    1
    2
    3
    4
    5
    class MyTestCase {
    @Test fun `ensure everything works`() { }

    @Test fun ensureEverythingWorks_onAndroid() { }
    }
  • 属性名中如果为常量,应使用大些和下划线分割名称:

    1
    2
    3
    const val MAX_COUNT = 8

    val USER_NAME_FIELD = "UserName"
  • 枚举常量使用大写和下划线分割名称,也可以使用大写字母开头

    1
    2
    3
    4
    5
    6
    7
    8
    9
    enum class Color{
    Red,
    Green,
    }
    //或者
    enum class Color{
    RED,
    GREEN,
    }
  • 私有属性应该使用开头下划线

    1
    2
    3
    class C {
    private val _stringList = mutableListOf<String>()
    }
  • 方法名称一般都是动词或者动词短语:close,open

  • 类的名称一般都是名词或者名词或者名词短语:List,Person
  • 避免在名称中使用无意义的单词:Manager,Wrapper
  • 使用首字母缩写,就将其大写:IOStream,如果缩写较长,只大写其首字母:XmlFormater
  • 无参数的注解可以放在同一行

    1
    2
    @JsonExclude @JvmField
    var x: String
  • 无参数的单个注解可以与相应的声明放在同一行

    1
    @Test fun foo() {  }

评论系统未开启,无法评论!