Create a simple book layout using the StackLayout

The StackLayout type is useful because of the way it allows you to stack controls on top of each other in the same view. You can hide and show controls to change the user interface of your application. The StackLayout type is often used to implement sliding menus or to display icons or badges on top of existing images (for example, the new mail icon).

The following example uses a StackLayout type to organize a set of chapters in an online book. The online reader uses a list at the left edge of the view to show the chapters in the book. The user can click on the list to open a new chapter in the book.

The complete code sample for this example can be found here, Code sample: Create a simple book layout using the StackLayout

This example uses the following libraries:

import flash.display.Sprite;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.events.Event;
	
	import qnx.fuse.ui.core.Container;
	import qnx.fuse.ui.events.ListEvent;
	import qnx.fuse.ui.layouts.Align;
	import qnx.fuse.ui.layouts.gridLayout.GridData;
	import qnx.fuse.ui.layouts.gridLayout.GridLayout;
	import qnx.fuse.ui.layouts.stackLayout.StackData;
	import qnx.fuse.ui.layouts.stackLayout.StackLayout;
	import qnx.fuse.ui.listClasses.List;
	import qnx.fuse.ui.listClasses.ListSelectionMode;
	import qnx.fuse.ui.text.TextArea;
	import qnx.ui.data.DataProvider;

First, in the StackSample class, create the constructor. The constructor contains a call to the initializeUI() function which contains most of the logic for this example.

public function StackSample()
		{
			super();
			
			// support autoOrients
			stage.align = StageAlign.TOP_LEFT;
			stage.scaleMode = StageScaleMode.NO_SCALE;
			addEventListener(Event.ADDED_TO_STAGE,handleAddedToStage);
			
		}

Next, in the initializeUI() function, create the container and the layout objects. The container, called topContainer, uses a GridLayout layout object called topGrid to organize the top level of the user interface into two columns. The left column contains a list of chapters and the right column contains the main chapter content. When the user clicks an item on the left, the associated content appears in the right pane.

topContainer = new Container();
			topContainer.setActualSize(stage.stageWidth, stage.stageHeight);
			this.addChild(topContainer);

			var topGrid:GridLayout = new GridLayout();
			topContainer.layout = topGrid;
			topGrid.numColumns = 2;			

			var myGridData:GridData = new GridData();
			myGridData.preferredWidth = 300;
			myGridData.vAlign = Align.FILL;

The right pane uses a StackLayout object to organize the chapter content. Remember that the StackLayout type overlaps controls vertically according to z-order. We also create two StackData types. The myTitleStackData object positions the title text, while the myStackData object positions the body text of each chapter.

var myStack:StackLayout = new StackLayout();
			myStack.padding = 25;


			var myTitleStackData:StackData = new StackData();
			myTitleStackData.hAlign = Align.CENTER;
			myTitleStackData.vAlign = Align.CENTER;


			var myStackData:StackData = new StackData();
			myStackData.hAlign = Align.FILL;
			myStackData.vAlign = Align.BEGIN;

Next, we create the list that appears in the left pane. We assign the myGridData object to the list to set the width and position of the list within the left column.

var arrChaps:Array=[];
			arrChaps.push({label: "Title"});
			arrChaps.push({label: "Preface"});
			arrChaps.push({label: "Chapter 1"});
			arrChaps.push({label: "Chapter 2"});
			arrChaps.push({label: "Chapter 3"});
			arrChaps.push({label: "Chapter 4"});

			var chapDP:DataProvider=new DataProvider(arrChaps);	

			var myList:List = new List();
			myList.layoutData = myGridData;
			myList.selectionMode = ListSelectionMode.SINGLE;
			myList.dataProvider = chapDP;
			myList.selectedIndex = 0;
			myList.addEventListener(ListEvent.ITEM_CLICKED, onListClick);
			topContainer.addChild(myList);

			mainContainer = new Container();

Next, we populate the chapter text. In this example, we use TextArea objects to contain the text for each chapter. You should probably consider using resource bundles to provide the text for each chapter.

