距離kotlin成為Android一級開發語言已經一年了,這節将從零開始,實作kotlin的幾個小知識點。
以下操作是在AndroidStudio3.0.1下完成的,如果是3.0以下版本的AndroidStudio,需要
安裝好kotlin插件 才能使用Kotlin進行開發
Kotlin教程推薦 官網文檔 , 黑馬教程 《Kotlin for android developers》中文版翻譯
相關代碼已經上傳到Github的 KotlinPractice檔案夾 下了
建立項目:
在建立項目中勾選kolin支援後直接下一步即可

勾選kotlin支援
建立完項目後我們發現主類已經是使用了kotlin代碼了,我們去project的build.gradle目錄下可以看到
ext.kotlin_version = '1.1.51' kotlin //版本号
dependencies {
classpath 'com.android.tools.build:gradle:3.0.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"//依賴
}
以及module下build.gradle的:
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
實際上這就是我們剛才勾選kotlin後給我們自動生成的,如果我們想要在現有Java代碼項目中使用kotlin,那麼我們就需要手動的去添加這些依賴,或者使用友善的 java代碼轉kotlin 來進行配置,我們看到MainActivity預設已經是kotlin類了
/**
* : AppCompatActivity()
* :類名,表示繼承于AppCompatActivity類
*/
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
}
為TextView控件指派:
我們在布局從添加一個TextView,id命名為text_01
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.administrator.kotlin.MainActivity">
<TextView
android:id="@+id/txt_01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="測試文本" />
</LinearLayout>
回到Activity,在activity的導包中添加這一行
import kotlinx.android.synthetic.main.activity_main.*
它的作用現在隻要知道添加了這一行後我們就不需要再findViewById就可以了,activity_main的意思是Activity布局的包名。
import kotlinx.android.synthetic.main.activity_main.*
/**
* : AppCompatActivity() :類名,表示繼承與什麼類
*/
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// 為TextView設定值,koltin的語句後面是不需要;的,但是如果你加上也不會報錯的
txt_01.setText("你好,世界")
}
}
運作程式,确實和我們想要的是一樣的
設定按鈕點選事件
我們再為布局添加3個button按鈕
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.example.administrator.kotlin.MainActivity">
<TextView
android:id="@+id/txt_01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="測試文本" />
<Button
android:id="@+id/btn_01"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="按鈕1"
/>
<Button
android:id="@+id/btn_02"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="按鈕2"
/>
<Button
android:id="@+id/btn_03"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="按鈕3"
/>
</LinearLayout>
回到Activity,讓MainActivity類繼承于View.OnClickListener接口,我們可以看到koltin繼承接口是使用,号進行的,如果我們想要繼承多個接口,隻需要使用多個,分隔開來就行了
/**
* : AppCompatActivity() :類名,表示繼承于什麼類
* ,View.OnClickListener, View.OnLongClickListener 表示繼承于 View.OnClickListener 點選事件接口, View.OnLongClickListener 長按事件接口
*/
class MainActivity : AppCompatActivity(), View.OnClickListener, View.OnLongClickListener {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// 為TextView設定值,koltin的語句後面是不需要;的,但是如果你加上也不會報錯的
txt_01.setText("你好,世界")
}
/**
* 重寫OnClickListener接口的onClick方法
*/
override fun onClick(p0: View?) {
}
/**
* 重寫OnLongClickListener接口的onLongClick方法
*/
override fun onLongClick(p0: View?): Boolean {
return false
}
}
然後就是我們熟悉的在點選事件裡面使用switch找到對應控件的id了,隻是在kotlin裡面是使用when
/**
* 重寫OnClickListener接口的onClick方法
*/
override fun onClick(p0: View?) {
when (p0!!.id) {
R.id.btn_01 -> {
Toast.makeText(this, "按鈕1", Toast.LENGTH_LONG).show()
}
R.id.btn_02 -> {
Toast.makeText(this, "按鈕2", Toast.LENGTH_LONG).show()
}
R.id.btn_03 -> {
Toast.makeText(this, "按鈕3", Toast.LENGTH_LONG).show()
}
}
}
最後要注意,雖然我們通過import kotlinx.android.synthetic.main.activity_main.*使得不需要寫控件的fndId,但是我們仍然是要寫setOnClickListener(this)控件點選回調監聽的
完整代碼:
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import android.widget.Toast
import kotlinx.android.synthetic.main.activity_main.*
/**
* : AppCompatActivity() :類名,表示繼承與什麼類
*/
class MainActivity : AppCompatActivity(), View.OnClickListener, View.OnLongClickListener {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// 為TextView設定值,koltin的語句後面是不需要;的,但是如果你加上也不會報錯的
txt_01.setText("你好,世界")
// 設定控件的回調監聽
init()
}
/**
* 設定控件的回調監聽
*/
private fun init() {
btn_01.setOnClickListener(this)
btn_02.setOnClickListener(this)
btn_03.setOnClickListener(this)
}
/**
* 重寫OnClickListener接口的onClick方法
*/
override fun onClick(p0: View?) {
when (p0!!.id) {
R.id.btn_01 -> {
Toast.makeText(this, "按鈕1", Toast.LENGTH_LONG).show()
}
R.id.btn_02 -> {
Toast.makeText(this, "按鈕2", Toast.LENGTH_LONG).show()
}
R.id.btn_03 -> {
Toast.makeText(this, "按鈕3", Toast.LENGTH_LONG).show()
}
}
}
/**
* 重寫OnLongClickListener接口的onLongClick方法
*/
override fun onLongClick(p0: View?): Boolean {
return false
}
}
運作程式點選按鈕後,出現了我們想要的吐司
實作網絡請求
開始之前我們先在module下配置anko依賴,這是為了等下線程排程用的
module:
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation"org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
implementation 'com.android.support:appcompat-v7:26.1.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.1'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
// kotlin插件anko
implementation "org.jetbrains.anko:anko-common:0.10.4"
}
然後實作我們的network()請求網絡方法,最後不要忘了在AndroidManifest.xml下添加網絡權限
<uses-permission android:name="android.permission.INTERNET" />
/**
* 重寫OnClickListener接口的onClick方法
*/
override fun onClick(p0: View?) {
when (p0!!.id) {
R.id.btn_01 -> {
// 隻進行網絡請求
network();
}
R.id.btn_02 -> {
// 進行網路請求,并且進行json資料解析
Toast.makeText(this, "按鈕2", Toast.LENGTH_LONG).show()
}
R.id.btn_03 -> {
Toast.makeText(this, "按鈕3", Toast.LENGTH_LONG).show()
}
}
}
/**
* 網絡請求
*/
private fun network() {
// 聲明要請求的網址,在kotlin中,var能聲明一切類型,而後面的:String其實是可以不加的
var string: String = "http://www.wanandroid.com/tools/mockapi/2872/k1"
// 作用類似java在子線程中進行網絡請求,但是async在kotlin中叫做協程
async() {
val fore = URL(string).readText()
Log.d("tonjies", fore)
}
}
觀察日志,我們可以看到确實已經擷取了Json資料
這裡寫圖檔描述
Json資料解析
接下來我們進行json資料的解析,首先添加gson解析依賴
// goso解析
compile "com.google.code.gson:gson:2.4"
我們建立bean實體類包,在包下建立解析實體類Student,我們不需要像Java那樣去生成get和set對象,因為這kotlin已經幫我們生成好啦!
/**
* Created by 舍長 on 2018/4/28.
* 描述: 資料請求實體類
*/
class Student {
var name:String?=null
var age:String?=null
}
在按鈕2的點選事件裡面寫一個gson方法,在gson方法裡将網絡請求到的資料轉換成實體類,并且回到UI線程,顯示在文字控件上
/**
* 重寫OnClickListener接口的onClick方法
*/
override fun onClick(p0: View?) {
when (p0!!.id) {
R.id.btn_01 -> {
// 隻進行網絡請求
network();
}
R.id.btn_02 -> {
// 進行網路請求,并且進行json資料解析
Toast.makeText(this, "按鈕2", Toast.LENGTH_LONG).show()
gson();
}
R.id.btn_03 -> {
Toast.makeText(this, "按鈕3", Toast.LENGTH_LONG).show()
}
}
}
/**
* 網絡請求并使用gson解析資料
*/
private fun gson() {
// 聲明要請求的網址,在kotlin中,var能聲明一切類型,而後面的:String其實是可以不加的
var string: String = "http://www.wanandroid.com/tools/mockapi/2872/student"
// 作用類似java在子線程中進行網絡請求,但是async在kotlin中叫做協程
async() {
val fore = URL(string).readText()
var fromJson: Student = Gson().fromJson(fore, Student::class.java)
// 回到UI線程中去更新資料,這裡的${屬性名}是字元串模闆,作用于Java的+屬性名+相同
uiThread {
txt_01.setText("學生的名字是${fromJson.name},年齡是${fromJson.age}")
}
}
}
運作程式,點選按鈕二,可以看到文字确實變成了我們想要的json資料:學習的名字是tonjies,年齡是18
這一小節的完整代碼:
布局檔案activity_main:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.example.administrator.kotlin.MainActivity">
<TextView
android:id="@+id/txt_01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="測試文本" />
<Button
android:id="@+id/btn_01"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="按鈕1"
/>
<Button
android:id="@+id/btn_02"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="按鈕2"
/>
<Button
android:id="@+id/btn_03"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="按鈕3"
/>
</LinearLayout>
MainActivity
package com.example.administrator.kotlin
import android.icu.lang.UCharacter.GraphemeClusterBreak.L
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.view.View
import android.widget.Toast
import com.example.administrator.kotlin.R.id.async
import com.example.administrator.kotlin.bean.Student
import com.google.gson.Gson
import kotlinx.android.synthetic.main.activity_main.*
import java.net.URL
import org.jetbrains.anko.custom.async
import org.jetbrains.anko.uiThread
/**
* : AppCompatActivity() :類名,表示繼承與什麼類
*/
class MainActivity : AppCompatActivity(), View.OnClickListener, View.OnLongClickListener {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// 為TextView設定值,koltin的語句後面是不需要;的,但是如果你加上也不會報錯的
txt_01.setText("你好,世界")
// 設定控件的回調監聽
init()
}
/**
* 設定控件的回調監聽
*/
private fun init() {
btn_01.setOnClickListener(this)
btn_02.setOnClickListener(this)
btn_03.setOnClickListener(this)
}
/**
* 重寫OnClickListener接口的onClick方法
*/
override fun onClick(p0: View?) {
when (p0!!.id) {
R.id.btn_01 -> {
// 隻進行網絡請求
network();
}
R.id.btn_02 -> {
// 進行網路請求,并且進行json資料解析
Toast.makeText(this, "按鈕2", Toast.LENGTH_LONG).show()
gson();
}
R.id.btn_03 -> {
Toast.makeText(this, "按鈕3", Toast.LENGTH_LONG).show()
}
}
}
/**
* 網絡請求并使用gson解析資料
*/
private fun gson() {
// 聲明要請求的網址,在kotlin中,var能聲明一切類型,而後面的:String其實是可以不加的
var string: String = "http://www.wanandroid.com/tools/mockapi/2872/student"
// 作用類似java在子線程中進行網絡請求,但是async在kotlin中叫做協程
async() {
val fore = URL(string).readText()
var fromJson: Student = Gson().fromJson(fore, Student::class.java)
// 回到UI線程中去更新資料,這裡的${屬性名}是字元串模闆,作用于Java的+屬性名+相同
uiThread {
txt_01.setText("學生的名字是${fromJson.name},年齡是${fromJson.age}")
}
}
}
/**
* 網絡請求
*/
private fun network() {
// 聲明要請求的網址,在kotlin中,var能聲明一切類型,而後面的:String其實是可以不加的
var string: String = "http://www.wanandroid.com/tools/mockapi/2872/student"
// 作用類似java在子線程中進行網絡請求,但是async在kotlin中叫做協程
async() {
val fore = URL(string).readText()
Log.d("tonjies", fore)
}
}
/**
* 重寫OnLongClickListener接口的onLongClick方法
*/
override fun onLongClick(p0: View?): Boolean {
return false
}
}
好了,這一小節就到這裡啦!在學習的過程中,參考開源項目和巧妙使用 Java代碼轉kotlin 的快捷鍵是挺有用的