:今天在知乎日报中的《Google I/O 完整盘点,这才是地球上最「性感」的发布会》中看到这么一句话
为了让开发者能够开发出更优秀的应用,Android 开始支持新的编程语言 Kotlin,开发人员的生产力能大幅度提升。
无奈,谷歌都说要支持了,看看Kotlin是个什么东西吧 - - - 不看不知道一看吓一跳,还真是个逆天的东西!
什么是Kotlin..
- Kotlin 是一个基于 JVM 的新的编程语言,由 JetBrains 开发;
- Kotlin可以编译成Java字节码,也可以编译成JavaScript,方便在没有JVM的设备上运行;
JetBrains,作为目前广受欢迎的Java IDE IntelliJ 的提供商,在 Apache 许可下已经开源其Kotlin
编程语言.
Kotlin有啥好处..简洁: 大量重复的模版代码不用写了,JavaBean不用写了,findViewById也不用写了..等等;
- 安全: 空指针等异常在语言层面被处理掉了,不用去写各种判空操作,有空会编译不通过;
- 函数式编程: 自带lambda,filter,map,reduce;
- 与 Java 完美结合: Kotlin 可以完美复用现有 Java 代码,不用去重写,反过来也适用.
怎么用..
语法
- 定义变量
var 变量名 : 变量类型 = 初值;
var 变量名 = 初值;
栗子
var variable : Int = 10086; - 定义常量
val 变量名 : 变量类型 = 初值;
栗子
val constant : Int = 10086; - 定义方法(注意 返回值类型前面有 “:”)
fun 方法名(参数名 : 参数类型,参数名:参数类型) : 返回值类型<没有不写>{
方法体;
}
栗子
fun method(count : Int,name : String) : String{
return name+count;
} - 重写方法
override fun 父类方法(父类参数) : 父类方法返回值{
方法体
}
栗子
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
} 方法扩展
Kotlin 可以在不修改原始类的情况下,给类增加新的功能(方法) 具体使用请见示例代码
fun 原类名.新方法名(参数)返回值{ 方法体 }List 赋初值
var list = arrayListOf<Int>(1,2,3,4,5); 泛型可加可不加List 不赋初值
var list = arrayListOf<Int>(); 泛型必须加List遍历
for(item in list){
Log.i(“RedWolf”,”“+item);
}Map的赋初值与不赋初值的用法和List一样
- Map 只读
var map = mapOf <Int,Int>(); Map 可读可写
var map = mutableMapOf<String,String>();Map遍历
for((k,v) in map){
Log.i(“RedWolf”, “$k->$v”);
}switch 被取消 被替换为When 具体使用请见实例代码
- 其余使用方法以及特性,咱们进去代码中使用
AndroidStudio中使用
- 然而AndroidStudio暂时还没有自带Kotlin,我们需要安装Plugin…
如图所示 安装重启.57.2M,要等几分钟.
重启之后 新建一个项目,并且打开我们MainActivity,我们可以Ctrl+Shift+A 搜索Convert 点击Convert Java File to Kotlin File 也可以直接Ctrl+Shift+Alt+K 进行转换,转换完毕如图所示
需要配置Gradle
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "org.jetbrains.kotlin:kotlin-android-extensions:$kotlin_version"
...
ext.kotlin_version = '1.1.2-4'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
...
compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
- sync之后,环境就配置好了,我就说一点,Bundle?的意思 是说savaInstanceState可以为null
好了 我们开始编码
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/mTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:id="@+id/mButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="逆天了" />
</LinearLayout>
onCreate中代码
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
mButton.setOnClickListener { mTextView.text = "逆天了" }
}
无奈,这样就行了,也没有findViewById,也没有new OnClickListener
咳咳,说明一下,首先为什么不用写findViewById,因为我们的 layout 文件中所有的控件被当成类一样 import 进来,控件的 id 就是其变量名
大家看好import的代码
import kotlinx.android.synthetic.main.activity_main.*
其次,因为Kotlin自带lambda 表达式,并且比原来的更为精简,若是对Lamdba不是很明白的可以看一下,简单易懂
我们把上面讲的使用方法以及特性<说了的和没说的>写到代码中来看看<高能预警 前方为连续代码片段,可直接源码下载>
源码下载
源码我把所有的文件都上传了 可能比较大 故有一份在Github上
也提供Github
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:id="@+id/mBtnWhen"
android:layout_width="match_parent"
android:textAllCaps="false"
android:layout_height="wrap_content"
android:text="mBtnWhen" />
<Button
android:id="@+id/mBtnList"
android:textAllCaps="false"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="mBtnList遍历" />
<Button
android:id="@+id/mBtnMap"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAllCaps="false"
android:text="mBtnMap遍历" />
<Button
android:id="@+id/mBtnMapMethod"
android:textAllCaps="false"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="mBtnMapMethod" />
<Button
android:id="@+id/mBtnReduce"
android:layout_width="match_parent"
android:textAllCaps="false"
android:layout_height="wrap_content"
android:text="mBtnReduce" />
<Button
android:id="@+id/mBtnFilter"
android:textAllCaps="false"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="mBtnFilter" />
<Button
android:id="@+id/mBtnExtend"
android:textAllCaps="false"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="mBtnExtend" />
<Button
android:id="@+id/mBtnJavaBean"
android:textAllCaps="false"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="mBtnJavaBean" />
</LinearLayout>
MainActivity.kt
package redwolf.com.test
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.util.Log
import android.widget.Button
import android.widget.Toast
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// When 替代 Switch
mBtnWhen.setOnClickListener {
val count: Int = 70;
// 很简单 就不带注释了 数字只能这么来 in X..X 字符串可以直接 in X
when (count) {
in 80..100 -> Toast.makeText(this, "80..100", Toast.LENGTH_SHORT).show();
in 71..79 -> Toast.makeText(this, "71..79", Toast.LENGTH_SHORT).show();
in 70..70 -> Toast.makeText(this, "70", Toast.LENGTH_SHORT).show();
else -> Toast.makeText(this, "else", Toast.LENGTH_SHORT).show();
}
}
mBtnExtend.setOnClickListener {
// 类的对象可直接使用
mBtnExtend.extendMethod("RedWolf")
}
mBtnFilter.setOnClickListener {
var list = arrayListOf<Int>(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 22, 33);
// Filter用于筛选
// 例 取出list中3的倍数
var newList = list.filter { it % 3 == 0 }
LogI("" + newList)
}
mBtnMapMethod.setOnClickListener {
var list = arrayListOf<Int>(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 22, 33);
// map用于变换
// 例 使List中的每一个元素自乘
var newList = list.map { it * it }
LogI("" + newList)
}
mBtnReduce.setOnClickListener {
var list = arrayListOf<Int>(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 22, 33);
// Reduce 主要用于求所有元素的结果(加减乘除立方开放 等等)
// 例 得到和
var sum = list.reduce { acc, i -> acc + i }
LogI("" + sum)
}
mBtnList.setOnClickListener {
var list = arrayListOf<Int>(1, 2, 3, 4, 5);
// 添加元素
list.add(111);
// 删除元素
list.remove(2);
// 删除指定位置的元素
list.removeAt(1);
// 遍历
for (item in list) {
LogI("" + item);
}
}
mBtnMap.setOnClickListener {
// 只读 没有put,replace remove 等方法 可以不赋初值 但是没意义
var map1 = mapOf<String, Int>();
// 普通
var map = mutableMapOf<String, Int>(Pair("1111", 2222), Pair("3333", 4444), Pair("5555", 6666));
// 使用方法和HadhMap一致
map.put("Key", 12345);
// 遍历
for ((key, value) in map) {
LogI("$key->$value")
}
}
mBtnJavaBean.setOnClickListener {
javaBean();
}
}
// 类扩展
fun Button.extendMethod(name: String) {
LogI("无奈 extendMethod_" + name);
}
// 表明message不可以为null
fun LogINull(message: String?) {
Log.i("RedWolf", message);
}
// 表明message不可以为null
fun LogI(message: String) {
Log.i("RedWolf", message);
}
// Kotlin 定义变量有两种方式,可以为 Null 和不可以为 Null
// 在变量类型后面 加"?"表示该变量 可以为 Null
fun nullTest() {
// 一个可以为null的字符串str
var str: String? = null;
// 一个不可以为null的字符串str1
//var str1: String = null; // 会报错
var str1: String = ""; // 不会报错
// 可能为null的变量不可以直接调用它的方法 会报错
// str.count();
// 如果str为空 咋不走这个方法 否则 执行str.count
str?.count();
// 不管str是否为null都要走这个方法,为空就抛出 空指针
str!!.count();
// str1不可以为空 所以可以直接调用方法
str1.count();
}
// 实体类使用
fun javaBean() {
var kStu: KStudent = KStudent("RedWolf", 108);
LogI(kStu.toString());
var stu: Student = Student("RedWolfChao", 10800);
LogI(stu.toString());
}
}
KStudent.kt
package redwolf.com.test
// 和Student类无关
data class KStudent(val name: String, val age: Int)
Student.java
package redwolf.com.test;
/**
* @作者 RedWolf
* @时间 2017/5/18 16:17
* @简介 Student.java
*/
public class Student {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
东西都在代码里了