扩展函数/属性/中缀调用

Kotlin - 扩展函数

扩展函数:它是一个类的成员函数,不过是定义在类的外面。
比如说定义一个String的扩展函数计算该字串的最后一个字符

1
fun String.lastChar(): Char = this.get(this.length - 1)

当我们想调用该函数的时候

1
println("kotlin".lastChar())

Warning: 扩展函数不能访问到私有的或者受保护的成员。

扩展函数不存在重写的情况,当一个类的成员函数和扩展函数拥有相同的签名时,成员函数会被优先使用。

1
2
3
4
5
6
7
class Button {  
fun test() {
println("This is member fun")
}
}
val button: Button = Button()
button.test()

Result : This is member fun

Kotlin - 扩展属性

扩展属性和扩展函数类似,就像接收者的一个普通成员属性一样。
Warning: 必须定义getter函数,不能初始化,因为没有地方存储初始值。

1
2
3
4
5
6
7
8
var StringBuilder.lastChar: Char  
get() = get(this.length - 1)
set(value: Char) {
this.setCharAt(length - 1, value)
}
val sb = StringBuilder("kotlin?")
sb.lastChar = '!'
println(sb)

Result : kotlin!
具体在实战中如何使用暂时不知。不过在Collection中已经默认增加了很多扩展函数,例如last(用来获取列表中最后一个元素)或者max(获取集合中的最大值)。这些在IDE中都会在补全功能中显示出来。

Kotlin - 中缀调用

中缀调用:调用函数的时候不加分隔符,直接在对象和参数之间的调用方式。

1
val map = mapOf(1 to "one", 7 to "seven")

等价于

1
val map = mapOf(1.to("one"), 7.to("seven"))

中缀调用可以与只有一个参数的函数一起使用,并且需要用infix修饰符来标记它。
例如上述to函数的声明

1
public infix fun <A, B> A.to(that: B): Pair<A, B> = Pair(this, that)

个人理解增加函数调用的可读性。

Modify shape attributes in code

1
2
3
((GradientDrawable)(ContextCompat.getDrawable(context, R.drawable.pen_color_red)))
.setSize(getResources().getDimensionPixelSize(R.dimen.wb_native_buttons_size_newui),
getResources().getDimensionPixelSize(R.dimen.wb_native_buttons_size));

convert drawable to GradientDrawable,and invoke setSize or setStroke and so on.

PopupWindow show at location

Recently,UE Team has updated some features.One of them is click on the button,and show PopupWindow right above the button.
The point is can’t use hardcode because different devices has different resolution. So the best way is get the location in the window.
There is method named getLocationInWindow(View view) in View.java.All we have to do is invoke the method by the button and pass an array.This array will store two value,X coordinate and Y coordinate.

1
2
3
4
int[] viewLocation = new int[2];
view.getLocationInWindow(viewLocation);
//X coordinate viewLocation[0]
//Y coordinate viewLocation[1]