快速切換至Kotlin for Android模式

MDove發表於2019-03-04

前言

幾個特性,快速上手Kotlin

充分理解Kotlin,快速上手寫業務

快速切換至Kotlin for Android模式

聊一聊Kotlin中的協程,真香

關於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 for Android模式
如果這樣的話,那就和new普通的類,沒什麼區別的(而不是匿名內部類)。藉著匿名內部類,我們直接來看一下Kotlin在RxJava中的實戰。

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的這段程式碼非常的好理解:

快速切換至Kotlin for Android模式
就是把主構造方法中傳遞的textView,傳給RecyclerView.ViewHolder()構造方法中。也就是和我們的Java程式碼一毛一樣的,只是寫法不同罷了。

尾聲

OK,關於Kotlin在我們Android開發這些彆扭的地方就暫時寫到這。其實說白了,這些都是最基本的語法問題。這裡挑出來的這幾個Android的場景,是我在自以為學會語法的時候,覺得彆扭的地方。當然彆扭的原因還是因為自己對語法並不夠理解。所以才有了這篇文章,希望可以給正準備走上Kotlin這條路上的大兄弟們一些幫助吧~

我是一個應屆生,最近和朋友們維護了一個公眾號,內容是我們在從應屆生過渡到開發這一路所踩過的坑,以及我們一步步學習的記錄,如果感興趣的朋友可以關注一下,一同加油~

個人公眾號:鹹魚正翻身

相關文章