点击菜单栏的“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。
在官方库Anko
的支持下,有了很多变化
val onlyTv = find(R.id.onlyTv)
val onlyTv: TextView = find(R.id.onlyTv)
在导入一个插件kotlin-android-extensions
,变得更简单了
直接使用在布局中定义的id为hello的这个textView
//原本的样子
Intent intent = new Intent(LoginActivity.this, MainActivity.class);
intent.putExtra("name", "张三");
intent.putExtra("age", 27);
startActivity(intent);
//在Kotlin中的表现
startActivity()
startActivity("name" to "张三", "age" to 27)
startActivityForResult(101, "name" to "张三", "age" to 27)
//原来样子
Toast.makeText(context, "this is a toast", Toast.LENGTH_SHORT).show();
//现在样子
context.toast("this is a toast")
Tag为所在类的类名
//例如
//创建三个类
class A(val b: B)
class B(val c: C)
class C(val content: String)
//用Java方法进行数据组合
C c = new C("content");
B b = new B(c);
A a = new A(b);
//使用apply方法进行数据组合
val a = A().apply {
b = B().apply {
c = C("content")
}
}
//在DSL编程汇中的写法
layout.addView(TextView(context).apply {
text = "这是文本内容"
textSize = 16f
})
只需声明一个变量。这里我们只声明了一个 a 对象,然后初始化了一个 A,在这个初始化的对象中先给 B 赋值,然后再提交给了 a。
我做字符串判断的时候一定会写一个工具类,在这个工具类里充斥着各种各样的判断方法。而在 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)
//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("张三");
//Kotlin代码
class Person(var name: String)
val person = Person("张三")
//添加默认值
class Person(var name: String = "张三")
val person = Person()
//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;
}
}
//而在Kotlin中,只用一句话表示
object Singleton{}
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()
}
}
每个类都可以实现一个伴生对象,它是该类的所有实例共有的对象。它将类似于Java中的静态字段。
class App : Application() {
companion object {
//lateinit表示这个属性开始是没有值得,但是,在使用前将被赋值
lateinit var instance: App
//private set用于说明外部类不能对其进行赋值。
private set
}
override fun onCreate() {
super.onCreate()
instance = this
}
}
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 {
}
}
使用sealed
关键字修饰
sealed class SealedClassTest {
object getStop : Opertion()
object getStart : Opertion()
}
val emails by lazy { loadEmails(this) }
Kotlin-代理属性(by)
使用by关键字
`使用了委托模式:为其他对象提供了一种代理以控制这个对象的访问
- 延迟加载属性(lazy property): 属性值只在初次访问时才会计算,
- 可观察属性(observable property): 属性发生变化时, 可以向监听器发送通知,
- 将多个属性保存在一个 map 内, 而不是保存在多个独立的域内.
//Kotlin中,委托的实现依靠于关键字 by ,by表示将抽象主题的实例(by后边的实例)保存在代理类实例的内部,比如SportsManager类继承于ISports接口,并可以ISports接口的所有的 public 方法委托给一个指定的对象。
interface ISports {
fun doSports()
}
class SwimForSports: ISports{
override fun doSports() {
println("do swim")
}
}
class SportsManager(sport: ISports): ISports by sport
fun main(args: Array) {
val swimSports: SwimForSports = SwimForSports()
SportsManager(swimSports).doSports()// Log:do swim
}
参考:
Kotlin学习
用Kotlin写Android 01 难道只有环境搭建这么简单?
用 Kotlin 写 Android 02 说说 Anko
用 Kotlin 开发 Android 项目是一种什么样的感受?
用 Kotlin 开发 Android 项目是一种什么样的感受?(二)