最近在学习kotlin语法,有一本书《kotlin for Android developers》对kotlin语法有很详细的讲解,但是我决定写一篇快速在Android开发中感受Kotlin奇妙的文章。
首先创建一个基本的demo
在plugins里面添加kotlin插件,在build.gradle里面加入下面这几个配置
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'
dependencies {
"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
}
把activity页面转成kotlin页面,打开文件,选择code -> convert file to kotlin file ,然后就会把java代码转成kotlin代码了。
看一下demo的基本代码和运行结果:
-
activity代码
-
xml文件
-
demo效果
kotlin与java语法对比
View Binding
看上面的demo代码我们发现了kotlin的一个特别方便的地方,没有findViewById() 这个方法了。对于Android开发人员来说,findViewById() 这个方法真的是太熟悉了,因为太熟悉所以也知道这个方法带来的问题也很让人头痛,尽管存在一系列的开源库能够为这个问题带来解决方案,但是和kotlin一对比真的还是差太多了。
现在 Kotlin 安卓扩展插件能够提供与这些开源库功能相同的体验,只需要在build.gradle里面启用 Gradle 安卓扩展插件就可以了
apply plugin: 'kotlin-android-extensions'
就是这个东西,其他的不需要添加任何额外代码。
使用的时候我们直接用View的id就可以去使用View的基本属性。系统会自动给我们导入
import kotlinx.android.synthetic.main.<布局名>.*
当前demo的布局名是activity_kotlin,所以导入的是
import kotlinx.android.synthetic.main.activity_kotlin.*
之后就可以非常简单快捷的设置View的属性了,比如:
text_view.text = "hello world";
text_view.visibility= View.GONE;
函数定义
- 无返回值的函数(类似Java中的void)
fun log(a:Int,b:Int){
Log.d("log",a);
}
// 等同于是返回 Unit类型,则可以省略
fun log(a:Int,b:Int):Unit{
Log.d("log",a);
}
- 有返回值的函数
//参数是Int类型,返回值是Int类型
fun add(a:Int,b:Int):Int{
return a+b
}
//理解为简写吧,由系统自动判断返回类型
fun add(a:Int,b:Int)=a+b
- kotlin中的构造方法和函数参数
从上面可以看出,kotlin中我们可以先写参数名字再定义它的类型,所以我们可以给参数指定一个默认值使这个参数变得可选,比如:
fun toast(message:String,length:Int = Toast.LENGTH_SHORT){
Toast.makeText(this,message,length).show();
}
第二个参数我们是给了一个默认值的,所以第二个参数就可以不传,所以我们调用的时候可以有两种调用方法:
toast("hello World",Toast.LENGTH_LONG);
toast("hello world");
这样一个函数就能实现java里面的重载函数,与下面的java代码是一样的,用起来还是非常方便的:
public void toast(String message){
Toast.makeText(this,message,Toast.LENGTH_SHORT).show();
}
public void toast(String message,int length){
Toast.makeText(this,message,length).show();
}
当然还有静态函数,在Kotlin里边被叫做了:伴生对象,至于这个半生对象的名词解释呢,要了解的人直接去查吧,我们直接看代码:
class function {
companion object {
fun delete(){
Log.d("function","delete");
}
}
}
//调用呢就是下面这样
function.delete();
这只是kotlin函数的最基本的一些用法,还有许多实现细节可以去参考书籍。总的来说基本的一些用法理解上还是比较简单的,给人的感觉也是很干净的代码。
kotlin in Adapter
Android 中用的最多的列表控件的Adapter用法,在kotlin中是怎样的呢,先看代码
@Suppress("UNUSED_EXPRESSION")
class TestAdapter(var items: List) : RecyclerView.Adapter() {
override fun getItemCount(): Int {
return items.size;
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
return ViewHolder(TextView(parent.context));
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.textView.text=items[position];
}
class ViewHolder(var textView: TextView) : RecyclerView.ViewHolder(textView)
}
在最开始声明这个class的时候,我们直接在TestAdapter的主构造方法中声明了一个var的变量。这种写法就类似于Java中的:
class TestAdapter {
public List items;
public TestAdapter(List data){
this.items = data;
}
}
从上面我们可以看出kotlin的类的声明方式,在声明类的时候直接在后面加入需要的参数,如果这个类不需要参数传入,就可以不要();
在kotlin的Adapter中,ViewHolder 也变的很简单了
class ViewHolder(var textView: TextView) : RecyclerView.ViewHolder(textView)
看一下java代码:
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView textView;
public viewHolder(TextView textView){
super(textView);
this.textView = textView;
}
}
这个就是把主构造方View,传给RecyclerView.ViewHolder()构造方法中,和我们的Java代码一样的,就是刚开始看的时候理解上有点难而已。
但是我在写demo的时候就发现了一些注意事项,在声明类的时候传入的参数可以用var定义,也可以不用var定义,但是这两个有很大的区别。
用var定义的参数,可以在类中的所有方法里面直接调用,类似于java中的全局变量,不用var定义的参数,就只能在构造方法体里面用,类似于java的局部变量,
- 当我们不用var定义参数时,使用这个参数时会找不到报错,如下
- 用var定义时是可以直接使用的。
那我们不用var定义参数,这个参数我们要使用怎么办呢,看代码:
class Name(name: String) {
var myName: String ? = null;
init {
this.myName = name;
}
fun yourName(): String ? {
return myName;
}
}
就是这样我们像java里面一样声明一个全局变量,在init块里把传入的name变量赋值给我们定义的myName就可以了。init块就是kotlin中类的构造函数的函数体,构造函数中的代码处理都放在init块中实现。
上面有一行 var myName: String ? = null; 这个代码,这个涉及到了kotlin中的null安全,据说可以完美的避免NullPointerException,具体的还没有学习,就先不说了。
小结
有java语法的基础,理解kotlin的语法还是比较容易的。但是任何一门语言肯定不只是简单的理解,在使用中才能发现其精髓。目前我也只是结合Android开发中常用的东西去粗略的学了一些kotlin的基本的语法。
参考书籍
《kotlin for android developers》