原文地址: TornadoFx 页面之间的数据传递 - Stars-One的杂货小窝
(相关资料图)
和Android开发一样,经常遇到两个页面之间需要进行数据的交互传输,本文讲解下TornadoFx框架中,页面之间的数据传递步骤方法
方法1 - 使用构造方法首先,我们知道TornadoFx中,页面可以是View或Fragment,然后View或Fragment对象中提供了对应的打开窗口的方法
比如说
openModal
openWindow
openInternalWindow
3种方法就是窗口模式有些不同,具体说明可以参考此文档3. Components
而我们需要传递数据,最简单的一种方法就是通过构造方法去传,如下面例子
class TestParamView : View("My View") { override val root = vbox { setPrefSize(300.0,300.0) button("跳转页面") { action { TestParamAView(1).openModal() } } }}class TestParamAView(val type:Int) : View() { override val root = vbox { setPrefSize(300.0,300.0) text(type.toString()) }}
效果如下所示:
那么,如果需要页面结束回传数据呢?
这里,TornadoFx默认没有相关方法,我们只能自己改造着实现了
既然我们可以传参,那么,我们也可以将函数回调传入,之后新页面关闭之前回调一下我们的方法即可实现上述要求
假设我们需要新页面返回String类型的数据,具体代码如下:
class TestParamView : View("My View") { override val root = vbox { setPrefSize(300.0, 300.0) button("跳转页面") { action { val closeAction = { s: String -> println("这是返回的数据: $s") } TestParamAView(1, closeAction).openModal() } } }}class TestParamAView(val type: Int, closeAction: (String) -> Unit) : View() { override val root = vbox { setPrefSize(300.0, 300.0) text(type.toString()) button("返回数据") { action { closeAction.invoke("数据11") close() } } }}
效果如下,可以看见控制台也是已经输出了返回的数据
上面流程,我们需要手动在调用close方法前才回调closeAction
,如果想要点击页面右上角关闭而返回的话,应该怎么做?
View和Fragment有对应的生命周期,在onUndock()
方法来实现拦截即可
class TestParamView : View("My View") { override val root = vbox { setPrefSize(300.0, 300.0) button("跳转页面") { action { val closeAction = { s: String -> println("这是返回的数据: $s") } TestParamAView(1, closeAction).openModal() } } }}class TestParamAView(val type: Int, closeAction: (String) -> Unit) : View() { override val root = vbox { setPrefSize(300.0, 300.0) text(type.toString()) button("返回数据") { action { close() } } } override fun onUndock() { super.onUndock() closeAction.invoke("数据11") }}
之后不管是通过代码触发close
方法还是点击页面右上角,最终都会走到onUndock
方法里去
然后剩下的就是逻辑完善了,比如在什么时机传回数据,传回其他类型的数据,各位参考上面思路即可
方法2 - 使用param()方法如果说你的使用情景中,打开的View或Fragment都是固定的一个对象,可以使用TornadoFx框架提供的find
方法来打开页面
find
方法里同时提供了传参使用,如下面例子:
class TestParamView : View("My View") { override val root = vbox { setPrefSize(300.0, 300.0) button("跳转页面") { action { val closeAction = { s: String -> println("这是返回的数据: $s") } find( mapOf( TestParamAView::type to 1, TestParamAView::closeAction to closeAction ) ).openModal() } } }}class TestParamAView() : View() { val type: Int by param() val closeAction: (String) -> Unit by param() override val root = vbox { setPrefSize(300.0, 300.0) text(type.toString()) button("返回数据") { action { close() } } } override fun onUndock() { super.onUndock() closeAction.invoke("数据11") }}
传承需要传递有个map集合,TestParamAView::type
是反射的用法,实际上就是得到结果就是一个字符串type
,直接定义为"type"
也是可行的,因为要相同的key才能注入参数,用反射的用法可以避免写错导致的不匹配问题
而在需要接受参数页面内,通过param
的委托方法来获取数据
如果说你的情景可能参数会传空,可以定义类型为空类型
val type: Int? by param()
之后的返回参数和上面章节一样,不再赘述
关键词: