加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

Preventing Back Button Default When Navigating Views in Flex

发布时间:2020-12-15 04:46:31 所属栏目:百科 来源:网络整理
导读:转载:http://swfhead.com/blog/?p=884 Preventing Back Button Default When Navigating Views in Flex Hero Mobile Application Items Covered: ?Flex Hero Views,Hardware Back Button on Android Devices Flex/AIR Version: ?4.5 (Hero),AIR Android 2.5

转载:http://swfhead.com/blog/?p=884


Preventing Back Button Default When Navigating Views in Flex Hero Mobile Application

Items Covered:?Flex Hero Views,Hardware Back Button on Android Devices
Flex/AIR Version:?4.5 (Hero),AIR Android 2.5
Difficulty Level:?Beginner
Prerequisite Knowledge:?How Views work in Flex 4.5 Mobile Application
Sample Application:?ViewNavFix.apk?(I would show this in browser but it is a mobile app,so you’ll need to download and either run it on a device or in Emulator)
Sample Application Files:?ViewNavFix.fxp?(You will need?Flash Builder Burrito)

Desired Interaction:

You want to prevent the hardware BACK button from firing a popView() event when in a View. Maybe this is to bring up a confirmation dialog or perform some other action. Then,go back to the previous view when another button is pressed.

Problem:

Simply using preventDefault() when listening to the Keyboard.BACK down (or up) event does not actually prevent the popView() event. It seems as though there is a bug where NativeApplication still hears when the Keyboard (hardware buttons) are pressed,so your application will always preform the default action when the hardware buttons are pressed. This happens whenever there is not anything on stage in focus.? In addition,the event listeners can not be fully removed from within a view.

Solution:

You must prevent default in the main Application file,as well as within any View. In essence you MUST handle all the hardware keys’ listeners yourself,in every state of the application. You must also have something on stage in focus to prevent the default action of the hardware buttons.

ViewNavFix.mxml

First,I had to preventDefault on the BACK button in the main Application file. This means I will then need to handle the back button interactions. See the code:

[codesyntax lang="actionscript3" lines_start="1"]

<?xml version="1.0" encoding="utf-8"?>
<s:MobileApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
					 xmlns:s="library://ns.adobe.com/flex/spark"
					  applicationComplete="init()"
					 firstView="views.ViewNavFixHome">
	<fx:Declarations>
		<!-- Place non-visual elements (e.g.,services,value objects) here -->
	</fx:Declarations>

	<fx:Script>
		<![CDATA[

			private function init():void
			{
				globalKeyListeners();
			}

			protected function globalKeyListeners():void
			{
				NativeApplication.nativeApplication.addEventListener(KeyboardEvent.KEY_DOWN,handleHardwareKeysDown);
				NativeApplication.nativeApplication.addEventListener(KeyboardEvent.KEY_UP,handleHardwareKeysUp);
			}

			private function handleHardwareKeysDown(e:KeyboardEvent):void
			{
				if(e.keyCode == Keyboard.BACK)
				{
					trace("back button down");
					e.preventDefault();

				}
			}

			private function handleHardwareKeysUp(e:KeyboardEvent):void
			{
				if(e.keyCode == Keyboard.BACK)
				{
					trace("back button up");
					e.preventDefault();

				}
			}

		]]>
	</fx:Script>

</s:MobileApplication>

[/codesyntax]

ViewNavFixHome.mxml

Since I have to handle the Back button my own now in the Home View,I have to preventDefault() and perform my desired action. I am listening for the Back button from NativeApplication to exit(),and pushing to a second View with navigator.pushView();. And since I am doing this I have to add the event listeners on viewActivate(). For some reason the listeners bubble to the previous next view so I have to remove them on viewDeactivate().
[codesyntax lang="actionscript3" lines_start="1"]

<?xml version="1.0" encoding="utf-8"?>
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009"
		xmlns:s="library://ns.adobe.com/flex/spark"
		 viewActivate="homeInit(event)"
		 viewDeactivate="destroyHardwareKeyListeners(event)"
		 title="Home">

	<fx:Script>
		<![CDATA[
			import mx.events.FlexEvent;

			private function homeInit(e:FlexEvent):void
			{
				trace("homeInit");
				enableHardwareKeyListeners();
			}

			private function enableHardwareKeyListeners():void
			{
				NativeApplication.nativeApplication.addEventListener(KeyboardEvent.KEY_DOWN,handleHardwareKeysDown,false,0);
				NativeApplication.nativeApplication.addEventListener(KeyboardEvent.KEY_UP,handleHardwareKeysUp,0);
			}

			private function destroyHardwareKeyListeners(e:FlexEvent):void
			{
				trace("destroyHardwareKeyListeners");
				NativeApplication.nativeApplication.removeEventListener(KeyboardEvent.KEY_DOWN,handleHardwareKeysDown);
				NativeApplication.nativeApplication.removeEventListener(KeyboardEvent.KEY_UP,handleHardwareKeysUp);
			}

			private function handleHardwareKeysDown(e:KeyboardEvent):void
			{
				if(e.keyCode == Keyboard.BACK)
				{
					e.preventDefault();
					NativeApplication.nativeApplication.exit();
				}
			}

			private function handleHardwareKeysUp(e:KeyboardEvent):void
			{
				if(e.keyCode == Keyboard.BACK)
				{
					e.preventDefault();
					NativeApplication.nativeApplication.exit();
				}
			}

			protected function goToNewView(e:MouseEvent):void
			{
				navigator.pushView(SecondView);
			}

		]]>
	</fx:Script>

	<fx:Declarations>
		<!-- Place non-visual elements (e.g.,value objects) here -->
	</fx:Declarations>
	<s:Label left="40" right="40" top="40" height="30" text="To go to a new View,click the button."/>
	<s:Button top="100" width="200" label="GO" click="goToNewView(event)" horizontalCenter="0"/>

