Activity的活动页面跳转是App最常用的功能之一,在前几章的demo源码中便多次见到了,常常是点击界面上的某个按钮,然后跳转到与之对应的下一个页面。对于App开发者来说,该功能的实现非常普通,使用Java编码不过以下两行代码而已:

    Intent intent = new Intent(MainActivity.this, LinearLayoutActivity.class);startActivity(intent);

上面代码的关键之处在于Intent的构造函数,其中第一个参数指定了页面跳转动作的来源,即MainActivity这个源页面,MainActivity.this通常简写为this;构造Intent的第二个参数则表示页面跳转动作的目的地,即LinearLayoutActivity这个目标页面。倘若把这两行Java代码转换为Kotlin代码(复制这两行然后粘贴到kt文件中,Android Studio就会自动完成转换),则可看到活动跳转的Kotlin代码如下所示:

    val intent = Intent(this@MainActivity, LinearLayoutActivity::class.java)startActivity(intent)

对比之下,这里的Kotlin代码与Java代码主要有两点不同之处:
1、在类内部指代自身的this关键字,Java的完整写法是“类名.this”,而Kotlin的完整写法是“this@类名”,当然二者均可简写为“this”;
2、获取某个类的class对象,Java的写法是“类名.class”,而Kotlin的写法是“类名::class.java”,一看便知带有浓浓的Java风味;
看起来,Kotlin代码与Java代码半斤八两,未有明显的简化,令人产生小小的失望。但细心的读者也许已经注意到了,本书附录源码里的活动跳转,并非上述的Kotlin正宗写法,而是下面这种简化版的写法:

    startActivity<LinearLayoutActivity>()

究其原因,乃是Anko库利用Kotlin的扩展函数,给Context类新增了名为startActivity的新方法。故而使用简化版的写法之前,必须先导入Anko库的指定文件,即在kt文件头部添加下面一行导入语句:

import org.jetbrains.anko.startActivity

活动页面跳转的时候,往往还要携带一些请求参数,如果使用Java编码,可以很轻松地调用Intent对象的putExtra方法,通过“putExtra(参数名, 参数值)”的方式传递消息,就像下面代码那样:

    Intent intent = new Intent(this, ActSecondActivity.class);intent.putExtra("request_time", DateUtil.getNowTime());intent.putExtra("request_content", et_request.getText().toString());startActivity(intent);

如果使用Anko的简化写法,其实也很容易,只要在startActivity后面的括号中依次填上每个参数字段的字段名和字段值,具体的Kotlin跳转代码如下所示:

    //第一种写法,参数名和参数值使用关键字to隔开startActivity<ActSecondActivity>("request_time" to DateUtil.nowTime,"request_content" to et_request.text.toString())

注意到上面的写法使用关键字to隔开参数名和参数值,感觉不够美观,而且容易使人迷惑,to后面究竟要跟着字段名还是字段值呢?所以Anko库提供了另一种符合习惯的写法,也就是利用Pair类把参数名和参数值进行配对,Pair的第一个参数为字段名,第二个参数为字段值。据此改写后的Kotlin跳转代码如下所示:

    //第二种写法,利用Pair把参数名和参数值进行配对startActivity<ActSecondActivity>(Pair("request_time", DateUtil.nowTime),Pair("request_content", et_request.text.toString()))

不管哪种写法,在下一个活动中解析请求参数的方式都一样,都得先获取Bundle对象,然后分别根据字段名称获取对应的字段值。具体的请求参数解析代码如下所示:

class ActSecondActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_act_second)val bundle = intent.extrasval request_time = bundle.getString("request_time")val request_content = bundle.getString("request_content")tv_response.text = "收到请求消息:\n请求时间为${request_time}\n请求内容为${request_content}"}
}

下面通过测试界面观察一下消息数据发送之前和发送之后的效果,如下面左图所示,这时第一个页面准备跳转到第二个页面;如下面右图所示,这是跳转后的第二个页面,界面上展示了第一个页面传递过来的参数信息。

