Wednesday, February 2, 2011

Appcelerator Titanium Scrollview Swipe functionality

I have recently started looking into the development of Appcelerator titanium for iphone and ipad. I have been finding the tool great for RAD development of mobile applications. The major problem i have faced with this platform is the memory management stuff. The inbuilt memory management is something quite unsatisfactory. Today I am going to discuss one such problem that I faced with appcelerator.

I wanted to have a simple functionality of swiping through the images in appcelerator, something that is very common in appcelrator. So I decided to use the most obvious choice ScrollableView. But on using the scrollableview the memory started shouting since I had approximately 150 - 200 images. Now the question was how to do this, I spent around 4 days searching blogs and all, but no answers. So I decided to find a solution.

The simplest logical answer was to have three imageviews in the scrollview each at index 0, 1, 2. The image displayed on the screen is always at index 1. Now on the swipe of right to left you should remove the view at position 0 and assign the view at position 1 to position 0, the view at position 2 to position 1 and the view that was at position 0 to position 2 and provide the view with new image. Similarly follow the reverse case for swiping form left to right. Attached is my code of App.js

// this sets the background color of the master UIView (when there are no windows/tab groups on it)
Titanium.UI.setBackgroundColor('#000');

//
// create base UI tab and root window
//
var win1 = Titanium.UI.createWindow({
title:'Tab 1',
backgroundColor:'#fff'
});

var imageViewArray = [];
var imageNameArray = [];
var nextImageIndex;

for(var i = 0; i < 3 ; i++){
var imageView1 = Titanium.UI.createImageView({
//image: imagePath
});
imageViewArray[i] = imageView1;
}


var scrollingView = Titanium.UI.createScrollableView({
//contentWidth:1280,
//contentHeight:450,
views:imageViewArray,
width: 310,
height: 450,
top: 5,
left: 5,
borderWidth: 2,
borderColor: '#000'
});

scrollingView.addEventListener('scroll', function(e){
Ti.API.info("C=" + e.currentPage);
Ti.API.info("N=" + nextImageIndex);
if(e.currentPage == 2 && nextImageIndex < imageNameArray.length - 2)
{
//Setting the current page to 1 will allow the smooth swipe functionality
scrollingView.currentPage = 1;
nextImageIndex += 1;
var vw = scrollingView.views[0];
imageViewArray[0] = scrollingView.views[1];
imageViewArray[1] = scrollingView.views[2];
scrollingView.removeView[vw];
vw.image=imageNameArray[nextImageIndex + 1];
imageViewArray[2] = vw;
scrollingView.views = imageViewArray;
}
else if(e.currentPage == 0 && nextImageIndex > 1)
{
nextImageIndex -= 1;
scrollingView.currentPage = 1;
var vw = scrollingView.views[2];
imageViewArray[1] = scrollingView.views[0];
imageViewArray[2] = scrollingView.views[1];
scrollingView.removeView[vw];
vw.image=imageNameArray[nextImageIndex - 1];
imageViewArray[0] = vw;
scrollingView.views = imageViewArray;
}
});

//get the config from config.xml
/*
Sample xml nodes
<root>
<items>
<item>True-Blood.jpg</item>
<item>2219-true-blood.jpg</item>
<item>true-blood-20080905051323782_640w.jpg</item>
</items>
</root>
*/
var f = Titanium.Filesystem.getFile(Titanium.Filesystem.resourcesDirectory, '320x480/images.xml');
var contents = f.read();
var xmlObject = Ti.XML.parseString(contents.text);
var imageNode = xmlObject.documentElement.getElementsByTagName("item");

for(var i = 0; i < imageNode.length; i++)
{
var imagePath = '320x480/' + imageNode.item(i).text;
imageNameArray[i] = imagePath;
}

scrollingView.views[0].image = imageNameArray[0];
scrollingView.views[1].image = imageNameArray[1];
scrollingView.views[2].image = imageNameArray[2];
nextImageIndex = 1;


win1.add(scrollingView);
win1.open();


I believe this is an alternative to the memory leak. Appcelerator team should provide the ultimate solution to this problem.

Please let me know if you find any issues with this. If my post helps you, dont forget to thank me ;)

Enjoy Coding

Shakil Bharucha