在Android中使用Kotlin

目录

    • 1. 环境要求
    • 2. 配置 Kotlin
    • 3. Java文件转换为Kotlin
    • 4. 一个JavaBean类的Kotlin版本
    • 5. data关键字
    • 6. for循环
    • 7. 字符串内插
    • 8. Kotlin Android 扩展视图绑定
    • 9. 使用 lambda 表达式
    • 10. Kotlin表达三元运算符
    • 11. 使用Kotlin扩展函数
        • 11.1 排序
        • 11.2 使用Kotlin标准库扩展替换 for 循环

1. 环境要求

  • 使用 Android Studio 3.0 或更高版本
  • 已安装Kotlin插件

2. 配置 Kotlin

在 Android Studio 中,选择 Tools > Kotlin > Configure Kotlin in Project。如果出现一个标题为 Choose Configurator 的窗口,请选择 Android with Gradle 并确保选择 All modules,然后点击 OK。
Android Studio 将在应用级别和项目级别的 build.gradle 文件中添加所需的依赖项。

3. Java文件转换为Kotlin

选择 Code > Convert Java File to Kotlin File

4. 一个JavaBean类的Kotlin版本

Java版本

class Contact {

    private String firstName;
    private String lastName;
    private String email;


    Contact(String firstName, String lastName, String email) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.email = email;
    }

    String getFirstName() {
        return firstName;
    }

    String getLastName() {
        return lastName;
    }

    String getEmail() {
        return email;
    }

    void setEmail(String email) {
        this.email = email;
    }
}

Kotlin版本

internal class Contact(val firstName: String, val lastName: String, var email: String?)
  • 声明一个名为 Contact 的类。
  • 为该类声明三个属性:为名字和姓氏声明两个只读字段,为电子邮件地址声明一个可变变量。
  • firstName 和 lastName 属性保证绝不会是 null,因为它们的类型为 String。
  • 电子邮件字段可为 null,因为它的类型为 String?

  1. Kotlin 中使用 var 关键字声明为可变,或者使用 val关键字声明为不可变。 可变属性(使用 var) 声明)可以分配任意次数,而不可变变量(使用 val) 声明)只能分配一次。

  2. Kotlin属性类型在属性名称和冒号之后:val firstName: String。

  3. 主构造函数是类声明的一部分:它紧跟着类名称,位于括号中。可以在类的正文中使用 constructor 关键字提供其他构造函数。属性在主构造函数中声明。

  4. 默认情况下,Kotlin 中的属性类型不得为 null。如果属性可以保留 null 值,请使用 ?语法通过可为 null 的类型对它进行声明。例如,String? 可为 null,但 String 不可以。

5. data关键字

data 关键字可以告知 Kotlin 编译器类用于存储数据,这将生成大量有用函数。
例如:揭示对象内容的 toString() 实现、copy() 函数,以及用于将对象解构成字段的分量函数。

internal data class Contact
(val firstName: String, val lastName: String, var email: String?)

上述代码,加了data关键字后,在打印Contact类的时,会调用toString方法,并打印出里面的各属性的值。
如果不加的话,则只是打印对象的地址。

Kotlin 提示:

  1. 语句结尾的分号在 Kotlin 中为可选。
  2. 函数通过 fun 关键字声明。
  3. 利用 lateinit 关键字,您可以推迟非 null变量的初始化。
  4. 如果属性类型不模糊,则可以将其忽略。例如
    private var mEntryValid:Boolean = false忽略类型变为:private var mEntryValid = false
  5. 您可以使用 !!运算符访问可为 null 类型的字段和函数。这可以告知编译器您知道引用在调用时不会是 null。请慎用此运算符,因为它可能会导致 NullPointerException。

6. for循环

第一种..左闭右闭

for (i in 0..contactsJson.length() - 1)

第二种until左闭右开

for (i in 0 until contactsJson.length())

7. 字符串内插

val fullName = "$firstName $lastName"

引用了firstName,lastName变量的值,拼接后赋值给fullName变量。

8. Kotlin Android 扩展视图绑定

不用再findViewById啦~

  1. 在您的应用级 build.gradle 文件中应用 Kotlin Android 扩展插件以使用 Kotlin 视图绑定。
    具体操作:在 应用级 build.gradle 文件的开头添加代码apply plugin: 'kotlin-android-extensions'
  2. 布局中将任何控件都可以直接使用了,并且使用它的变量名就是控件的ID。
  3. 引用属于另一个扩充视图(例如 ViewHolder 或对话框的根视图)子项的视图。在这种情况下,使用它的时候语法为 .id

9. 使用 lambda 表达式

Kotlin 提供对 lambda 的支持,lambda 是未声明但会立即以表达式形式传递的函数。它们具有以下语法:

  • lambda 表达式始终由花括号 { } 包围。
  • 箭头 (->) 将函数参数和函数定义分隔。
  • 函数的参数(如果存在)在 ->之前声明。如果可以推断出来,则可以忽略参数类型。
  • 函数的正文在 -> 后定义。
{ x: Int, y: Int -> x + y }

创建一个不可变变量,该变量存储名为 notEmpty 的 lambda 表达式。该 lambda 表达式将 TextView 用作参数(EditText 继承自 TextView)并返回一个布尔值

