1. Kotlin配置
点击菜单栏的“Tools”选项,选择“Kotlin”,然后选择“Configure Kotlin in Project”。如下图所示。
在弹出的窗口中选择需要使用Kotlin的模块和Kotlin编译器和运行时的版本,如下图所示。
点击“OK”之后,Kotlin插件会自动开始配置。配置完成之后,同步一下工程(Sync Project)即可。
推荐配置
:打开模块下的build.gradle文件,在apply plugin: ‘kotlin-android’下面加入一行:apply plugin: ‘kotlin-android-extensions’。这是一个Kotlin的扩展模块,可以让Activity自动关联xml布局中的View而不需要findViewById。
2. Anko的使用
![Alt text](https://img-blog.csdn.net/20170928104504372?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvTGVicm9uX3hpYQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
在官方库Anko
的支持下,有了很多变化
2.1 向findViewById告别
val onlyTv = find<TextView>(R.id.onlyTv)
val onlyTv: TextView = find(R.id.onlyTv)
在导入一个插件kotlin-android-extensions
,变得更简单了
直接使用在布局中定义的id为hello的这个textView
2.2 简单粗暴的startActivity
Intent intent = new Intent(LoginActivity.this, MainActivity.class);
intent.putExtra("name", "张三");
intent.putExtra("age", 27);
startActivity(intent);
startActivity<MainActivity>()
startActivity<MainActivity>("name" to "张三", "age" to 27)
startActivityForResult<MainActivity>(101, "name" to "张三", "age" to 27)
![Alt text](https://img-blog.csdn.net/20170928104545895?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvTGVicm9uX3hpYQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
2.3 封装Toast
//原来样子
Toast.makeText(context, "this is a toast", Toast.LENGTH_SHORT).show()
//现在样子
context.toast("this is a toast")
2.4 DSL编程(接下来补充)
2.5 简化异步操作
//有了Anko的配合,蜜汁缩进
Alt text
2.6 简化日志打印
实现AnkoLogger
这个接口,方便打印日志
![Alt text](https://img-blog.csdn.net/20170928104745612?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvTGVicm9uX3hpYQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
Tag为所在类的类名
3. 其他方法
3.1 用apply方法进行数据组合
class A(val b: B)
class B(val c: C)
class C(val content: String)
C c = new C("content");
B b = new B(c);
A a = new A(b);
val a = A().apply {
b = B().apply {
c = C("content")
}
}
layout.addView(TextView(context).apply {
text = "这是文本内容"
textSize = 16f
})
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
只需声明一个变量。这里我们只声明了一个 a 对象,然后初始化了一个 A,在这个初始化的对象中先给 B 赋值,然后再提交给了 a。
3.2 利用扩展类代替工具类
我做字符串判断的时候一定会写一个工具类,在这个工具类里充斥着各种各样的判断方法。而在 Kotlin 中,可以用扩展方法来替代。
//String的扩展类
fun String.isName(): Boolean {
if (isEmpty() || length > 10 || contains(" ")) {
return false
}
val reg = Regex("^[a-zA-Z0-9\u4e00-\u9fa5]+$")
return reg.matches(this)
}
fun String.isPassword(): Boolean {
return length in 6..12
}
fun String.isNumber(): Boolean {
val regEx = "^-?[0-9]+$"
val pat = Pattern.compile(regEx)
val mat = pat.matcher(this)
return mat.find()
}
...
println("张三".isName())
println("123abc".isPassword())
println("123456".isNumber())
//ImageView的扩展类
fun ImageView.displayUrl(url: String?) {
if (url == null || url.isEmpty() || url == "url") {
imageResource = R.mipmap.ic_launcher
} else {
Glide.with(context)
.load(ColumnServer.SERVER_URL + url)
.into(this)
}
}
...
val imageView = findViewById(R.id.avatarIv) as ImageView
imageView.displayUrl(url)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
3.3 委托/代理,SharedPreference 不再麻烦(还需要研究)
3.4 数据类的自动getter/setter及class简洁的写法
//Java代码
class Person {
private String name;
public Person(String name) {
this.name = name;
}
public void setName(String name) {
this.name = name;
}
public void getName() {
return name;
}
}
Person person = new Person("张三");
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
//Kotlin代码
class Person(var name: String)
val person = Person("张三")
class Person(var name: String = "张三")
val person = Person()
3.5 实现单例
//Java中单例
public class Singleton {
private static Singleton instance = null;
private Singleton(){
}
private synchronized static void createInstance() {
if (instance == null) {
instance = new Singleton();
}
}
public static Singleton getInstance() {
if (instance == null) createInstance();
return instance;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
//而在Kotlin中,只用一句话表示
object Singleton{}
3.6 容器的操作符(接下来补充)
3.7 with的用法
with函数是一个单独的函数,并不是Kotlin中的extension,所以调用方式有点不一样,返回是最后一行,然后可以直接调用对象的方法
当一个对象实例需要调用多个方法
fun alphabet(): String {
val stringBuilder = StringBuilder()
return with(stringBuilder) {
for (letter in 'A'..'Z') {
this.append(letter)
}
append("\nNow I know the alphabet!")
this.toString()
}
}
3.8 伴生对象
每个类都可以实现一个伴生对象,它是该类的所有实例共有的对象。它将类似于Java中的静态字段。
class App : Application() {
companion object {
lateinit var instance: App
private set
}
override fun onCreate() {
super.onCreate()
instance = this
}
}
3.9 创建匿名类的实现
recycler.adapter = object : RecyclerView.Adapter() {
override fun onBindViewHolder(holder: RecyclerView.ViewHolder?, position: Int) {
}
override fun getItemCount(): Int {
}
override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): RecyclerView.ViewHolder {
}
}
3.10 最终类
使用sealed
关键字修饰
sealed class SealedClassTest {
object getStop : Opertion()
object getStart : Opertion()
}
3.11 延迟属性
val emails by lazy { loadEmails(this) }
3.12 委托类/代理属性(by)
Kotlin-代理属性(by)
使用by关键字
`使用了委托模式:为其他对象提供了一种代理以控制这个对象的访问
- 延迟加载属性(lazy property): 属性值只在初次访问时才会计算,
- 可观察属性(observable property): 属性发生变化时, 可以向监听器发送通知,
- 将多个属性保存在一个 map 内, 而不是保存在多个独立的域内.
interface ISports {
fun doSports()
}
class SwimForSports: ISports{
override fun doSports() {
println("do swim")
}
}
class SportsManager(sport: ISports): ISports by sport
fun main(args: Array<String>) {
val swimSports: SwimForSports = SwimForSports()
SportsManager(swimSports).doSports()
}