Kotlin入门(21)活动页面的跳转处理
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.extras
val 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;
// 写数据
@Override
public void writeToParcel(Parcel out, int flags) {
out.writeString(content);
out.writeString(send_time);
}
// 例行公事实现createFromParcel和newArray
public 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];
}
};
@Override
public 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入门(21)活动页面的跳转处理的更多相关文章
- Kotlin入门教程——目录索引
Kotlin是谷歌官方认可的Android开发语言,Android Studio从3.0版本开始就内置了Kotlin,所以未来在App开发中Kotlin取代Java是大势所趋,就像当初Android ...
- 写给Android开发者的Kotlin入门
写给Android开发者的Kotlin入门 转 https://www.jianshu.com/p/bb53cba6c8f4 Google在今年的IO大会上宣布,将Android开发的官方语言更换为K ...
- Kotlin入门第二课:集合操作
测试项目Github地址: KotlinForJava 前文传送: Kotlin入门第一课:从对比Java开始 初次尝试用Kotlin实现Android项目 1. 介绍 作为Kotlin入门的第二课, ...
- Kotlin入门(32)网络接口访问
手机上的资源毕竟有限,为了获取更丰富的信息,就得到辽阔的互联网大海上冲浪.对于App自身,也要经常与服务器交互,以便获取最新的数据显示到界面上.这个客户端与服务端之间的信息交互,基本使用HTTP协议进 ...
- Kotlin入门(23)适配器的进阶表达
前面在介绍列表视图和网格视图时,它们的适配器代码都存在视图持有者ViewHolder,因为Android对列表类视图提供了回收机制,如果某些列表项在屏幕上看不到了,则系统会自动回收相应的视图对象.随着 ...
- Kotlin入门(5)字符串及其格式化
上一篇文章介绍了数组的声明和操作,包括字符串数组的用法.注意到Kotlin的字符串类也叫String,那么String在Java和Kotlin中的用法有哪些差异呢?这便是本文所要阐述的内容了. 首先要 ...
- Kotlin入门(9)函数的基本用法
上一篇文章介绍了Kotlin新增的空安全机制,控制语句部分可算是讲完了,接下来将连续描述Kotlin如何定义和调用函数,本篇文章先介绍函数的基本用法. 前面几篇文章介绍控制语句之时,在setOnCli ...
- Kotlin入门(11)江湖绝技之特殊函数
上一篇文章介绍了Kotlin对函数的输入参数所做的增强之处,其实函数这块Kotlin还有好些重大改进,集中体现在几类特殊函数,比如泛型函数.内联函数.扩展函数.尾递归函数.高阶函数等等,因此本篇文章就 ...
- Kotlin入门(13)类成员的众生相
上一篇文章介绍了类的简单定义及其构造方式,当时为了方便观察演示结果,在示例代码的构造函数中直接调用toast提示方法,但实际开发是不能这么干的.合理的做法是外部访问类的成员属性或者成员方法,从而获得处 ...
随机推荐
- golang IO streaming
IO Streaming Streaming IO in Go,引用此文,略有修改 io.Reader和io.Writer io.Reader接口定义了从传输缓存读取数据 type Reader in ...
- Fiddler修改请求、返回数据
相信你们有听过说“绕过前端”,但是可能想不到要怎样才能绕过前端呢? 首先,我们要知道什么是绕过前端?比如:登录用户名限制数字.6位,用户在登录页面填写用户名符合要求,使用Fiddler作为代理,拦截登 ...
- javascript数组的属性、方法和清空-最全!!!(必看)
今天经理要我从新看一遍js,当我再看<精通js和jquery>这本书时,发现关于数组的这章节讲的很少,于是想自己总结一下数组的常用方法. 定义数组: var arr = new Array ...
- pylot测试工具环境搭建
1.下载Pylot:www.pylot.org/ 2. 安装Python 2.5 + (必须) 3. 安装wxPython(可选 - 用于GUI模式) 4. 安装numpy的(可选 - 用于报告以图表 ...
- mysql 开发基础系列3 日期数据类型
日期类型 如果要用来表示年月日,通常用DATE 来表示. 如果要用来表示年月日时分秒,通常用DATETIME 表示. 如果只用来表示时分秒,通常用TIME 来表示. TIMESTAMP表示格式 :YY ...
- 全能系统监控工具dstat
一.什么是dstat? 通过man帮助,可以看到官方对dstat的定义为:多功能系统资源统计生成工具( versatile tool for generating system resource st ...
- html自适应头
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-sca ...
- python练习七—P2P下载
最近有些事儿比较忙,python的学习就断断续续,这个练习来得比预期的晚,不过还好,不管做什么,我都希望能认真对待,认真做好每一件事. 引入 这个练习原书中称作“使用XML-RPC进行文件共享”,题目 ...
- SpringMVC学习(二)———— 参数绑定
一.参数绑定 1.1.什么是参数绑定? 客户在浏览器端会提交一些参数到服务器端,比如用户的登录等,就会传username 和 password过来,springmvc则通过参数绑定组件将请求参数的内容 ...
- 【转载】阿里云ECS服务器监控资源使用情况
在阿里云Ecs服务器运维过程中,无论是Centos系统还是Windows系统,有时候我们需要监控分析最新的服务器资源利用率等运行情况,例如最近3个小时CPU使用率情况.内存使用率.网络流入带宽.网络流 ...