背景:kotlin
kotlin在今天的Android市场已占领了一部分开发语言的份额,大公司在面试或者项目中已涉及到kotlin,下面我将简单介绍一下kotlin的写法与坑是如何规避。该文档江不断更新与优化,下面会从大概到详细的一个过场。以及kotlin的在Android中的写法与使用技巧!
kotlin比较混淆的地方语法使用
var与val:var是定义一个变量,var a:Int=1,在后期使用可以,val是定义一个常量,后期将不可修改。
标识:"?" 、"!!"
people?
people?.name?:"name is null"
people!!.name
Switch与when
三目运算A=a>b?c:d,A=if(a>b)c else d
interface A{
public void log();
public void print(String msg);
}
interface A{
public void log();
public void print(msg:String){
println(msh)
}
}
open:
class A constraction(title:String){
var a;
set(){
//修改set参数
}
get(){
}
init(){
//初始化模块
}
}
in 和 is
in:是遍历数字,类似java foreach中的":"
kotlin:in
for( temp in arry){
}
Java: ":"
for(String value: arry){
}
is:是类型的判断,类似java instanceof,
kotlin: if(a is String)
java: if(a instanceof String)
三目运算
kotlin的语法不支持三目运算,因为?在kotlin中有特殊用法,如果一个参数a?,表示如果该参数为null,将返回一个null值。
Java: a>b?a:b
kotline: var max=if(a>b) a else b;
类的方法、函数扩展扩展:
kotline支持动态方法扩展,无须在类中提前定义好一个类,
class MyInfo{
}
//在其他地方给MyInfo新增一个新的方法,可以通过类名+“.”+ 方法名
fun MyInfo.getName():String{
return "li si"
}
这样就可以使用了
var info:MyInfo=MyInfo()
println(info.getName())
println(MyInfo().getName())
单利:kotlin的单利用关键字object来修饰的
object +类名
object DateUtil{ var name="nihao" fun get():String{ return name; } }
关于类的继承:
JAVA:extends
kotline: ":"
kotlin的继承需要将该父类通过open来修饰,且继承通过":"+类名+()
如果 class A{
}
open class B{
}
如果A类需要继承B类,首先通过open关键字来修饰,然后继承即可
class A:B(){
}
类的构造器:
在kotlin中,如果参数需要在初始化时,需要通过类的沟通传入参数,需要通过关键字"constructor"来申明
class A constructor(a :Int,b:Int){
init{
print("a=$a,b=$b")
}
}
上面的构造器属于一级构造器,如果针对Java中的方法重载,只要参数不同,但是kotlin的构造器只有一个主的,所以想要不同参数的构造器,只能通过二级构造器来完成。
open class MyConstraction constructor(name: String) { //重写构造器 constructor(name: String, age: Int) { } //重写构造器 constructor(name: String, age: Int, sex: Boolean) { } }
二级构造器会造成误解,以及init方法会被多次调用,所以也可以将二级构造器变成一级使用
open class MyConstraction { constructor(name: String) { } constructor(name: String, age: Int) { } constructor(name: String, age: Int, sex: Boolean) { } }
也可以通过默认参数构造器:只需要在类的后面新增参数即可,无须通过constructor关键字
open class MyConstraction (msg:String){ constructor(name: String, age: Int) { } constructor(name: String, age: Int, sex: Boolean) { } }
如果在Java文件中引用了默认参数类。new一个对象,发现报错,应该用 @JvmOverloads去修饰
open claa A @JvmOverloads constructor(name: String, age: Int){
}
默认参数初始值:
fun ok(msg:String="default"): String {
return msg
}
可变参数:vararg
在Java中,可变参数通过...来定义,且放在参数最后一位,
public void test(String... list);
在Kotlin中,可变参数需要通过一个关键字来申明:vararg
fun test(vararg arry:String){
}
数组:
Java在定义数组int[] arry=new int[2]{1,2};
var intarry:IntArray= intArrayOf(1,2,3,4,5)
格式:定义一个变量名:数组类型=赋值
String数组:
String 素组和其他数组有一点区别,按数据格式如下
var string_arry:Array<String>=arratOf("A","B","C")
但是一些版本中可能存在问题:提示错误
正确如下:
第一种:var string_arry=arrayOf("A","B","C",1,2,3,c)
或者
第二种
var string_arry:Array<String>
string_arry=arratOf("A","B","C")
第一种写法,里面的内容可以是任何类型,第二种因为var已定义类型是String,所以在赋值只能是String类型,否则会报错,因为泛型已指定String导致。
字符拼接:
在java中,字符拼接常见如下
String a="ABC",b="abc";
b=b+c;结果是b="ABCabc",
或者StringBuild sb=new StringBuild();
sb.append("ABC").append("abc");
在kotlin中:
var a="ABC" var b="abc is$a"
连接是通过美元符号$来链接你要拼接的内容。不需要+号
System.err.println("字符串长度${a.length}" )
如果拼接设计到对象属性,需要通过{}来包起来
由于美元符是特殊字符,打印该符号如下:${'$'}或者"\$"
容器:
在Java中,容器我们常见的有map,set等,在kotline里也有,但是kotlin的容易分为可变集合和只读集合
Java中:我们定义一个set,
Set set=new Set();
set.add(1);
set.add(2);
set.add(3);
这时,set里有三个值:1,2,3
在kotlin中,
var set:Set<String>
set=setOf(1,2,3,4);
这时set里有四个值,如果需要新增元素,通过如下plus()方法
set.plus(5),你打印发现并没有同步到set容器中,是因为plus()源码如下
public operator fun <T> Set<T>.plus(element: T): Set<T> { val result = LinkedHashSet<T>(mapCapacity(size + 1)) result.addAll(this) result.add(element) return result }
新增值以后,会生成一个新的result,这个result和原来的set已不是一个对象,并且在plus调用会返回,如果想保持一致,只需要再每次调用都把结果赋值给当前set,如果:
set=set.plus(5),这时候,set里面是5个数据集合
可变集合:
MutableSet:是set的可变即可。多了一个add方法
所以var mset:MutableSet<String>=mutableSetOf("A","B","C")
mset.add("D")
不可变通过plus一样可实现一个临时新的变量,MutableSet可变多一个add
List和MutableList也是参考Set的用法。同时,容器本身也支持排序:
sortBy和sortByDescending
Map的使用:
java中,map提供了key和value,
kotline写法:
var map:Map<String,String> // 第一种 map= mapOf("a" to "65","b" to "66","c" to "67" ); // map= mapOf(Pair("A","96"),Pair("B","97"),Pair("C","99")) 如果是可变MutableMap,依旧可以通过add来新增,如果不是,只能通过plus()来管理
容器的迭代:
1.in的使用
在Java中,我们迭代使用的for很多
for(int a=0;a<list.size();a++)或者for(String item:list)
但是在kotlin中,使用in来处理
for(item in list),也支持java的写法
for (index in list.indices) { println( list.get(index)) }
2.Iterator
Java和kotlin都支持Iterator,写法也基本一样
Java:
Iterator iterator = list.iterator(); while (iterator.hasNext()) { String item=iterator.next(); }
Kotlin:
val iterator=set.iterator(); while (iterator.hasNext()) { var value=iterator.next(); }
3.forEach,只要在for循环中定义一个容器类型的临时对象即可
Java中的forEach:
for(String item:list)
kotlin:容器本身提供一个forEach方法,item为内部的it对象,直接引用即可
set.forEach { print(it)}
备注:如果使用$it连接符,需要注意,该连接符是连接"$it",后面不可连续接未定义的对象,
比如:print("值为:$it的数字"),这样会报错
正确:print("值为:$it 的数字")或者print("值为:${it}的数字")
需要通过{},把定义的变量引用到指定的位置
条件语句
1.if的使用
kotlin的if语句,不仅可以作为条件判断,还可以作为三目运算
类似Java的三目运算,因为kotlin不支持三目运算
var resullt=if(3>2){"3>2"}else{"3<2"}
其他就是正常的条件判断:
if(3>2){
printf("3>2");
}else{
printf("3<2");
}
2.when的语句
when语句和Java中的Switch语句一样,但是when语句支持的条件比Switch更多
Java:
switch (2) { case 1: break; }
kotlin:
when (text) { 1 -> { println("1") } 2 -> { println("2") } 3 -> { println("3") } else -> { println("defaule:") } }
java是从case,但是kotlin不需要,直接 "text->"格式,如果没命中,java是default,kotlin是else
3.for循环 in的高阶用法
kotlin for循环非java的for(int index0;index<size;index++)
kotlin for特性如下:
3.1 until,从A到B,但是不包括B,【10,100),左边是闭区间,右边是开区间
for(item in 0 until 100)
tem=[0,100)
3.2 step:步长的意思,类似java for(a;,b;c)中c的条件
for(temp 0..100 temp 4)
这里面的".."连接,0..100=[0,100],step是步长
until 也可以配合temp一起使用:for(item in 0 until 100 temp 4)
3.3downTo:递减的意思
for ( item in 10 downTo 0) 从高到底递减,类似--
备注:这里面的特性如果没有特意写temp 的值,默认步长都是1,
也就是说:for ( item in 10 downTo 0)=for ( item in 10 downTo 0 temp 1)
4.while循环和do/while的使用:
Java和kotlin的是一样用法,可以参考java,
5.跳出多重循环break和continue与标记位@。
这两种的基本用法和java一样,但是kotlin多一个标记位,可以通过@ 来标记循环体的开始位置,直接跳转到该位置
var index: Int = 0 flag@ while (index < 10) { var j = 0 secend@ while (j < 10) { if (j == 5) { break@secend } print("index=${index},j=${j}\n") j++ } index++ }
在这里,我们定义了两个标记:flag和secend,在第二层嵌套while循环break到secend,也就是说如果j==5,跳出里面的循环,继续往下执行,如果break @flag,j==5,跳出整个循环体。这是break用法
continue也可以使用标记,但是请注意,continue使用标记可能会出现死循环,所以如果把上面的break换成continue,
var index: Int = 0 flag@ while (index < 10) { var j = 0 secend@ while (j < 10) { if (j == 5) { continue@secend } print("index=${index},j=${j}\n") j++ } index++ }
那么,当j=5时,由于j++在continue下面,continue跳转到secend标记位,这样j==5一直没变,导致进入死循环。所以在把continue与标记位结合,注意
6.字符串的有效判定
isNullOrEmpty:为空指针或者字符串长度为0返回true
isNullOrBlank:为空指针、字符串长度为0或者权威空格返回true
isEmpty:字符串长度为0
isBlank:字符串长度为0或者全为空格
isNotEmpty:字符串长度大于0
isNotBlank:字符串导航度大于0缺不全是空格
7.空对象的规避与使用
var a:string?=null
表示a可为null,即使你在使用直接返回是null ,而不会报空指针
包括方法参数也是如此fun test(txt:String?),表示txt可为null,否则ied会提示错误
即在参数后面加上?:a?.length返回null
7.1很多时候我们不想要null,想要默认值,可以通过"?:"来规避
(a?.length?:0)->如果a为null,那么返回的是null,这时,通过?:来达到三目运算符返回0
a?这种写法的好处是不会抛出空指针,但是会返回null
7.2 "!!"运算符,是变量从可控转向非可空,但是如果对象为null,需要自己去判断,否则会报空指针
var people:People?=null people=People() println(people.name?:"")//返回空 println(people.name)//返回null
8.==和equals的对比,“===”又是什么?
println("a"=="a") true println("a".equals("a")) true
Java中==是对象的空间地址比较,kotlin比较的是当前对象的值,属于结构对比,简称值的比较。
那么"==="是什么呢?
var p1:People= People() var p2:People=People() println(p1===p2) false println(p1!==p2) true println("a"==="a") true
可以看出===和java中的==是一致的,是对象地址对比,!==和java中!=是一个效果,都是针对地址控件的判定
9.对象的类型判断 is 和!is
println("a" is String) true println("a" !is String) false
10.函数的使用与定义
java :public void methodName(String name)或者public String methodName(String name)
这种是比较常见的使用,前面是无返回值,后一个是返回一个string
kotline: fun methodName(name:String)或者fun methodName(name:String):String
函数申明:fun ,函数名(参数),如果有返回值,在参数括号外新增“:返回类型”,:String=返回一个String
//无返回值
fun a(name:String){
printf(name)
}
//有返回值
fun add(txt:Int):Int{
var result=txt+10
return result
}
10.1方法继承
在Java中,如果继承一个类,实现该类的一个方法
@Override
public void log(String txt){
}
kotlin中,与java不一致,是小写override在fun前面
override fun log(txt:String){
}
10.2 类的继承
//父类
open class Base{ open fun log(log:String?){ } }
//子类
class MyBase: Base() { //方法的重写 override fun log(log: String?) { super.log(log) } }
父类在申明作用范围时,采用open,类似java public 。
继承直接用":",如果想使用父类的方法,该方法也必须修饰成open
10.3抽象类:
参考下方资料
10.4接口与接口的继承
参考下方资料
10.5形参默认值,
在函数中,我们经常会说形参与实参。形参默认值是很少听说,java中,形参不支持默认值,如果未传,默认传的就是null。但是kotlin与java还是有区别的
fun test(txt:String="你好"){
printf(txt)
}
如果调用了该方法,你即使不传值,默认也是调的通,打印"你好",Java就不行了。
调用有三种:
1.aa(txt = "hello") //打印:hello 2.aa("哈喽")//打印:哈喽 3.aa()//打印:你好
第一种属于命名参数,可以指定多个参数中一个参数的值,其他是默认
10.6可变参数:
在Java中,如果我们定义一个可变参数,可用"..."来修饰,String... list,定义一个list字符数组
在kotlin中,依旧支持这种行为,通过关键字vararg来形容
Java:
public void log(String... log){
}
kotlin:
fun log(vararg log:String){
}
10.7匿名函数
匿名函数类型和lambda表达式非常详解,不需要定义一个完整的函数,通过lambda表达式来完成。可以参考下方资料
10.8泛型函数
泛型在JAVA中,使用的是对象构造时已指定,不能通过方法来构造,但是kotlin,可以通过方法来构造
Java:
public class MyTest1<T> { public static void main(String[] args) { MyTest1<Integer> test1 = new MyTest1<Integer>(); System.out.println(test1.getLog(123)); } public T getLog(T name) { if (name instanceof Integer) { System.out.println("name is Int"); } return name; } }
kotlin:
fun <T> myLog(txt: String, name: T): T { return name; }
10.9内联函数
inline fun <reified T : Number> setTextValue(arry: Array<T>) { for (item in arry) { if (item is Int) { println("item is int value=${item}") } } }
格式:inline fun<reified T:参数>方法名(value:T)
T是内联泛型,
调用:
setTextValue<Int>(arry),指定泛型类型,通过方法名<T>(参数)
10.10简化函数
//下面是1到100求和
fun add(n: Int): Int { if (n <= 1) { return n } else { return n + add(n - 1) } } //简化函数求和 fun add1(n: Int): Int=if (n<=1) n else n+ add(n-1);
10.11尾递归函数
尾递归函数是指尾部值重复调用自身函数,在fun 关键字前加一个tailrec来修饰。
//如果是尾递归函数,编译器会利用循环替代递归,避免溢出(死循环)
tailrec fun cons(x:Double=1.0) :Double{ if (x==Math.abs(x)) return x else return cos(Math.abs(x)) }
10.12高阶函数
运行将表达式作为参数传进来,形成高阶,如下:
fun <T> maxLength(arry: Array<T>, grate: (T, T) -> Boolean): T? {
var max: T=arry[0]
for (item in arry) {
if (item == null || grate(item, max)) {
max = item;
}
}
return max;
}计算长度最大值,grate: (T, T) -> Boolean是高阶函数的参数,该写法属于lambda的匿名写法。
调用如下:
var list: Array<String>
list = arrayOf("lisi", "zhangshan", "wangwu", "jck")
var max=maxLength(list) { a, b -> a.length > b.length }
println("max=${max}")
函数后接表达式参数写法:{ a, b -> a.length > b.length }
{ a, b -> a.length > b.length }是lambda写法等同如下:
fun maxLengtj(a:T,b;t):Boolean{
var maxResult=if(a.length>b.length){
a
}else{
b
}
rreturn maxResukt
}
10.13扩展函数:
扩展函数是对函数自身的进行扩展,在java中,如果一个类提供了指定函数后,如不在原来类里进行扩展,该类将无法提供额外函数:
public void Log{
public void log(String log){
system.out.printf(log);
}
}
Log类只提供了一个方法,kotlin可以在原来类上进行扩展。
如果我们想对String这个函数新增一个方法,如下
fun 类名.方法名
fun String.hello(){
var value=toString() print("hello value=${value}")
}
这个时候我们就新增了一个hello方法,
调用如下:
var txt:String="nihao" txt.hllo()
备注:扩展函数内部可以通过this来引用自己。
10.14日期函数
格式:
1. yyyy=表示年份
2.MM=表示月份
3.dd:表示日期天
4.HH=表示24小时制
5.hh=表示12小时制
6.mm=表示分
7.ss=表示秒
8.sss-毫秒
如何使用:
//扩展函数
fun Date.newTime(): String { var time = SimpleDateFormat("HH:mm:ss:sss") return time.format(this) } //常见的使用 fun time() { var time = SimpleDateFormat("yyyy-MM-dd HH:mm:ss:sss") var result = time.format(Date()) println(result) }
调用如下:
time() println(Date().newTime())
10.15单利对象:
单利对象在Java用比较常见,kotlin也支持单利模式,通过object关键字来修饰类。
object DataUtil { var newTime: String = "" get() { var time=SimpleDateFormat("yyyy-MM-dd") return time.format(Date()) } }
利用对象get()方法重写,可以省去定义方法,也可以通过方法,效果一样
11.类的继承与构造
1.类在使用的使用,常见的就是构造器,继承,初始化
Java:
1.继承 ,通过extends来修饰,
public class V extends B
2.构造,参考方法的重载,即方法名相同,参数不同
kotlin:
继承:通过 “:”来修饰
class MyBase :BaseA(){ override fun log() { super.log() } }
基类需要通过open来修饰,该作用类似public,
open class BaseA { open fun log(){ println(javaClass.name) } }
构造器:
kotlin提供了一个默认的
init{
}
这个类,在构造器之前被执行
class MyBase constructor() { init { println("MyBASES") } constructor(aa: String) { } constructor(aa: String, bb: String) { println("MyBASES constructor=${aa}${bb}") } }
构造器可以在类的后面接入,或者方法体中新增,支持多构造。
2.内部构造器的继承
kotlin中,继承通过":"来标识的,构造器也支持,
class MyBase constructor(aa: String) { init { println("MyBASES") } constructor() : this("") { println("MyBASES1 constructor=") } constructor(aa: String, bb: String) : this("") { println("MyBASES1 constructor=") } }
如果你想调用其他构造器,通过:+this指向构造器,参数匹配即可
但是这里有个问题,如果构造器使用了this 指向,那么就需要其他构造器也要继承,否则会报错
Primary constructor call expected
上面的案例提供了三个构造器,而且只能方法体可以使用方法体内的或者类名默认构造器,类跟着构造器无法引用内部的。
3.类构造器的写法
class myBean(aa:String,bb:String){
}
或者
class MyBase constructor(aa: String) {
}
可以通过constructor来修饰,也可以省略
4.构造器的分类
kotlin的构造器分为主构造器和二级构造器,主构造器类名后面接的构造器,该构造器可以通过constructor来修饰,也可以直接省略该关键字。
二级构造器:除了主构造器,类的内部构造器都叫二级构造器,通过constructor来修饰,二级构造器可以引用主枸杞子,或者引用二级构造器,通过this,但是主构造器无法引用二级构造器。
主构造器没写constructor也叫默认构造器。
5.参数set和get修改
kotlin与Java不同,如果在定义一个可变参数,默认提供set和get方法,
class MyPeople { var name: String set(value) { println(value) } get() :String { return name } }
我们可以在set和get修改值,注意有一点:var name:String后面不能加";"号,否则该语句算结束了,不能再提供set和get方法了,
这里面只要调用name就会调用set,不能在set中引用name变量,否则会死循环。所以在set中,不要处理当前变量名,否则会互相调用,进入死循环。
12.伴生对象
kotlin取消了static静态修饰,采用了伴生对象,这是一个内部修饰,用 companion object来修饰
class MyPeople {
companion object NameTag { fun tag(name: String): String { if (name.startsWith("a")) { return "A"; } else if (name.startsWith("b")) { return "b" } else if (name.startsWith("c")) { return "c"; } else { return "d"; } } }
}
调用如下:
println(MyPeople.NameTag.tag("a")) println(MyPeople.tag("b"))
13.抽象类
Java中存在抽象类,abstract来修饰,抽象类只提供了抽象方法,不提供具体方法体,在kotlin中,同样也有抽象类这一修饰。也是通过abstract
abstract class Animation(kind: String = "") { var mkind = ""; init { mkind = kind; } abstract fun getName():String; fun log() { print(mkind) } }
class Kid(name: String = "") : Animation() { var mName = ""; init { mName = name; } override fun getName(): String { // TODO("Not yet implemented") return mName; } }
备注:如果参数已赋默认值,在调用时,可以不传值。
构造器值的使用:主构造器的值不可以直接使用,只能在
init{
}
//中引用,如果构造器有默认参数值,可以省略不传。
抽象类和抽象方法都是通过abstract来修饰,用法和Java一样原则
14.接口
kotlin也支持接口,但是接口不支持构造器,但是接口支持的东西比较杂,
interface KotlinInterface { fun log() { } abstract fun getName():String open fun setValue(name:String="") }
class TestInterface : KotlinInterface { override fun getName(): String { // TODO("Not yet implemented") return "hello" } override fun setValue(name: String) { // TODO("Not yet implemented") } }
14.1支持方法实现体,并可以,Java的接口是不支持方法的实现体,支持抽象方法,支持方法不实现方法体。
所以kotlin的接口实现丰富,和Java的有所区别。
14.2接口作为回调
如果接口作为回调,就不能设置抽象方法,否则提示报错。以下是接口作为参数回调使用
interface MyClickListener { fun log() { } // abstract fun getName():String open fun setValue(name:String="") }
class TestMyClick { var clickListener: MyClickListener? = null fun setClick(click: MyClickListener) { clickListener = click } fun setName(name: String) { clickListener?.setValue(name) } } fun main() { var item=TestMyClick() item.setClick(object :MyClickListener{ override fun setValue(name: String) { TODO("Not yet implemented") } }) }
15.嵌套类
和Java一样,kotlin也支持内部类
Java:
publi class A{
public class B{
}
}
kotlin:
class TestInllClass { class Child { var name = "" } } fun main() { var item = TestInllClass.Child() item.name = "你好" print(item.name) }
嵌套类和内部类只差一个修饰inner
1.内部类:inner
class TestInllClass { inner class Child { var name = "" } }
inner关键字
修饰表示内部类
嵌套类属于静态类和外部类没任何关系
内部类使用this,访问外部类的变
inner class Child(kids: String = "child") { var name = "" var tag = "child" fun getname(): String { //外部对象 return "${this@TestInllClass.tag}" } fun getOun(): String { //自己 return "${this.tag}" } }
16.枚举
枚举在Java中支持,在kotlin也支持,都是通过enum来修饰,但是Java和kotlin的写法有点不同如下
Java
public enum People { One,Two,Three,Four }
kotlin
enum class Peoples { One,Two,Three,Four }
kotlin支持构造器写法,也就是给不同的item赋不同值
enum class Peoples(name:String="默认值") { One("1"),Two("2"),Three("3"),Four }
17.密封类
密封类的用法和枚举差不多,更像Java中的枚举用法,通过sealed关键字类修饰
sealed class MifengClass{ class One(var name: String) : MifengClass() class Two(var name: String) : MifengClass() class Three(var name: String) : MifengClass() }
fun main() { print(MifengClass.One("12").name) }
18.数据类
数据类是对java bean的一个新的封装,我们在Java中,经常对数据解析都需要定义一个数据bean,然后在解释,在kotlin中,只需要把这个类申明为数据类,在主构造器申明变量,系统会自动为他们设置set和get方法
data class MyInfo(var name: String, var age: Int, var address: String)
我们定义一个基本的人的信息数据
使用如下:
fun main() { var people = MyInfo("zhangshan", 20, "jiangsu nanjing") print(people.info()) } //给Myinfo新增一个方法,以上的demo已介绍过该种写法 fun MyInfo.info(): String { return "name={$name},age={$age},address={$address}" }
备注:
1.数据类至少有一个参数,不存在空属性。即不存在一个对象没有属性。
2.构造器参数与类构造器不同,需要通过var或者val修饰。
3.支持copy方法,支持一模一样的数据。
17.类型转换 :as
Java中类型转换,只需要强转(TypeClass)item即可。kotlin也支持转换,需要通过as
(a asPeople):转出来就是People的对象
Android:Kotlin库Anko的使用与语法使用
Anko库:简单描述,结合语法,详细会出一篇文字
布局引入,直接使用:
1.在Android中,布局引入后,对控件的使用需要通过findViewById或者new一个对象来使用,但是kotlin提供一个anko库,可以直接把当前页中的布局注入并直接使用
kotlinx.android.synthetic.main.
import kotlinx.android.synthetic.main.layout_kotline_one.*; 格式:import kotlinx.android.synthetic.main.layoutname.*;
layoutname是当前需要引入的layout文件名,后面的*是指当前布局下所有view 的id,如果你只想引入某一个控件,把*换成对应的view 的id name即可,*代表全部注入
如果使用控件:
例如:
2.方法的简洁:
正常我们设置一个监听:
btn_one.setOnClickListener( object : View.OnClickListener{ override fun onClick(v: View?) { //TODO("Not yet implemented") } })
anko库,直接如下:
btn_one.setOnClickListener { btn_one.text="变化" }
2.1对象字段赋值
//原生Android
btn_one.setText("sssss")
//kotlin直接引用字段
btn_one.text="变化"
2.2监听支持返回值,在设置监听,会提供两种,一种是anko库的写法,还有一种是kotlin的对象写法
btn_one.setOnLongClickListener(object : View.OnLongClickListener { override fun onLongClick(v: View?): Boolean { //TODO("Not yet implemented") showToast("asd");true } })
//这种写法也是延续java 的lambda表达式
toast(String msg) 或者toast(int resid)是kotlin自动支持的。
toast显示默认有两种时间间隔,toast提供是短时间,长时间使用
longToast("123")
1.接口设置:
匿名函数
btn_one?.setOnClickListener { v -> toast("你好") } btn_one?.setOnClickListener { object:View.OnClickListener{ override fun onClick(v: View?) { // TODO("Not yet implemented") } } }