var myTitle:TextArea = new TextArea();
			myTitle.text = "A simple StackLayout example";
			myTitle.layoutData = myTitleStackData;
			myTitle.alpha = 1;
			myTitle.editable = false;
			myTitle.selectable = false;
			mainContainer.addChild(myTitle);

			var myText:TextArea = new TextArea();
			myText.text = "Mauris ut neque vitae ipsum ullamcorper semper. Nullam" +
				" ornare posuere lobortis. Sed eget risus est, eu sagittis nibh. Nunc" +
				" libero arcu, dictum id laoreet non, consequat vitae augue. " +
				"Sed et torto r id neque interdum elementum non at quam. Vestibulum" +
				" ac magna pharetra nibh faucibus imperdiet quis eget lorem. Duis" +
				" sed mauris a quam pellentesque lobortis in ac metus. Vestibulum ante" +
				" ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;" +
				" Nam id imperdiet ante. Praesent lacus quam, bibendum ac pulvinar a, " +
				"fringilla quis enim. Aliquam ante ligula, sollicitudin vitae egestas sed," +
				" cursus in nibh. Integer lobortis feugiat placerat. Suspendisse ut arcu" +
				" aliquam est hendrerit lacinia. Nulla sodales, diam non auctor mollis, nibh" +
				" erat aliquam diam, nec tristique orci metus eget elit. Suspendisse et neque" +
				" neque, a elementum tellus. ";
			myText.layoutData = myStackData;
			myText.alpha = 0;
			myText.editable = false;
			myText.selectable = false;			

			var myText2:TextArea = new TextArea();
			myText2.text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum" +
				" dignissim " +
				"sapien non eros lacinia vestibulum. Quisque cursus dapibus mollis. Proin mollis" +
				" feugiat metus," +
				" eget rutrum augue euismod vel. Vivamus at blandit justo. Lorem ipsum dolor sit" +
				" amet, consectetur " +
				"adipiscing elit. Nullam dictum justo ut dui iaculis ullamcorper. Curabitur ac" +
				" arcu vel elit dictum " +
				"auctor eget non justo. Nam id diam dictum elit rhoncus condimentum ut et risus." +
				" Fusce felis nibh," +
				" ultrices id sagittis sed, aliquam in nisl.";
			myText2.layoutData = myStackData;
			myText2.alpha = 0;
			myText2.editable = false;
			myText2.selectable = false;

			var myText3:TextArea = new TextArea();
			myText3.text = "Donec tempus viverra nisi at molestie. Sed" +
				" tincidunt blandit risus, posuere elementum" +
				" quam fermentum eget. Morbi vitae libero at erat " +
				"fermentum tempus. Duis scelerisque auctor neque, id" +
				" lacinia leo consequat sed. Nullam accumsan aliquam " +
				"lacus sit amet elementum. Etiam consequat, mauris" +
				" non congue fermentum, arcu elit consectetur nunc, in " +
				"vulputate risus ante non libero. Aenean id sapien" +
				" risus. Curabitur elit arcu, iaculis sit amet semper et, " +
				"tincidunt vel metus. Vivamus tortor odio, " +
				"facilisis vel pharetra et, convallis dictum est. Praesent " +
				"pretium mattis libero et placerat. Aenean" +
				" lobortis hendrerit odio, ut hendrerit justo condimentum a." +
				" Nam ornare, elit ac molestie accumsan," +
				" nunc nisl pulvinar risus, ut bibendum odio nisl vitae sem. " +
				"Vestibulum ut justo vitae mauris ultrices" +
				" vulputate. Quisque viverra, ligula vel placerat sagittis, " +
				"dolor nisi sodales tellus, sit amet mattis" +
				" justo metus eget nibh. ";
			myText3.layoutData = myStackData;
			myText3.alpha = 0;
			myText3.editable = false;
			myText3.selectable = false;

			var myText4:TextArea = new TextArea();
			myText4.text = "Morbi vel odio sem, id iaculis eros. In hac habitasse" +
				" platea dictumst. In egestas, " +
				"arcu et venenatis rutrum, lorem magna dignissim justo, in accumsan" +
				" augue turpis ac purus. Curabitur" +
				" nulla purus, mollis in egestas vel, tempus nec turpis. Nulla imperdiet" +
				" mi at nisi sollicitudin nec " +
				"sodales ligula ultricies. Curabitur non lacus urna. Curabitur aliquet" +
				" turpis nec eros ultrices mattis." +
				" Aenean in elit a est tincidunt rhoncus. Fusce faucibus, augue nec " +
				"blandit tincidunt, libero velit " +
				"fermentum eros, ut luctus metus lorem id ante. ";
			myText4.layoutData = myStackData;
			myText4.alpha = 0;
			myText4.editable = false;
			myText4.selectable = false;

			var myText5:TextArea = new TextArea();
			myText5.text = "Sed rhoncus velit quis urna semper quis pellentesque" +
				" odio viverra. Vestibulum vel " +
				"ligula et orci gravida mollis. Quisque sit amet orci sed urna " +
				"imperdiet feugiat. Vivamus commodo " +
				"imperdiet massa, et scelerisque mi elementum ac. Vestibulum vitae " +
				"felis at massa accumsan blandit. Donec " +
				"eget venenatis nibh. Nulla nisi lorem, mattis ac iaculis vitae, consequat" +
				" vel massa. Cras magna neque, congue" +
				" eu tincidunt sed, consectetur at sapien. ";
			myText5.layoutData = myStackData;
			myText5.alpha = 0;
			myText5.editable = false;
			myText5.selectable = false;


			mainContainer.addChild(myText);
			mainContainer.addChild(myText2);
			mainContainer.addChild(myText3);
			mainContainer.addChild(myText4);
			mainContainer.addChild(myText5);
			mainContainer.layout = myStack;

			topContainer.addChild(mainContainer);

