Kotlin详解:第三章,实战

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wang_yong_hui_1234/article/details/81476954

一,搭建开发环境

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
    }
}

④,单例化第三种方式(自定义代理)
一般前两种在大多数情况下是可以的,但是还不够严格

扫描二维码关注公众号,回复: 4599868 查看本文章
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的图片文件

猜你喜欢

转载自blog.csdn.net/wang_yong_hui_1234/article/details/81476954