前言
关于 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{}没有 (). 这里也是属于语法细节, 加上() 表示显示的调用这个类的构造方法.
如果这样的话, 那就和 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 的这段代码非常的好理解:
就是把主构造方法中传递的 textView, 传给 RecyclerView.ViewHolder()构造方法中. 也就是和我们的 Java 代码一毛一样的, 只是写法不同罢了.
尾声
OK, 关于 Kotlin 在我们 Android 开发这些别扭的地方就暂时写到这. 其实说白了, 这些都是最基本的语法问题. 这里挑出来的这几个 Android 的场景, 是我在自以为学会语法的时候, 觉得别扭的地方. 当然别扭的原因还是因为自己对语法并不够理解. 所以才有了这篇文章, 希望可以给正准备走上 Kotlin 这条路上的大兄弟们一些帮助吧~
来源: https://juejin.im/post/5bee256651882572ac7f14c9