Welcome!

Welcome to the official BlackBerry Support Community Forums.

This is your resource to discuss support topics with your peers, and learn from each other.

inside custom component

Adobe AIR Development

Reply
Highlighted
Contributor
Posts: 42
Registered: ‎03-01-2011
My Device: Not Specified

Using the TileList component

Hi all,

 

To follow up a previous post about building an image gallery I have some questions about the TileList component.

 

I've uploaded a quick mockup of what I am trying to achieve, I want to dynamically load images into a TileList and as the user scrolls through the list I want to call another 'page' of images dynamically. I have produced an example which uses a custom cell renderer to dynamically load images but I am having problems when I attempt to identify when the user has reached the end of the list.

 

I have tried using the lastVisibleItem property of the list while the user is scrolling to identify if the last item visible in the list is also last in the DataProvider (so I know I need to call for more images) but when I add images to the DataProvider it takes me back to the start of the list, can anyone tell me the reason for this?

 

Does anyone else know of a better solution? Maybe a Flex only solution or another approach with QNX components?

 

PlayBookMock.jpg

BlackBerry Development Advisor
Posts: 172
Registered: ‎10-25-2010
My Device: Not Specified

Re: Using the TileList component

Here is something that I came up with that may work ok in your situation. You don't get super smooth scrolling but the scroll position will not reset on you. Because my items are not loaded, this may work better for you as there will be a little delay in retrieving the items.

 

You might want to also throw a footer view on the list that shows that more items are loading. it might be a little tricky to get super smooth scrolling to occur because you are at the end of the list and that is where the bounce is applied. If items are added to the list during the bounce chances are it is going to snap the list into place quickly.

 

 

 

 

 

 

package
{
	import flash.display.Sprite;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.events.Event;
	import flash.events.MouseEvent;
	
	import qnx.ui.buttons.Button;
	import qnx.ui.data.DataProvider;
	import qnx.ui.events.ScrollEvent;
	import qnx.ui.listClasses.TileList;
	import qnx.ui.theme.ThemeGlobals;
	
	public class listpaging extends Sprite
	{
		
		private var dataProvider:DataProvider;
		private var list:TileList;
		
		private var currentIndex:int = 0;
		
		public function listpaging()
		{
			super();
			
			ThemeGlobals.currentTheme = ThemeGlobals.BLACK;
			
			// support autoOrients
			stage.align = StageAlign.TOP_LEFT;
			stage.scaleMode = StageScaleMode.NO_SCALE;
			
			dataProvider = new DataProvider();
			
			for( var i:int = 0; i<400; i++ )
			{
				dataProvider.addItem( {label:"" + i} );
			}
			
			
			list = new TileList();
			list.columnCount = 2;
			list.width = 330;
			list.height = 400;
			//list.addEventListener( ScrollEvent.SCROLL_MOVE, onScroll );
			list.addEventListener( ScrollEvent.SCROLL_END, onScrollEnd );
			list.addEventListener( ScrollEvent.SCROLL_BEGIN, onScrollBegin );
			addChild( list );
			addNextPage();
			
			var btn:Button = new Button();
			btn.x = 400;
			addChild( btn );

			btn.addEventListener( MouseEvent.CLICK, onClick );
			
		}
		
		protected function onScrollBegin(event:ScrollEvent):void
		{
			if( list.lastVisibleItem.index != list.dataProvider.length - 1 )
			{
				addEventListener( Event.ENTER_FRAME, onFrame );
			}
		}
		
		protected function onScrollEnd(event:ScrollEvent):void
		{
			removeEventListener( Event.ENTER_FRAME, onFrame );
		}
		
		protected function onFrame(event:Event):void
		{
			if( list.lastVisibleItem.data == list.dataProvider.getItemAt( list.dataProvider.length - 1 ) )
			{
				addNextPage();
			}
		}
		
		protected function onScroll(event:ScrollEvent):void
		{
			if( list.lastVisibleItem.data == list.dataProvider.getItemAt( list.dataProvider.length - 1 ) )
			{
				addNextPage();
			}
		}
		
		protected function onClick(event:Event):void
		{
			addNextPage();
		}
		
		private function addNextPage():void
		{
			trace( "adding items" );
			var len:int = Math.min( currentIndex + 10, dataProvider.length );
			
			for( var i:int = currentIndex; i<len; i++ )
			{
				list.addItem( dataProvider.getItemAt( i ) );
			}
			
			currentIndex = i;
		}
		
		
	}
}

 

Contributor
Posts: 42
Registered: ‎03-01-2011
My Device: Not Specified

Re: Using the TileList component

[ Edited ]

Hi Julian,

 

Thanks for taking the time to put this together, so looking at this I need to avoid ever using a dataprovider to set the items in the List, instead I populate the dataprovider and then loop through it and use List.addItem() instead?

 

So when I am using your example I would call for dynamic data (see code below ) in the addNextPage method to populate the data provider, then loop through the newly added items in the data provider and add them using List.addItem?

 

 

		private function getShots(url:String, page:int, per_page:int):void
		{	
			var shot_loader:URLLoader = new URLLoader();
			shot_loader.dataFormat = URLLoaderDataFormat.TEXT; 
			shot_loader.addEventListener(IOErrorEvent.IO_ERROR, IOErrorError);
			shot_loader.addEventListener(ProgressEvent.PROGRESS, progressEvent);
			shot_loader.addEventListener(Event.COMPLETE, handleResults);
			shot_loader.load(new URLRequest(_current_query + "?page=" + page + "?pages=" + 1 + "&per_page=" + per_page));
		}

 		private function handleResults(event:Event):void 
		{			
			var response:String = event.target.data as String; //<- important
			_container = (JSON.decode(response));// <- important _container = first { } on api stuff below
		
			var shotLength:Number = getLength(_container.shots);
				for(var i:uint = 0; i < shotLength; i++)
				{
					if(_container.shots[i].image_teaser_url != null) //shots in an array, iterate through it as usual
					{	
						var obj:Object = new Object();
						obj.title = _container.shots[i].id;
						obj.url = _container.shots[i].image_teaser_url;
						_dp.addItem({label:obj.text, data:obj});
						trace("dp length " + _dp.length);					
					}					
				}
		}

 

Hope that makes sense,

 

Cheers,