1.kotlin的parcelable使用。
class Student : Parcelable {
var name: String = “”
var sex: String = “”
var age: Int = 0
constructor(source: Parcel) : this( //这是调用了下面的三个参数的构造器,然后进行赋值
source.readString(), //这个要跟下面的构造器的参数进行一一对应
source.readString(),
source.readInt()
)
constructor(name:String,sex:String,age:Int){
this.name=name
this.sex=sex
this.age=age
}
//必须有空参的构造器,这样可以创建无参的对象
constructor()
override fun describeContents() = 0
override fun writeToParcel(dest: Parcel, flags: Int) = with(dest) { //在这里应该是将数据写成序列化数据
writeString(name)
writeString(sex)
writeInt(age)
}
override fun toString(): String {
return "Student(name='$name', sex='$sex', age=$age)"
}
// 通过静态的CREATOR对象,来从Parcel中读取数据。
companion object {
@JvmField
val CREATOR: Parcelable.Creator = object : Parcelable.Creator {
override fun createFromParcel(source: Parcel): Student = Student(source)//在这里会调用构造函数.从parcel中获取数据,封装在对象中。
override fun newArray(size: Int): Array
}
}
}
2.?和!!的区别
//kotlin:
a?.foo()
//相当于java:
if(a!=null){
a.foo();
}
//kotlin:
a!!.foo()
//相当于java:
if(a!=null){
a.foo();
}else{
throw new KotlinNullPointException();
}
3.with //主要是调用某个对象的若干个方法
override fun writeToParcel(dest: Parcel, flags: Int) = with(dest) {
writeString(name)
writeString(sex)
writeInt(age)
}
等同于
override fun writeToParcel(desk:Parcel,flags:Int){
dest.writeString(name)
dest.writeString(sex)
dest.writeInt(age)
}
在绑定对象的数据的时候就能用with(){ }的语法
比如
with(data){
tv_name.text=name
tv_age.text=age
}
4.object
object是lazy-init, 即在第一次使用的时候被创建出来。
//相当于已经初始化对象了。
如果在用object xxxClass{
init{
//这样其实是实现了一个懒加载的功能, 即在这个类被加载的时候,就已经被初始化了一个对象。这里一般情况下等同于java中的单例。但是并不完全是。
}
}
标识为匿名内部类
比如是自定义接口的时候
(activity as MainActivity).setOnDataListener(object: MainActivity.OnDataListener{
override fun onDataListener(data:Object){
}
})
但是在设置点击监听的时候,能够使用更加简便的方法 有三种写法
tv_click.setOnClickListener(object : View.OnClickListener {
override fun onClick(v: View?) {
Toast.makeText(this@Main2Activity, “xxx”, Toast.LENGTH_SHORT).show()
}
})
tv_click1.setOnClickListener(View.OnClickListener {
Toast.makeText(this, “xxx1”, Toast.LENGTH_SHORT).show()
})
tv_click1.setOnClickListener {
Toast.makeText(this, “xxx1”, Toast.LENGTH_SHORT).show()
}
其他地方声明匿名类
fun foo(){
var obj=object{
var x:Int=0
var y:String=""
}
}
5.let
let的使用场景有两个
①进行一个对象的统一判空处理
②明确一个对象作用的区域 然后用it进行代替这个对象。
student?.let{//这里进行了统一的判空的处理。
Log.e(“TAG”,“xxxx”+it.name)
}
6.run
适用于let,with函数任何场景。因为run函数是let,with两个函数结合体,准确来说它弥补了let函数在函数体内必须使用it参数替代对象,在run函数中可以像with函数一样可以省略,直接访问实例的公有属性和方法,另一方面它弥补了with函数传入对象判空问题,在run函数中可以像let函数一样做判空处理
student.run{
Log.e(“TAG”,“xxxx”+name)
}
7.apply函数
和run方法相似
整体作用功能和run函数很像,唯一不同点就是它返回的值是对象本身,而run函数是一个闭包形式返回,返回的是最后一行的值。正是基于这一点差异它的适用场景稍微与run函数有点不一样。apply一般用于一个对象实例初始化的时候,需要对对象中的属性进行赋值。或者动态inflate出一个XML的View的时候需要给View绑定数据也会用到,这种情景非常常见。
8.also函数 功能和apply一样 但是当前的对象用it进行代替
MainActivity.this this@MainActivity