</s:View>

SecondView.mxml

So now comes the View where we need to I need to actually block the Back button from popView() to go back to the previous View. This was the biggest pain. Again,I’m adding the event listeners on viewActivate() and removing them on viewDeactivate(). The Back button can now catch the user from leaving the View and goes to a Confirmation state where the user can then either stay in the View to continue working or go back. In order for the Back button to not call popView() something needs to be in focus (preventDefault doesn’t catch it otherwise). So I’m just focusing something,anything,on stage whenever the Initial State is entered.

[codesyntax lang="actionscript3" lines_start="1"]

<?xml version="1.0" encoding="utf-8"?>
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009"
		xmlns:s="library://ns.adobe.com/flex/spark" title="SecondView"
		 viewActivate="secondViewInit(event)"
		viewDeactivate="destroyKeyListeners(event)">

	<fx:Script>
		<![CDATA[
			import mx.events.FlexEvent;

			protected function secondViewInit(e:FlexEvent):void
			{
				trace("secondViewInit");
				enableKeyListeners();
			}

			private function enableKeyListeners():void
			{
				trace("enableKeyListenersInit");
				NativeApplication.nativeApplication.addEventListener(KeyboardEvent.KEY_DOWN,handleHardwareKeysUp);
			}

			private function destroyKeyListeners(e:FlexEvent):void
			{
				trace("destroyKeyListenersInit");
				NativeApplication.nativeApplication.removeEventListener(KeyboardEvent.KEY_DOWN,handleHardwareKeysUp);
			}

			private function handleHardwareKeysDown(e:KeyboardEvent):void
			{
				trace("handleHardwareKeysDown");
				if(e.keyCode == Keyboard.BACK)
				{
					currentState = "ConfirmState";

					e.preventDefault();
				}
			}

			private function handleHardwareKeysUp(e:KeyboardEvent):void
			{
				trace("handleHardwareKeysUpInit");
				if(e.keyCode == Keyboard.BACK)
				{
					currentState = "ConfirmState";

					e.preventDefault();
				}
			}

			// !----- Initial State -----! //
			private function goBackButtonClick(e:MouseEvent):void
			{
				currentState = "ConfirmState";
			}

			private function focusSomething(e:FlexEvent):void
			{
				trace("focusSomethingElse");
				mainLabel.setFocus();

			}

			// !------  ConfirmState -----! //

			private function noButtonClick(e:MouseEvent):void
			{
				trace("noButtonClick");
				currentState = "InitialState";
			}
			private function yesButtonClick(e:MouseEvent):void
			{
				trace("yesButtonClick");
				navigator.popView();
			}

		]]>
	</fx:Script>

	<fx:Declarations>
		<!-- Place non-visual elements (e.g.,value objects) here -->
	</fx:Declarations>

	<s:states>
		<s:State name="InitialState" enterState="focusSomething(event)" />
		<s:State name="ConfirmState" /> <!-- enterState="focusSomethingElse(event)"/> -->
	</s:states>

	<!-- InitialState -->
	<s:Label includeIn="InitialState" id="mainLabel" left="10" right="10" top="40" textAlign="center"
			 text="Try to Hit the Back Button,&#xd;or the button below" />

	<s:Button includeIn="InitialState" id="goBackButton" top="100" label="Go Back" horizontalCenter="0"
			   click="goBackButtonClick(event)" />

	<!-- ConfirmState -->
	<s:Label includeIn="ConfirmState" id="confirmLabel" left="10" right="10" top="40" textAlign="center"
			  text="Are you sure you want to go back?" />

	<s:Button includeIn="ConfirmState" id="noButton" top="100" left="30" width="200" label="STAY"
			  click="noButtonClick(event)" />

	<s:Button includeIn="ConfirmState" id="yesButton" top="100" right="30" width="200" label="LEAVE"
			   click="yesButtonClick(event)"/>

</s:View>

Conclusion:

In order to fully prevent the Back button default action,you MUST fully handle the hardware button yourself. This also gives you the most control over the hardware buttons if you want to do something other than the default action – like bringing up a dialog. While your handling them,you MUST
1. Listen for the Events when the View is activated.
2. Remove the Events when the View is deactivated.
3. Handle the closing of your app appropriately.
4. preventDefault in the main application file AND every subsequent View.

A bit of overkill for something that sounds so simple,sure. But,frankly it was easier than rolling my own ViewNavigator. This is beta software (Flex 4.5 is anyway) so I can’t complain too much,but this should be much easier to do.

Happy Flashing!

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读