事件与回调
事件在轻舟中表示外部(用户)对程序内某个组件或对象产生动作的描述;例如:用户点击了按钮、用户打开窗口、窗口加载完毕等等;因此事件也是一种编程机制,它允许我们(开发者)监听用户的操作和行为并同时对组件产生的变化做出响应;在安卓中支持以下方式对不同类型事件进行监听并执行相关操作:
-
普通组件事件
-
子程序引用
-
监听多个事件回调
-
跨窗口传递事件
-
自定义事件
普通组件事件
针对窗口中的可视与不可视组件、轻舟支持像 VB、C# 那样通过面向过程的方式、采用事件驱动向开发者回调事件、这种事件回调方式简单易懂、也是初学者相对使用最多、最容易让人理解的一种、但这种事件一般只适合处理单一事件的回调。
代码示例:
'仅当窗口中的按钮1被用户点击后、触发该事件、参数被单击对象为按钮1
事件 按钮1.被单击(被单击对象 为 视图)
结束 事件
'自定义组件的对象、当我们在窗口代码里面自定义一个按钮组件时、添加其单击事件
变量 按钮A 为 按钮
事件 窗口创建完毕()
按钮A = 创建 按钮()
'将组件添加到窗口中
添加组件(按钮A)
结束 事件
'选中 按钮A 变量名称然后右键菜单、添加组件事件、即可自动生成该事件代码
事件 按钮A.被单击(被单击对象 为 视图)
'当按钮A被单击时触发该事件
结束 事件
子程序引用
熟悉 C 或 C++ 的朋友应该都知道指针、通过指针我们可以直接取出、或者传递一个函数的地址、简单的来说、即可以把函数当作参数传递给其他函数调用、这在实际编程开发工作中往往会非常方便、轻舟也借鉴了这一思想、在开发中、尤其是对非组件事件的回调、支持直接用 "&加上函数名" 即可把待操作的函数当作参数传递给方法、这种方式对待调用的函数自由度相对较高、无需特定函数名、但需要保证参数名与所需函数一致、且函数不可有返回值的场景、常用于为不可视组件对非组件对象添加事件回调、例如启动线程、或设置自定义回调。
代码示例:
'启动线程调用一个子程序、让子程序在线程中执行
事件 按钮1.被单击()
启动线程(&获取网页源码)
结束 事件
' 该函数将会在子线程中执行
函数 获取网页源码()
变量 结果 为 文本型
结果 = 取网页源码("http://www.baidu.com","UTF-8",5000)
'注意这里取回的结果仍然是在子线程中、不能直接修改界面内容
调试输出(结果)
结束 函数
'除了调用子程序外、还可以给组件设置回调事件、这里动态创建10个按钮并设置其当按钮被单击时的回调事件
函数 按钮1.被单击()
变量 i 为 整数型
计次循环(10,i)
变量 btn 为 按钮
btn = 创建 按钮()
btn.标题 = "按钮" + i
btn.置被单击回调(&按钮被单击回调)
垂直滚动框1.添加组件(btn)
结束 循环
结束 函数
函数 按钮被单击回调(来源对象 为 视图)
'这里返回的参数视图则为被单击的按钮、如果需要使用按钮需要强制转成按钮类型
变量 被点击按钮 为 按钮 = (按钮)来源对象
弹出提示(被点击按钮.标题)
结束 函数
使用“&”符号引用的子程序函数的参数类型和格式、可以在IDE支持库中查询指定组件接口中的事件、例如:上方我们给动态创建的按钮设置的 被单击回调 子程序函数、这个函数是我们自定义的、但是这个函数中具体的参数、则可以在IDE支持库窗口中找到按钮组件、再找到按钮节点下的“被单击回调”接口、这个接口中的参数即是我们需要设置的参数。
监听多个事件回调
使用普通事件及子程序引用的方式、都只能实现对单个组件添加处理回调事件、如果遇到需要同时监听多个回调事件的情况时、则需要使用事件回调接口来处理、例如:当我们向服务器发送一个网络请求时、请求结果有可能是失败的、也有可能发生错误、此时如果使用单一事件回调、则无法同时处理请求成功、请求失败、或者请求错误的情况、如果使用回调接口、则可以很方便同时处理。
代码示例:
事件 按钮1.被单击()
变量 异步请求1 = 创建 异步网络操作()
'task1 为请求的标记
异步请求1.发送POST请求链("task1","http://www.vcnstudio.com/post","id=1&name=vcn","UTF-8",5000)
异步网络1.置请求回调(异步请求回调1)
结束 事件
定义 异步操作回调 为 异步网络操作.请求完毕回调
事件 请求发送成功(标记 为 文本型,响应头 为 哈希表,返回数据 为 字节型[])
变量 结果 = 字节集到文本(返回数据,"UTF-8")
标签1.标题 = $"请求标记:{标记} 请求发送成功;返回数据为:\n{结果}"
结束 事件
事件 请求发送失败(标记 为 文本型,响应头 为 哈希表,返回数据 为 字节型[],错误信息 为 文本型)
标签1.标题 = $"请求标记:{标记} 请求发送失败;错误信息:{错误信息}"
结束 事件
结束 定义
跨窗口传递事件
在实际开发时、除了组件自己的回调事件外;在程序中也可能遇到自身事件回调的场景、例如:跨窗口传递数据、在窗口中接收模块返回的数据等;在遇到这种需求时、则可以通过事件消息来完成;以下为代码演示在窗口中接收模块返回的数据;代码应用场景:在模块中完成一系列耗时操作、获得数据后、将结果发送给窗口;然后显示结果。
窗口代码:
事件 窗口创建完毕()
' 使用系统函数注册接收消息的子函数
接收事件消息(&接收模块消息)
结束 事件
函数 接收模块消息(消息ID 为 整数型,消息值 为 对象)
如果(消息ID == 1)
标签1.标题 = "我是模块1发过来的消息;消息值为:" + 到文本(消息值)
否则 如果(消息ID == 2)
标签1.标题 = "我是模块2发过来的消息;消息值为:" + 到文本(消息值)
结束 如果
结束 函数
事件 按钮2.被单击(来源对象 为 视图)
模块2.获取网页源码("http://www.vcnstudio.com")
结束 事件
模块代码:
' 模拟耗时操作获取网页源码后;发送结果到主窗口
函数 静态 获取网页源码(地址 为 文本型)
异步执行
变量 源码 = 取网页源码(地址,"UTF-8",5000)
' 事件消息的发送与接收都必须在主线程中操作
到主线程
发送事件消息(2,源码)
结束 异步执行
结束 函数
自定义事件
自定义事件一般多用于在封装自定义组件时使用;例如:在项目中直接封装自定义组件;且需要向外传递组件的回调事件时;则需要自定义回调事件;在轻舟中为自定义组件定义回调事件非常简单;只需要一行代码即可完成:
公开 事件 事件名称(参数 为 文本型)
例如:我们在一个自定义搜索框组件中定义了一个”搜索被触发“事件
公开 事件 搜索被触发(关键字 为 文本型)
在窗口中使用:
搜索框1.置搜索被触发回调((关键字)->{
弹出提示(关键字)
})