41

Kotlin for Android

 5 years ago
source link: http://tech.dianwoda.com/2018/12/13/kotlin-for-android/?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

最近在学习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代码 MbeEzqM.png!web

  • xml文件 aiymemI.png!web

  • demo效果 v22UBbJ.jpg!web

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;

虽然现在我们骑手项目里面用的开源库简化findViewById(),但是对于一个页面布局有很多View的来说,声明布局View的名称还是非常繁琐的。比如下图这样的还只是所有的1/3,如果使用kotlin这些声明都可以去掉,直接用View的id就可以去使用了。

MBjI3uy.png!web

函数定义

  • 无返回值的函数(类似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<String>) : RecyclerView.Adapter<TestAdapter.ViewHolder>() {  
    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<String> items;

    public TestAdapter(List<String> 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定义参数时,使用这个参数时会找不到报错,如下

BNZ3Yfb.png!web

  • 用var定义时是可以直接使用的。

M3U7vya.png!web

那我们不用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也是谷歌官方推荐的Android开发语言了,虽然我们的项目现在还没有用到,但是我们也可以在这之后慢慢的加入kotlin的大军。有学习kotlin语法的小伙伴也可以一起讨论交流。

参考书籍

《kotlin for android developers》


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK