前言
關於Kotlin的文章,已經構思了很久。一直不知道該怎麼寫。文件式文章?那不如直接看文件,何必需要我再多“嗶嗶”呢。思來想後,決定寫一篇快速在Android開發中感受Kotlin的其妙的文章。
說實話,最開始搞Kotlin我是拒絕的。為啥?因為完全沒有感覺到用它替換Java開發有什麼實質性的改變;而且感覺語法很“彆扭”!(其實說白了,就是不想學,給自己找藉口。哈哈)
但是,後來機緣巧合卻感受到了Kotlin的有趣之處。當然這一切的開始,要克服寫久了Java的那一種“彆扭”(由其是在Lambda寫的也不多的情況下)。OK,不扯了。文章將從我接觸Kotlin時,遇到“彆扭”的地方開始展開。
正文
靜態方法
第一個讓我懵逼的是靜態方法。在Kotlin裡邊被叫做了:伴生物件。這裡不扯“花裡胡哨”的介紹。直接上程式碼:
public class StringUtils{
public static void myFun(){
Log.d("StringUtils","Haha");
}
}
複製程式碼
在Java中這麼一個簡單工具類中的靜態方法,Kotlin要怎麼寫?
class StringUtils{
companion object {
fun myFun(){
Log.d("StringUtils","Haha")
}
}
}
複製程式碼
匿名內部類
setOnClickListener是我們比較常用的匿名內部類的使用場景:
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d("Listener","Haha")
}
}
複製程式碼
那麼到了Kotlin中又是什麼樣子了呢?
btn.setOnClickListener {
Log.d("Listener","Haha")
}
複製程式碼
直接幫我們Lambda化了。如果我們不想Lambda化那應該是什麼樣子?
btn.setOnClickListener(object : View.OnClickListener{
override fun onClick(v: View?) {
Log.d("Listener","Haha")
}
})
複製程式碼
也沒什麼特別的,其實就是Kotlin的語法。因為Kotlin裡邊宣告的變數要寫在前面,其型別用:號隔開,寫在後面。也就是現在這個樣子。不過需要注意的,這裡的object代表匿名物件型別。
這裡有一個小細節,不知道大兄弟們有沒有注意到。在Java中我們new匿名內部類的時候:new View.OnClickListener(){}
,是有()的。而在Kotlin中則:View.OnClickListener{}
沒有()。這裡也是屬於語法細節,加上()表示顯示的呼叫這個類的構造方法。
Kotlin in RxJava
先看一個很簡單的Java用法:
Observable.just(0)
.map(new Function<Integer, String>() {
@Override
public String apply(Integer integer) throws Exception {
return integer.toString();
}
})
.subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
Log.d("RxJava", s);
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
Log.d("RxJava", throwable.getMessage());
}
});
複製程式碼
對於Kotlin來說,在Lambda的加持之下,寫法變得異常的簡潔(當然Java進行Lambda化也很簡潔):
Observable.just(0)
.map({ it!!.toString() })
.subscribe({ t: String -> Log.d("RxJava", t)
}, { t: Throwable -> Log.d("RxJava", t.message) })
複製程式碼
如果對Lambda不是很熟悉的大兄弟們,肯定有點懵。那麼我們們換成普通的kotlin,,是不是感覺很熟悉?object又出現了,沒錯這裡就是普通的匿名內部類而已。
Observable.just(0)
.map(object : Function<Int, String> {
override fun apply(t: Int): String {
return t.toString()
}
})
.subscribe(object : Consumer<String> {
override fun accept(t: String) {
Log.d("RxJava", t)
}
}, object : Consumer<Throwable> {
override fun accept(t: Throwable) {
Log.d("RxJava", t.message)
}
})
複製程式碼
Kotlin in Adapter
上述的幾塊程式碼,我們一起感受了Kotlin在RxJava中的變形。說實話,如果丟擲Lambda,真心談不上什麼大的變化。就是語法上的轉變。聊過了我們日常開發比重比較大的RxJava,接下來我們再來看一看另一個重頭戲Adapter。這裡直接上Kotlin程式碼:
class TestAdapter(var data: List<String>,var context:Context) : RecyclerView.Adapter<TestAdapter.ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): ViewHolder {
return ViewHolder(TextView(context))
}
override fun getItemCount(): Int {
return data.size
}
override fun onBindViewHolder(holder: ViewHolder?, position: Int) {
holder!!.textView.text = "Haha"
}
class ViewHolder(var textView: TextView) : RecyclerView.ViewHolder(textView)
}
複製程式碼
最開始看這個程式碼的時候,我是有點懵的,感覺不知所措。其實帶入Kotlin的語法,非常的好理解。在最開始宣告這個class的時候,我們直接在TestAdapter的主構造方法中宣告瞭兩個var的變數。這種寫法就類似於Java中的:
class TestAdapter {
public List<String> data;
public Context context;
public TestAdapter(List<String> data, Context context) {
this.data = data;
this.context = context;
}
}
複製程式碼
這也就是為什麼我們能在class裡邊隨意呼叫data和context的原因。
注意var,如果我們在構造方法中宣告時不加上var,就可以理解為這個變數是區域性變數。只適用於構造方法中。
這中間override的程式碼應該沒什麼好說的,我們來看一下最後宣告的class ViewHolder。正常來說我們在Java中的ViewHolder都是這個樣子:
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView textView;
public ViewHolder(TextView textView) {
super(textView);
this.textView= textView;
}
}
複製程式碼
那為什麼到了Kotlin之中,就變成了短短的一行class ViewHolder(var textView: TextView) : RecyclerView.ViewHolder(textView)
了呢?其實也沒有什麼神奇的,就是正常語法而已。
這小結開始的時候,我們提到了主構造方法,以及在匿名內部類這個小結中提到加上()表示顯示的呼叫這個類的構造方法。
因此Kotlin的這段程式碼非常的好理解:
尾聲
OK,關於Kotlin在我們Android開發這些彆扭的地方就暫時寫到這。其實說白了,這些都是最基本的語法問題。這裡挑出來的這幾個Android的場景,是我在自以為學會語法的時候,覺得彆扭的地方。當然彆扭的原因還是因為自己對語法並不夠理解。所以才有了這篇文章,希望可以給正準備走上Kotlin這條路上的大兄弟們一些幫助吧~