事件是 Corona 交互式应用程序的基础。它们用于触发应用程序中的响应,例如屏幕点击、特定系统事件的检测、计时器的完成、两个物理实体的碰撞等。事件使用 object:addEventListener() 方法检测,该方法指示 Corona 在监听器函数中跟踪(监听)关联的事件。有关详细信息,请参阅注册事件部分。
运行时事件被分派到全局运行时监听器。这些事件并非针对任何特定对象;而是广播给所有感兴趣的监听器。常见的运行时事件包括以下内容:
enterFrame
事件(文档)以应用程序的
lateUpdate
事件(文档)以应用程序的enterFrame
事件之后,渲染过程之前。
system
事件(文档)在某些外部事件发生时分派,例如设备暂停或退出应用程序时。
resize
事件(文档)在应用程序视图的宽度或高度发生更改时发生。
orientation
事件(文档)在设备方向从纵向更改为横向或
windowState
事件(文档)在应用程序窗口被发送到后台或再次激活时发生(仅限 Win32 和 macOS)。
以下代码显示了应用程序如何响应 system
事件。
local function onSystemEvent( event ) local eventType = event.type if ( eventType == "applicationStart" ) then -- Occurs when the application is launched and all code in "main.lua" is executed elseif ( eventType == "applicationExit" ) then -- Occurs when the user or OS task manager quits the application elseif ( eventType == "applicationSuspend" ) then -- Perform all necessary actions for when the device suspends the application, i.e. during a phone call elseif ( eventType == "applicationResume" ) then -- Perform all necessary actions for when the app resumes from a suspended state elseif ( eventType == "applicationOpen" ) then -- Occurs when the application is asked to open a URL resource (Android and iOS only) end end Runtime:addEventListener( "system", onSystemEvent )
局部事件通常发送到单个监听器,并且不会广播到全局运行时。常见的局部事件包括以下内容:
tap
和 touch
事件在用户触摸设备屏幕时发生。有关更多信息,请参阅点击/触摸/多点触控指南。
timer
事件在运行的计时器完成其持续时间时发生。
监听器可以是函数或表/显示对象。
当调用函数监听器时,会向其传递一个表示事件的表。
local myListener = function( event ) print( "Listener called with event of type: " .. event.name ) end Runtime:addEventListener( "touch", myListener ) Runtime:addEventListener( "enterFrame", myListener )
有时,函数监听器并不方便,因为在调用监听器时某些变量不在作用域内。在这种情况下,应使用表监听器。表监听器必须具有一个与事件名称对应的实例方法。
-- Assumes "myClass" and "myClass:new()" already exist function myClass:enterFrame( event ) print( "enterFrame called at time: " .. event.time ) end function myClass:touch( event ) print( "touch occurred at: " .. event.x .. "," .. event.y ) end local myObject = myClass:new() Runtime:addEventListener( "touch", myObject ) Runtime:addEventListener( "enterFrame", myObject )
如上例所示,事件被分派到作为基本函数编写的事件监听器。始终会向函数分派一个 event
参数。
local function myTouchListener( event ) print( "Touch X location" .. event.x ) print( "Touch Y location" .. event.y ) end local myButton = display.newRect( 100, 100, 200, 50 ) myButton:addEventListener( "touch", myTouchListener )
请注意,传递给 myTouchListener
函数的 event
参数包含表示触摸发生屏幕位置的 x
和 y
属性。与 event
参数关联的属性对于每种事件类型都是唯一的 — 有关详细信息,请参阅事件 API 文档。
可以使用 object:addEventListener() 方法注册事件。只需传递事件类型的字符串名称和应处理它的事件监听器函数的名称即可。
-- Standard touch listener on an object myButton:addEventListener( "touch", myTouchListener ) -- Runtime "system" event listener Runtime:addEventListener( "system", onSystemEvent )
如上所示,可以使用 object:addEventListener()
方法创建两种类型的事件监听器:附加到显示对象的监听器和附加到全局运行时的监听器。
创建显示对象并向其添加局部触摸事件监听器时,实际上是通过引用该函数来指向一段代码块。这段代码驻留在其自己的内存中,并在显示对象被移除后仍然存在。发生这种情况时,无法感知对象上的未来事件,因此实际上会为您移除局部事件监听器。您无需显式移除它。
另一方面,运行时事件监听器在使用完毕后必须移除。否则,它们将继续运行,因为运行时事件是全局的。这不仅会导致内存泄漏,而且如果在运行时中执行的任何函数尝试引用不再存在的对象,程序将会崩溃。有关更多信息,请参阅下面的移除事件监听器。
大多数监听器(运行时监听器(如 "enterFrame"
)除外)会在关联对象被移除时自动移除,例如,当您调用 object:removeSelf() 或 display.remove() 时。但是,您可能需要在不移除对象的情况下显式移除事件监听器。
移除事件监听器是使用
调用此函数的方式与 object:addEventListener()
完全相同。例如,如果您想停止监听 myButton
对象上的触摸事件,请按如下方式移除监听器:
myButton:removeEventListener( "touch", myTouchListener )
移除关联的监听器需要类型和函数名称,因为可以将同一类型的多个监听器分配给单个对象。例如,您可以将两个(或更多)不同的监听器函数分配给 myButton
显示对象的 "touch"
事件。因此,在调用 object:removeEventListener()
时,您需要指定要停止监听的事件类型,以及先前分配给该事件的监听器函数。