val notEmpty: (TextView) -> Boolean

使用 Kotlin isNotEmpty() 函数向 notEmpty 分配一个 lambda 表达式,它会在 TextView 的 text 属性不为空时返回 true:

val notEmpty: (TextView) -> Boolean = { textView -> textView.text.isNotEmpty() }

如果 lambda 表达式只有一个参数,则可以忽略并替换为 it 关键字。移除 textView 参数并在 lambda 正文中将其引用替换为 it:

val notEmpty: (TextView) -> Boolean = { it.text.isNotEmpty() }

Kotlin 提示:

  1. 如果 lambda 表达式只有一个参数,则可以使用 it 关键字推断。
  2. Kotlin 没有三元运算符,而是使用 if/else 语句替代。

10. Kotlin表达三元运算符

Java版的三元运算符

result = isValidate?true:false

Kotlin版,使用if/else

retsult = if (isValidate) true else false

11. 使用Kotlin扩展函数

Kotlin 语言的一个主要特性是扩展,即向任何外部类(您未创建的类)添加功能的能力。这有助于避免"实用程序"类,这种类会封装您无法修改的导入 Java 或 Android 框架类。例如,如果您想要向 ArrayList 添加一个函数来提取只有整型的任何字符串,则可以向 ArrayList 添加一个扩展函数,这样就不用创建任何子类。

标准的 Kotlin 库包含大量常用 Java 类的扩展。

11.1 排序

Kotlin 标准库包含可变列表(包括 ArrayList)的 sortBy() 扩展函数,此函数使用"选择器"函数作为参数。这是一个高阶函数示例,高阶函数将另一个参数作为参数。此传入函数的作用是为任意对象列表定义自然排序顺序。
sortBy() 函数将循环访问调用它的每一个列表项,并在列表项上执行选择器函数来获取它了解如何排序的值。选择器函数通常会返回实现 Comparable 接口的对象的一个字段,例如 String 或 Int。

在 mContacts 列表上调用 sortBy() 函数。传入一个使用 Contact 对象作为参数的 lambda 表达式并返回其名字属性。由于联系人是唯一的参数,可以将它作为 it 引用:

mContacts.sortBy { it.firstName }

11.2 使用Kotlin标准库扩展替换 for 循环

Kotlin 标准库将许多扩展函数添加到集合(例如 Lists、Sets 和 Maps)中,以便在不同的集合之间进行转换。

将光标放在 for 关键字上。按橙色的灯泡显示快速修复菜单,并选择 Replace with mapTo(){}

Java版的for循环

 private ArrayList<Contact> loadContacts() {
        Set<String> contactSet = mPrefs.getStringSet
                (CONTACT_KEY, new HashSet<String>());
        ArrayList<Contact> contacts = new ArrayList<>();
        for (String contactString : contactSet) {
            contacts.add(new Gson().fromJson(contactString, Contact.class));
        }
        return contacts;
    }

更改后的Kotlin版本,使用mapTo函数

private fun loadContacts(): ArrayList<Contact> {
    val contactSet = mPrefs.getStringSet(CONTACT_KEY, HashSet())
    return contactSet.mapTo(ArrayList<Contact>()) { 
        Gson().fromJson(it, Contact::class.java) 
    }
}

Android Studio 会将 for 循环改成 mapTo(){} 函数,这种高阶函数采用两个参数:要将接收器参数(您正在扩展的类)转换成的集合,以及用于指定如何将集合项转换成列表项的 lambda 表达式。
注意 lambda 中的 it 表示法,它表示单个传入参数(列表中的项)。

另一个for循环的改法,使用map函数

Java版的代码

private void saveContacts() {
        SharedPreferences.Editor editor = mPrefs.edit();
        editor.clear();
        HashSet<String> contactSet = new HashSet<>();
        for (Contact contact : mContacts) {
            contactSet.add(new Gson().toJson(contact));
        }
        editor.putStringSet(CONTACT_KEY, contactSet);
        editor.apply();
    }

更改后的Kotlin版本,使用map函数

 private fun saveContacts() {
        val editor = mPrefs.edit()
        editor.clear()
        val contactSet = mContacts.map { Gson().toJson(it) }.toSet()
        editor.putStringSet(CONTACT_KEY, contactSet)
        editor.apply()
    }

同样,Android Studio 会将循环替换为扩展函数:这一次为 map{},它可以在列表中的每一个项上执行传入函数(使用 GSON 将其转换成字符串),然后使用 toSet() 扩展函数将结果转换成集合

Kotlin 提示:

  1. Kotlin 标准库附带大量的扩展函数,这些函数可以向现有的 Java 数据结构添加功能。
  2. 这些扩展通常是高阶函数,它们将其他函数用作参数(通常以 lambda 表达式形式传入)。
    sortBy() 扩展函数可以扩展许多 Java 列表类,以便按照传入的 lambda 表达式对这些类进行排序,lambda 表达式将列表项用作参数并返回一个实现 Comparable 接口的对象,从而定义列表的自然排序顺序。
  3. mapTo() 和 map() 函数也是可以扩展 Java 列表的高阶函数。传入的 lambda 表达式作用于列表中的每一个项。

参考 https://github.com/googlecodelabs/android-using-kotlin

你可能感兴趣的:(android开发学习)