一,搭建开发环境
1,安装Android Studio 3.0及以上版本
2,升级Gradle插件版本至少为4.1
3,升级Kotlin插件版本
4,工程配置
①,配置工程
buildscript {
ext.kotlin_version = '1.1.51'//指定Kotlin的编译版本
ext.anko_version="0.9"//指定Anko库的版本号
repositories {
google()
jcenter()
}
dependencies {
classpath ':gradle:3.1.3'
//指定Kotlin插件的路径
classpath ":kotlin-gradle-plugin:$kotlin_version"
classpath ":kotlin-android-extensions:$kotlin_version"
}
}
②,配置项目
//引入插件
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
//库编译版本
implementation ":kotlin-stdlib-jre7:$kotlin_version"
implementation ":anko-common:$anko_version"
③,编写Activity,这就是Activity代码和Java方式基本一样,只是Kotlin用 “ :” 替代了extends,还有类的重载用override
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
(savedInstanceState)
setContentView(.activity_main2)
}
}
二,常用控件使用
1,Button
①,基本使用
//anko库支持直接用控件名button的方式,省去了findViewById
= "这是个按钮"
//点击事件,不需要视图方式
{
= "你点了一下"
}
②,匿名函数方法
//点击事件,需要传入视图方式。“->” 前边是类型参数相当于View,后边是事件的具体实现
//模板表达式 ${""}
{ v ->
toast("点击了控件:${(v as Button).text}")
}
③,内部类
class Main2Activity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
(savedInstanceState)
setContentView(.activity_main2)
//点击事件,内部类方式
(MyClickListener())
}
//Kotlin关键字 inner 是标记该类为内部类,和Java内部类一样。
// 如果不用inner关键字,就是嵌套类,嵌套类不能访问外部类成员
private inner class MyClickListener : {
override fun onClick(v: View) {
toast("点击了控件:${(v as Button).text}")
}
}
}
2,复选框CheckBox
//isChecked可以设置状态也可以获取状态
= false
//复选框点击事件
{ v, isChecked ->
= "你${if (isChecked) "勾选" else "取消"}了复选框"
}
3,自定义view
①,自定义view和java的对比
//java实现
public class MyImageView extends ImageView {
public MyImageView(Context context) {
this(context, null);
}
public MyImageView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public MyImageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
}
//kotlin实现
class MyImageView @JvmOverloads constructor(context: Context, attributeSet: AttributeSet? = null, defAttrStyle: Int = 0)
: ImageView(context, attributeSet, defAttrStyle) {
}
kotlin实现,使用@JvmOverloads注解是为了在Java中可以调用Kotlin中定义重载构造器方法,也就是重载三种构造的意思。
三,Kotlin实现数据存储
1,全局Application
①,在App运行中,Application贯穿应用的整个生命周期,我们经常会用到全局Application,通常我们会把Application实现单例模式
②,单例化第一种方式
class App : Application() {
override fun 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() {
()
instance = this
}
//借助Delegates的委托属性单例化
companion object {
private var instance: App by ()
fun instance() = instance
}
}
④,单例化第三种方式(自定义代理)
一般前两种在大多数情况下是可以的,但是还不够严格
class App : Application() {
override fun 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) {
= if ( == 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 { ("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(()) {
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?) {
(savedInstanceState)
setContentView(.activity_main2)
//isChecked可以设置状态也可以获取状态
= false
//复选框点击事件
{ v, isChecked ->
//保存数据
name = "小名"
age = 28
}
//获取数据
= "姓名:${name},年龄:${age}"
}
}
3,文件I/O操作
Kotlin文件读取常用方法
- readText():读取整个文件内容
- readLines():按行读取,返回字符串集合
- readBytes():得到文件字节数组
- writeText():写入文件
- walk():得到文件树
//读取文件内容,可以指定编码格式
val content = File("文件路径").readText(("UTF-8"))
//按行读取 读取前三行
var strs: List<String> = File("文件路径").readLines().take(3)
//写文件
File("文件路径").writeText("写入内容")
//遍历文件目录
val fileTree: FileTreeWalk = File("路径").walk()
(1)//遍历目录层级为1,不需要遍历子目录
.filter { }//只选择文件,不包含目录
.filter { == "txt" }//选择扩展名为txt的文本文件
//.filter { in listOf("png", "jpg") }//选择扩展名为png和jpg的图片文件