Kotlin詳解:第三章,實戰
阿新 • • 發佈:2018-12-22
一,搭建開發環境
1,安裝Android Studio 3.0及以上版本
2,升級Gradle外掛版本至少為4.1
3,升級Kotlin外掛版本
4,工程配置
①,配置工程build.gradle
buildscript { ext.kotlin_version = '1.1.51'//指定Kotlin的編譯版本 ext.anko_version="0.9"//指定Anko庫的版本號 repositories { google() jcenter() } dependencies { classpath 'com.android.tools.build:gradle:3.1.3' //指定Kotlin外掛的路徑 classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.kotlin:kotlin-android-extensions:$kotlin_version" } }
②,配置專案build.gradle
//引入外掛
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
//庫編譯版本
implementation "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
implementation "org.jetbrains.anko:anko-common:$anko_version"
③,編寫Activity,這就是Activity程式碼和Java方式基本一樣,只是Kotlin用 “ :” 替代了extends,還有類的過載用override
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main2)
}
}
二,常用控制元件使用
1,Button
①,基本使用
//anko庫支援直接用控制元件名button的方式,省去了findViewById button.text = "這是個按鈕" //點選事件,不需要檢視方式 button.setOnClickListener { button.text = "你點了一下" }
②,匿名函式方法
//點選事件,需要傳入檢視方式。“->” 前邊是型別引數相當於View,後邊是事件的具體實現
//模板表示式 ${""}
button.setOnClickListener { v ->
toast("點選了控制元件:${(v as Button).text}")
}
③,內部類
class Main2Activity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main2)
//點選事件,內部類方式
button.setOnClickListener(MyClickListener())
}
//Kotlin關鍵字 inner 是標記該類為內部類,和Java內部類一樣。
// 如果不用inner關鍵字,就是巢狀類,巢狀類不能訪問外部類成員
private inner class MyClickListener : View.OnClickListener {
override fun onClick(v: View) {
toast("點選了控制元件:${(v as Button).text}")
}
}
}
2,複選框CheckBox
//isChecked可以設定狀態也可以獲取狀態
checkbox.isChecked = false
//複選框點選事件
checkbox.setOnCheckedChangeListener { v, isChecked ->
checkbox.text = "你${if (isChecked) "勾選" else "取消"}了複選框"
}
3,自定義控制元件
三,Kotlin實現資料儲存
1,全域性Application
①,在App執行中,Application貫穿應用的整個生命週期,我們經常會用到全域性Application,通常我們會把Application實現單例模式
②,單例化第一種方式
class App : Application() {
override fun onCreate() {
super.onCreate()
instance=this
}
companion object {
//實現一:宣告可空屬性
private var instance:App?=null
fun instance()=instance!!
//實現二:宣告延遲初始化屬性
//private lateinit var instance:App
//fun instance()= instance
}
}
③,單例化第二種方式
class App : Application() {
override fun onCreate() {
super.onCreate()
instance = this
}
//藉助Delegates的委託屬性單例化
companion object {
private var instance: App by Delegates.notNull()
fun instance() = instance
}
}
④,單例化第三種方式(自定義代理)
一般前兩種在大多數情況下是可以的,但是還不夠嚴格
class App : Application() {
override fun onCreate() {
super.onCreate()
instance = this
}
//自定義一個非空且只能一次性賦值的委託屬性
companion object {
private var instance: App by NotNullSingleValueVar()
fun instance() = instance
}
private class NotNullSingleValueVar<T>() : ReadWriteProperty<Any?, T> {
private var value: T? = null
override fun getValue(thisRef: Any?, property: KProperty<*>): T {
return value ?: throw IllegalStateException("application not initialized")
}
override fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
this.value = if (this.value == null) value
else throw IllegalStateException("application already initialized")
}
}
}
2,SharedPreferences
單獨寫個類實現SharedPreferences
class Preference<T>(val context: Context, val name: String, val default: T) : ReadWriteProperty<Any?, T> {
//通過屬性代理初始化共享引數物件
val prefs: SharedPreferences by lazy { context.getSharedPreferences("default", Context.MODE_PRIVATE) }
//接管屬性值的獲取行為
override fun getValue(thisRef: Any?, property: KProperty<*>): T {
return findPreference(name, default)
}
//接管屬性值的修改行為
override fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
putPreference(name, value)
}
//利用with函式定義臨時的名稱空間
private fun <T> findPreference(name: String, default: T): T = with(prefs) {
val res: Any = when (default) {
is Long -> getLong(name, default)
is String -> getString(name, default)
is Int -> getInt(name, default)
is Boolean -> getBoolean(name, default)
is Float -> getFloat(name, default)
else -> throw IllegalArgumentException("This type can be saved saved Preferences")
}
return res as T
}
private fun <T> putPreference(name: String, value: T) = with(prefs.edit()) {
when (value) {
is Long -> putLong(name, value)
is String -> putString(name, value)
is Int -> putInt(name, value)
is Boolean -> putBoolean(name, value)
is Float -> putFloat(name, value)
else -> throw IllegalArgumentException("This type can be saved into Preferences")
}.apply()
}
}
使用Preference進行資料儲存
class MainActivity : AppCompatActivity() {
//儲存名字
private var name: String by Preference(this, "name", "")
//儲存年齡
private var age: Int by Preference(this, "age", 0)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main2)
//isChecked可以設定狀態也可以獲取狀態
checkbox.isChecked = false
//複選框點選事件
checkbox.setOnCheckedChangeListener { v, isChecked ->
//儲存資料
name = "小名"
age = 28
}
//獲取資料
checkbox.text = "姓名:${name},年齡:${age}"
}
}
3,檔案I/O操作
Kotlin檔案讀取常用方法
- readText():讀取整個檔案內容
- readLines():按行讀取,返回字串集合
- readBytes():得到檔案位元組陣列
- writeText():寫入檔案
- walk():得到檔案樹
//讀取檔案內容,可以指定編碼格式
val content = File("檔案路徑").readText(Charset.forName("UTF-8"))
//按行讀取 讀取前三行
var strs: List<String> = File("檔案路徑").readLines().take(3)
//寫檔案
File("檔案路徑").writeText("寫入內容")
//遍歷檔案目錄
val fileTree: FileTreeWalk = File("路徑").walk()
fileTree.maxDepth(1)//遍歷目錄層級為1,不需要遍歷子目錄
.filter { it.isFile }//只選擇檔案,不包含目錄
.filter { it.extension == "txt" }//選擇副檔名為txt的文字檔案
//.filter { it.extension in listOf("png", "jpg") }//選擇副檔名為png和jpg的圖片檔案