Activity之间传递的参数类型,除了整型、浮点数、字符串等基本数据类型,还允许传递序列化结构如Parcelable对象。这个Parcelable对象可不是简单的实体类,而是实现了Parcelable接口的实体类,实现接口意味着该类必须重写接口定义的所有方法,不管你愿不愿意都得老老实实地照猫画虎。譬如前面的活动跳转传递了两个字段数据,如果把这两个字段放到Parcelable对象中,仅仅包含两个字段的Parcelable类对应的Java代码也如下面这般冗长:

public class MessageInfo implements Parcelable {public String content;public String send_time;// 写数据@Overridepublic void writeToParcel(Parcel out, int flags) {out.writeString(content);out.writeString(send_time);}// 例行公事实现createFromParcel和newArraypublic static final Parcelable.Creator<MessageInfo> CREATOR= new Parcelable.Creator<MessageInfo>() {// 读数据public MessageInfo createFromParcel(Parcel in) {MessageInfo info = new MessageInfo();info.content = in.readString();info.send_time = in.readString();return info;}public MessageInfo[] newArray(int size) {return new MessageInfo[size];}};@Overridepublic int describeContents() {return 0;}
}

看看这架势,如此简单的自定义Parcelable类,就得重写包括writeToParcel、createFromParcel、newArray、describeContents在内的四个方法,可谓是兴师动众。由此可见这里又是Java的一个痛点,正适合Kotlin施展拳脚、好好改进。在第五章的类和对象中,介绍了Kotlin对数据类的写法,在类名前面关键字data,Kotlin即可自动提供get/set、equals、copy、toString等诸多方法。那么序列化对象的改造也相当简单,仅需在类名之前增加一行注解“@Parcelize”就好了,整个类的Kotlin代码只有下面寥寥几行:

@Parcelize
data class MessageInfo(val content: String, val send_time: String) : Parcelable {
}

不过若想正常编译,还需修改模块的编译文件build.gradle,在文件末尾添加下面几行,表示增加安卓插件的编译支持:

//@Parcelize标记需要设置experimental = true
androidExtensions {experimental = true
}

编译文件修改完毕,现在能在Kotlin中使用序列化对象的注解了。虽然自定义的MessageInfo类内部没有任何一行代码,但是它除了具备数据类的所有方法,也自动实现了Parcelable接口的几个方法。接下来就可以利用该类传输活动跳转的序列化数据了,下面是改写后的Kotlin跳转代码:

    val request = MessageInfo(et_request.text.toString(), DateUtil.nowTime)startActivity<ParcelableSecondActivity>("message" to request)

跳转后的下一个页面,调用getParcelable即可正常获得原始的序列化数据,具体的数据解析代码如下所示:

class ParcelableSecondActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_parcelable_second)val request = intent.extras.getParcelable<MessageInfo>("message")tv_response.text = "收到打包好的请求消息:\n请求时间为${request.send_time}\n请求内容为${request.content}"}
}

同样通过测试界面观察序列化对象的打包和解包效果,如下面左图所示,这时第一个页面准备跳转到第二个页面;如下面右图所示,这是跳转后的第二个页面,界面上展示了第一个页面传递过来的序列化数据。

点此查看Kotlin入门教程的完整目录

__________________________________________________________________________
打开微信扫一扫下面的二维码,或者直接搜索公众号“老欧说安卓”添加关注,更快更方便地阅读技术干货。

