Searched in the forums and online but can’t get this working, can someone help?
I have a multi screen app that uses Director. I want the hardware back button on Android devices to function as expected - i.e. from the home_screen if a button opens a new module (screen2) then pressing back should take you back to home_screen. But if on the home_screen, the back button should exit the app.
I’ve read that I need to scope my hardwareKeyEvent listener to outside of each Director scene so here’s what I’ve tried:
main.lua (which scopes onHardwareKeyEvent as a global table)
local director = require("director") local mainGroup = display.newGroup() --====================================================================-- -- GLOBAL -- handle to scope hardwareKeyEvent listeners outside of each Director scene local onHardwareKeyEvent = {} --====================================================================-- -- MAIN FUNCTION local main = function () mainGroup:insert(director.directorView) director:changeScene("home\_screen") return true end --====================================================================-- -- BEGIN --====================================================================-- main()
home_screen.lua (which then defines as a function which returns the default key operation:
onHardwareKeyEvent = function( event )
return false – use default key operation
end
module(…, package.seeall)
–====================================================================–
– SCENE: Home Screen
–====================================================================–
new = function ( params )
------------------
– Constants
------------------
BTN_LABEL = “Open Screen”
------------------
– Imports
------------------
--import the ui library for buttons
local ui = require ( “ui” )
--import the widgets library for buttons
local widget = require ( “widget” )
------------------
– Groups
------------------
local localGroup = display.newGroup()
--====================================================================–
– BUTTONS
--====================================================================–
local function onButtonEvent( event )
local btn = event.target
if event.phase == “ended” then
if btn.id == “button1” then
director:changeScene( { content=“Hello” } , “screen2”, “fade” )
end
end
end
local button1 = widget.newButton{
id = “button1”,
defaultFile = “images/ui/button.png”,
overFile = “images/ui/button_over.png”,
width = 200,
height = 41,
onEvent = onButtonEvent,
label = BTN_LABEL,
font = native.systemFontBold,
fontSize = 16,
labelColor = { default={ 205 }, over={ 105 }}
}
--====================================================================–
– INITIALIZE
--====================================================================–
local initVars = function ()
------------------
– Inserts
------------------
localGroup:insert( button1 )
------------------
– Positions
------------------
button1.x = display.contentCenterX
button1.y = display.contentCenterY+50
------------------
– Listeners
------------------
– hardware key callback
local resetHardwareKeyListeners = function()
onHardwareKeyEvent = function( event )
return false – use default key operation
end
end
Runtime:removeEventListener( “key”, onHardwareKeyEvent )
resetHardwareKeyListeners()
Runtime:addEventListener( “key”, onHardwareKeyEvent )
end – end initVars() function
------------------
– Initiate variables
------------------
initVars()
------------------
– MUST return a display.newGroup()
------------------
return localGroup
end
screen2.lua (which then attempts to ‘reset’ the onHardwareKeyEvent function)
module(…, package.seeall)
–====================================================================–
– SCENE: SCREEN 2
–====================================================================–
new = function ( params )
------------------
– Imports
------------------
local ui = require(“ui”)
local widget = require “widget”
------------------
– Params
------------------
local vContent = “no content”
if type( params ) == “table” then
if type( params.content ) == “string” then
vContent = params.content
end
end
------------------
– Groups
------------------
local localGroup = display.newGroup()
------------------
– Display Objects
------------------
local background = display.newRect(0, 0, display.contentWidth, display.contentHeight)
local contentText = display.newText( vContent, 0, 0, native.systemFontBold, 16 )
--Setup the back button
local function handleBackButtonEvent( event )
print()
print(“pressed back”)
director:changeScene( “home_screen”, “moveFromLeft” )
end
local backBtn = widget.newButton{
id = “backBtn”,
defaultFile = “images/ui/backButton.png”,
overFile = “images/ui/backButton_over.png”,
width = 60,
height = 34,
onRelease = handleBackButtonEvent,
label = " Home",
font = native.systemFontBold,
fontSize = 12,
labelColor = { default={ 205 }, over={ 105 }}
}
------------------
– Listener
------------------
local doSlide = function ( event )
if event.phase == “ended” then
if event.xStart >= event.x then
director:changeScene( “home_screen”, “moveFromRight” )
else
director:changeScene( “home_screen”, “moveFromLeft” )
end
end
end
--====================================================================–
– INITIALIZE
--====================================================================–
local initVars = function ()
------------------
– Inserts
------------------
localGroup:insert( background )
localGroup:insert( contentText )
localGroup:insert( backBtn )
------------------
– Positions
------------------
--initial values
local screenOffsetW, screenOffsetH = display.contentWidth - display.viewableContentWidth, display.contentHeight - display.viewableContentHeight
contentText.x = 160
contentText.y = 240
backBtn.x = math.floor(backBtn.width/2) + screenOffsetW
backBtn.y = math.floor(display.screenOriginY + 20)
------------------
– Colors
------------------
contentText:setTextColor( 255,255,255 )
background:setFillColor(77, 77, 77)
------------------
– Listeners
------------------
– Key listener for hardware keys (android)
local resetHardwareKeyListeners = function()
onHardwareKeyEvent = function( event )
local returnValue = false – use default key operation
local phase = event.phase
local keyName = event.keyName
if ( phase == “up” and keyName==“back” ) then
director:changeScene( “home_screen”, “moveFromLeft” )
returnValue = true – disable default key operation
end
return returnValue
end
end
Runtime:removeEventListener( “key”, onHardwareKeyEvent )
resetHardwareKeyListeners()
Runtime:addEventListener( “key”, onHardwareKeyEvent )
background:addEventListener( “touch” , doSlide )
end
------------------
– Initiate variables
------------------
initVars()
------------------
– MUST return a display.newGroup()
------------------
return localGroup
end
Unfortunately this doesn’t work. On loading the app, on the first screen the back button works as expected - it quits the app. But if you load the app > goto screen2, and press the back button (which takes you back to home_screen), the back button then continues to return to ‘home_screen’ - it never exits.
I just can’t remove the event listener or ‘reset’ the function that the hardware key listener is calling…
Any help much appreciated!
(attached is full test code)