Next, create the logic for displaying the TextArea controls in the right pane. Remember that the right pane uses a StackLayout type so each control that has been added to the pane is stacked on top of each other by z-order. When the user clicks an item in the list, the onListClick() callback function is called, then immediately a call is made to the zeroAll() function. The zeroAll() function sets the alpha value of each control in the container to 0, making each control invisible.

Next, the index of the list entry is trapped and a switch statement is used to set the alpha value of the corresponding TextArea to 1, making it visible.

function onListClick(event:ListEvent):void {

				trace("Item clicked: " + event.data.label);

				zeroAll();
				switch (event.index) {

					case 0:
						trace("Index clicked: " + event.index);
						myTitle.alpha = 1;							
						break;

					case 1:
						trace("Index clicked: " + event.index);
						myText.alpha = 1;							
						break;

					case 2:
						trace("Index clicked: " + event.index);
						myText2.alpha = 1;							
						break;

					case 3:
						trace("Index clicked: " + event.index);
						myText3.alpha = 1;							
						break;

					case 4:
						trace("Index clicked: " + event.index);
						myText4.alpha = 1;							
						break;

					case 5:
						trace("Index clicked: " + event.index);
						myText5.alpha = 1;							
						break;
				}
			}

			function zeroAll():void {

				trace("zeroing all textfield alphas");
				for (var i:int=0; i<mainContainer.numChildren; i++){
					mainContainer.getChildAt(i).alpha = 0;
				}	
			}		
		}
		

		private function onResize(event:Event):void
		{
			trace("ContainerTest.onResize()");
			trace(topContainer.width);
			trace(topContainer.height);
			
			if (stage.stageWidth > stage.stageHeight) {	
				topContainer.setActualSize(stage.stageWidth, stage.stageHeight);						
			}else{
				topContainer.setActualSize(stage.stageWidth, stage.stageHeight);				
			}

		}
		
	}
}

That's all there is to it. This is a very simple example of a StackLayout type that is used in conjunction with a GridLayout type to show and hide controls on the screen.

comments powered by Disqus