Kotlin入门(21)活动页面的跳转处理相关推荐

  1. Kotlin入门教程——目录索引

    Kotlin是谷歌官方认可的Android开发语言,即将发布的Android Studio 3.0版本也会开始内置Kotlin,所以未来在App开发中Kotlin取代Java是大势所趋,就像当初And ...

  2. Kotlin入门(23)适配器的进阶表达

    前面在介绍列表视图和网格视图时,它们的适配器代码都存在视图持有者ViewHolder,因为Android对列表类视图提供了回收机制,如果某些列表项在屏幕上看不到了,则系统会自动回收相应的视图对象.随着 ...

  3. 古月居《ROS入门21讲》零基础学习笔记

    文章目录 前言 1.课程简介 2.Linux系统介绍及安装 3.Linux基础操作(操作集) 命令结构 常用命令 快捷操作 4.cpp&python极简基础(操作集) 简单对比 安装编译器 编 ...

  4. kotlin入门学习文档

    kotlin入门学习文档 前言:本文会着重对比java和kotlin,方便Java选手理解 提前总结:kotlin在服务端应用本质上是基于Java进行的改进,底层都是由JVM翻译成底层语言,我们只需要 ...

  5. Kotlin入门(14)继承的那些事儿

    上一篇文章介绍了类对成员的声明方式与使用过程,从而初步了解了类的成员及其运用.不过早在<Kotlin入门(12)类的概貌与构造>中,提到MainActivity继承自AppCompatAc ...

  6. 知识图谱入门2-1:实践——基于医疗知识图谱的问答系统

    注:欢迎关注datawhale:https://datawhale.club/ 系列: 知识图谱入门一:知识图谱介绍 知识图谱入门2-1:实践--基于医疗知识图谱的问答系统 知识图谱入门2-2:用户输 ...

  7. Kotlin入门(5)字符串及其格式化

    上一篇文章介绍了数组的声明和操作,包括字符串数组的用法.注意到Kotlin的字符串类也叫String,那么String在Java和Kotlin中的用法有哪些差异呢?这便是本文所要阐述的内容了. 首先要 ...

  8. Kotlin入门(33)运用扩展属性

    进行App开发的时候,使用震动器要在AndroidManifest.xml中加上如下权限: <!-- 震动 --><uses-permission android:name=&quo ...

  9. Kotlin入门(32)网络接口访问

    手机上的资源毕竟有限,为了获取更丰富的信息,就得到辽阔的互联网大海上冲浪.对于App自身,也要经常与服务器交互,以便获取最新的数据显示到界面上.这个客户端与服务端之间的信息交互,基本使用HTTP协议进 ...

最新文章

  1. 学以致用七---Centos7.2+python3.6.2+django2.1.1 --搭建一个网站(补充)
  2. 两张照片重叠处半透明_手机可以“抛起来”拍照,给你的照片换个角度
  3. vim编辑器----常用命令
  4. [字符编码]Invalid byte 1 of 1-byte UTF-8 sequence终极解决方案
  5. 小学计算机课程表说课稿,小学信息技术《制作课程表》说课稿.doc
  6. utf8 and unicode
  7. 不同特权级间代码段的跳转{ 门 + 跳转(jmp + call) + 返回(ret) }
  8. datagridview 动态插入图片_挑战一张照片制作动态PPT背景
  9. 冯雪 手术机器人的应用_未来达芬奇手术机器人的应用将更为广阔
  10. java返回datatable_(转)在JAVA实现DataTable对象(三)——DataTable对象实现
  11. html签到插件,GitHub - inu1255/soulsign-chrome: 魂签,一款用于自动签到的chrome插件
  12. python版本的适配器模式(对象)
  13. IE-LAB网络实验室:HCNP培训机构 HCIE培训中心 HCIE认证培训 HCNA培训 华为面试考试时需要注意什么
  14. nx零件库插件_3DSource企业自定义零件库插件
  15. 无人机pid调节顺口溜
  16. 野火ISO-V2学习
  17. 前端开发中spa的优缺点_使用单Spa开发和部署微前端
  18. P/O矩阵、R/D矩阵、IPO图、C/U矩阵知识点
  19. android sensor hal,Android Sensor详解(3)porting drvier
  20. redisson 主从模式Unsupported protocol version 50_华米Amazfit Pop智能手表发布:支持50米防水,血氧检测 - 数码 - IT商业网...

热门文章

  1. Leetcode每日一题:424.longest-repeating-character-replacement(替换后的最长重复字符)
  2. ROS入门-6.ROS 命令行工具的使用
  3. 364 页 PyTorch 版《动手学深度学习》分享(全中文,支持 Jupyter 运行)
  4. 数据标记系列——图像分割 Curve-GCN
  5. 出门问问发布企业级场景的智能交互屏TicKasa Show,适用于多种场景...
  6. 译-使用Scroll Snapping实现CSS控制页面滚动
  7. 一阶低通滤波器算法实现
  8. 第二:Git如何将本地项目上传到Github(超详解)
  9. mysql 5.7日志的种类_MySQL中的六种日志类型的介绍
  10. 非对称加密原理及RSA加密步骤