PageRenderTime 57ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 0ms

/content/as3-madcomponents-tutorial-series-tablet-and-phone-in-one.md

https://gitlab.com/monkmartinez/Caffeine_Industries
Markdown | 314 lines | 256 code | 58 blank | 0 comment | 0 complexity | ce0abcb2e6d7c7547ae5aa662fbd9e44 MD5 | raw file
  1. Title: AS3 MadComponents Tutorial Series - Tablet and Phone in One!
  2. Date: 2011-09-12 11:15
  3. Author: Michael
  4. Category: AS3
  5. Tags: Flash, MadComponents, UI, Tutorial
  6. Slug: as3-madcomponents-tutorial-series-tablet-and-phone-in-one
  7. Status: published
  8. This tutorial will demonstrate both tablet and phone layout in one
  9. ActionScript 3 Flash application for mobile. We will utilize the
  10. powerful [MadComponents library](http://madskool.wordpress.com/) to
  11. quickly and easily add an amazing spilt screen view for the tablet. Then
  12. we will basically recycle the phone tutorial shown in the previous
  13. [separation of concerns tutorial](http://caffeineindustries.com/?p=234).
  14. Tablets such as the iPad and Android variants have quite a bit more
  15. screen real estate to work with. We can literally replicate a desktop
  16. experience with the tablet resolutions we are seeing today. So what
  17. should we do with all of this real estate? The answer to that question
  18. is; It depends. I know that is a bit of a cop-out, but we can not
  19. realistically attempt to cover every situation.
  20. This app will determine the screen resolution and choose the best layout
  21. to initialize. The table will utilize the popular split-view pattern for
  22. the tablet with a list control on the left side and content on the
  23. right. The phone layout consists of list based navigation as shown in
  24. the previous [example.](http://caffeineindustries.com/?p=234)
  25. DISCLAIMER: The colors used are ATROCIOUS. I did this to make absolutely
  26. sure the tutorial-ee can see what colors are used and where. Its a bit
  27. confusing and you'll need to experiment anyway.
  28. The SRC files can be downloaded
  29. [HERE](http://www.mediafire.com/file/d4sbql4o0x44uhd/src.zip).
  30. Lets get this party started:
  31. :::actionscript3
  32. package
  33. {
  34. import com.danielfreeman.madcomponents.*;
  35. import flash.desktop.NativeApplication;
  36. import flash.display.Sprite;
  37. import flash.display.StageAlign;
  38. import flash.display.StageScaleMode;
  39. import flash.events.Event;
  40. import flash.events.KeyboardEvent;
  41. import flash.events.MouseEvent;
  42. import flash.system.Capabilities;
  43. import flash.ui.Keyboard;
  44. public class SplitViewMAD extends Sprite
  45. {
  46. //////////////////////////// DATA FOR BOTH APPLICATIONS ////////////////////////////
  47. protected static const DATA:XML =
  48. ;
  49. //////////////////////////// END DATA //////////////////////////////////////////////
  50. /////////////////////////// TABLET XML DEFINITION //////////////////////////////////
  51. // List can also be masked for a wrapping effect
  52. protected static const SPLITVIEW:XML =
  53. {DATA}
  54. {Page0.LAYOUT}{Page1.LAYOUT1}{Page2.LAYOUT2}{Page3.LAYOUT3}
  55. ;
  56. protected var _page:UIPages;
  57. /////////////////////////// END TABLET ///////////////////////////////////////////////
  58. /////////////////////////// PHONE XML DEFINITIONS ///////////////////////////////////
  59. protected static const LIST:XML = {DATA};
  60. // Each additional "Page" needs to have different id's for the components, even when they are separated into separate classes
  61. protected static const NAVIGATION:XML =
  62. {LIST}
  63. {Page0.LAYOUT}
  64. {Page1.LAYOUT1}
  65. {Page2.LAYOUT2}
  66. {Page3.LAYOUT3}
  67. ;
  68. protected var _uiNavigation:UINavigation;
  69. protected var _list:UIList;
  70. ////////////////////////////// END PHONE //////////////////////////////////////////////
  71. ///////////////////////////// INDEPENDENT CLASS VARS //////////////////////////////////
  72. protected var _resY:int = Capabilities.screenResolutionX;
  73. protected var _resX:int = Capabilities.screenResolutionY;
  74. protected var _dpi:int = Capabilities.screenDPI;
  75. ///////////////////////////// END CLASS VARS //////////////////////////////////////////
  76. ```
  77. The comments should visually separate the XML. The order in which you
  78. define this data is absolutely inconsequential.
  79. The DATA constant is used for both layouts. I'm quite sure there are a
  80. myriad of optimizations you could make here, but I wanted to make this
  81. as clear as possible for the uninitiated.
  82. Lets concentrate on the SPLITVIEW constant for a bit. The root node or
  83. tag is **columns**. We can use any numbers we like here. 36% for the
  84. left column and 64% for the right looked good on my Galaxy Tab 10.1
  85. Android tablet.
  86. After columns, you'll see the <vertical> node and it is the container
  87. for the left column. I choose to define the list here. You can get
  88. really creative and add images and/or other components in this column.
  89. The main thing to consider is text wrapping. If you aren't careful or
  90. have long labels, the text will spill onto the next column. In this
  91. case, I set **autoLayout = true** in the list node. Then we define the
  92. actual label node contained in the DATA constant with this tag; &lt;
  93. label id="label" alignH="fill" /&gt;. This will make your text wrap nice
  94. and neat.
  95. The right column is defined in the &lt; pages &gt; node. This, again,
  96. can be any node you'd like for your particular application but page
  97. worked well for this example. Note that we once again defined our pages
  98. outside this class and call them by their LAYOUT constant, then
  99. initialize them in a later method. You don't need to specify LAYOUT
  100. followed by a number, as LAYOUT or any other name will work just as
  101. well. I do that because, again, my brain works best with everything
  102. separated as cleanly as possible.
  103. The independent class vars grab the screen resolution in the X and Y
  104. axis and also provide the screen DPI. This will enable us to make the
  105. right decision on which layout we like to display.
  106. Lets move onto the constructor:
  107. :::actionscript3
  108. //////////////////////////// CONSTRUCTOR /////////////////////////////////////////////
  109. public function SplitViewMAD(screen:Sprite = null) {
  110. if (screen){
  111. screen.addChild(this);
  112. }
  113. trace("Screen Resolution is " + _resX + "x" + _resY + " at " + _dpi + "ppi");
  114. // support autoOrients
  115. stage.align = StageAlign.TOP_LEFT;
  116. stage.scaleMode = StageScaleMode.NO_SCALE;
  117. // If the screen in the Y-axis is larger than 855px init tablet layout
  118. if(_resY >= 855){
  119. initializeTablet();
  120. }
  121. // If the screen in the Y-axis is smaller than 855px init Phone layout
  122. if(_resY <= 855){
  123. //Register the back button listener in constructor before UI.create and all is well
  124. stage.addEventListener(KeyboardEvent.KEY_DOWN, goBackButton);
  125. initializePhone();
  126. }
  127. }
  128. ```
  129. This constructor simply chooses to initialize the phone or tablet based
  130. on the resolution in the Y-axis. The number I decided to use for a break
  131. over is 855px because I'm testing on the OG Droid-1 (480x854) and a
  132. Galaxy 10.1 tablet (800 x 1290). I needed a way to make sure that the
  133. proper layout is initializing (you know, that it actually works). A more
  134. robust switch statement or if/else block is absolutely more appropriate
  135. in a real world scenario based on the devices one is targeting.
  136. The only gotcha here is the physical Android back button in the
  137. initializePhone block. The physical Android back button listener needs
  138. to be called before UI.create, which is in the initializePhone method,
  139. to work properly.
  140. In the interest of keeping all the logic available to copy and paste
  141. here is the phone logic. Note: its not materially different than the
  142. [previous tutorial](http://caffeineindustries.com/?p=234).
  143. :::actionscript3
  144. ////////////////////// PHONE ////////////////////////
  145. private function initializePhone():void
  146. {
  147. // Create the main UI or "Landing Page"
  148. UI.create(this, NAVIGATION);
  149. // Initialize "views"
  150. // Initialize "views"
  151. Page0.initialize();
  152. Page1.initialize();
  153. Page2.initialize();
  154. Page3.initialize();
  155. // Navigation layout and behaviour
  156. _uiNavigation = UINavigation(UI.findViewById("nav"));
  157. _uiNavigation.autoForward = false;
  158. _uiNavigation.autoBack = false;
  159. // Change page handler
  160. _uiNavigation.addEventListener(UIList.CLICKED, navigationChange);
  161. _uiNavigation.navigationBar.backButton.addEventListener(MouseEvent.MOUSE_UP, goBack);
  162. // Nav back button color
  163. _uiNavigation.navigationBar.backButton.colour = 999999;
  164. }
  165. // Handles List item clicks
  166. public function navigationChange(event:Event):void {
  167. var navIndex:int = _uiNavigation.index;
  168. // Check to see if current page is @ 0 to set correct title
  169. if(_uiNavigation.pages[0]){
  170. _uiNavigation.title = "Phone Nav";
  171. }
  172. // navigation logic
  173. if(navIndex == 0){
  174. _uiNavigation.goToPage(2, UIPages.SLIDE_LEFT);
  175. _uiNavigation.title = "Page 1";
  176. } else if (navIndex == 1){
  177. _uiNavigation.goToPage(3, UIPages.SLIDE_LEFT);
  178. _uiNavigation.title = "Page 2";
  179. }else if (navIndex == 2){
  180. _uiNavigation.goToPage(4, UIPages.SLIDE_LEFT);
  181. _uiNavigation.title = "Page 3";
  182. }
  183. }
  184. // Nav bar back button
  185. protected function goBack(event:Event):void {
  186. var navIndex:int = _uiNavigation.index;
  187. _uiNavigation.goToPage(0, UIPages.SLIDE_RIGHT);
  188. _uiNavigation.title = "Phone Nav";
  189. trace("NavBar Event fired");
  190. }
  191. // Device back button handler
  192. protected function goBackButton(event:KeyboardEvent):void
  193. {
  194. // With autoBack set to false, you lose the back button for some reason
  195. // You can use the Native App library to hard check a back button press
  196. var navIndex:int = _uiNavigation.index;
  197. if(event.keyCode == Keyboard.BACK){
  198. _uiNavigation.goToPage(0, UIPages.SLIDE_RIGHT);
  199. _uiNavigation.title = "Phone Nav";
  200. trace("Keyboard event fired");
  201. }
  202. }
  203. //////////////////////// END PHONE /////////////////////////////
  204. ```
  205. Next we'll look at the tablet specific code:
  206. :::actionscript3
  207. /////////////////////// TABLET ////////////////////////////////
  208. private function initializeTablet():void
  209. {
  210. // Create the main UI or "Landing Page"
  211. UI.create(this, SPLITVIEW);
  212. // Initialize "views"
  213. Page0.initialize();
  214. Page1.initialize();
  215. Page2.initialize();
  216. Page3.initialize();
  217. // Add the list
  218. _list = UIList(UI.findViewById("myList"));
  219. _list.addEventListener(UIList.CLICKED, changePage);
  220. // Add the pages component
  221. _page = UIPages(UI.findViewById("myPages"));
  222. }
  223. protected function changePage(event:Event):void
  224. {
  225. // TODO: holder page @ index 0 in DATA constant so first page is 1 and second is two. Holder will have a cool logo or something
  226. var index:int = _list.index;
  227. // Navigation logic
  228. if(index == 0){
  229. _page.goToPage(1,UIPages.SLIDE_RIGHT);
  230. } else
  231. if (index == 1){
  232. _page.goToPage(2,UIPages.SLIDE_RIGHT);
  233. } else
  234. if (index == 2){
  235. _page.goToPage(3,UIPages.SLIDE_RIGHT);
  236. }
  237. }
  238. ////////////////////// END TABLET ////////////////////////////////
  239. }
  240. }
  241. ```
  242. We call UI.create and pass in the SPLITVIEW constant. This is the
  243. MadComponents standard, so if don't get it... I suggest you to have a go
  244. with the other tutorials on [Daniels](http://madskool.wordpress.com/)
  245. site or mine. Next, we initialize all the pages that reside outside of
  246. this class, but are defined in the pages node.
  247. We need a way to capture the clicks for the list on the left. So we
  248. instantiate a UIList variable to hold the list data. We then assign a
  249. click listener to the list variable. We also need a mechanism to
  250. navigate the pages once we've determined which list item has been
  251. clicked. So, again we assign a UIPages variable to hold and act on that
  252. data. This is all handled in the changePage event handler which is
  253. relatively self explanatory. I'm still working on the Android back
  254. button for this block. I will update it once I get it handled.
  255. I hope this helps you visualize what is possible with tablets and the
  256. ActionScript3 MadComponent Library. Expect more tutorials to follow!