目錄
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?
Kotlin 中使用 var 關鍵字聲明爲可變,或者使用 val關鍵字聲明爲不可變。 可變屬性(使用 var) 聲明)可以分配任意次數,而不可變變量(使用 val) 聲明)只能分配一次。
Kotlin屬性類型在屬性名稱和冒號之後:val firstName: String。
主構造函數是類聲明的一部分:它緊跟着類名稱,位於括號中。可以在類的正文中使用 constructor 關鍵字提供其他構造函數。屬性在主構造函數中聲明。
默認情況下,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 提示:
- 語句結尾的分號在 Kotlin 中爲可選。
- 函數通過 fun 關鍵字聲明。
- 利用 lateinit 關鍵字,您可以推遲非 null變量的初始化。
- 如果屬性類型不模糊,則可以將其忽略。例如
private var mEntryValid:Boolean = false
忽略類型變爲:private var mEntryValid = false
- 您可以使用 !!運算符訪問可爲 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啦~
- 在您的應用級 build.gradle 文件中應用 Kotlin Android 擴展插件以使用 Kotlin 視圖綁定。
具體操作:在 應用級 build.gradle 文件的開頭添加代碼apply plugin: 'kotlin-android-extensions'
- 佈局中將任何控件都可以直接使用了,並且使用它的變量名就是控件的ID。
- 引用屬於另一個擴充視圖(例如 ViewHolder 或對話框的根視圖)子項的視圖。在這種情況下,使用它的時候語法爲
<rootview>.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 提示:
- 如果 lambda 表達式只有一個參數,則可以使用 it 關鍵字推斷。
- 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 提示:
- Kotlin 標準庫附帶大量的擴展函數,這些函數可以向現有的 Java 數據結構添加功能。
- 這些擴展通常是高階函數,它們將其他函數用作參數(通常以 lambda 表達式形式傳入)。
sortBy() 擴展函數可以擴展許多 Java 列表類,以便按照傳入的 lambda 表達式對這些類進行排序,lambda 表達式將列表項用作參數並返回一個實現 Comparable 接口的對象,從而定義列表的自然排序順序。- mapTo() 和 map() 函數也是可以擴展 Java 列表的高階函數。傳入的 lambda 表達式作用於列表中的每一個項。
參考 https://github.com/googlecodelabs/android-using-kotlin