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
14 comments:
looks alot like this solution https://gist.github.com/810171
Thanks... this is a nice solution
look nice but how can you integrate an orientation change, that you can view landscape too?
Hi Shakil,
Just came up with a solution to any memory problems. See here: http://developer.appcelerator.com/question/116867/this-is-a-solution-to-your-memory-woes
This is a nice article but I'm having problem with flickering in ipad.
@Rey: In my code, I put
scrollingView.currentPage = 1;
as the last thing to happen. It isn't perfect, but reduces flashes maybe 80%.
Working solution to the iPad flickering:
The use of the removeView method is being used incorrectly. It should be removeView( vw ); instead of removeView[vw];
Also, just remove the currentPage = 1; in the two conditions and put in at the bottom of the function like Adam is suggesting. This fixes it for me :-)
Good work.
It flickr a little bit when scrolling to the left but it's ok.
I have to display the imageView plus a label showing the image name, but for this I have to know the "real" index of the image in the scroll event.
How can I get it ?
Thanks
if the size of images is not too large, try cacheSize of scrollview :) everything else is unnecessary. 6 hours of headache
Hi..
I want to know that is Scrollable view can display circular view .
Means when user at last view at that time he swipe it will display first view..
Thanks
Is it possible that we can manage 5 images instead of 3 images at a time.
Hi
I have implemented this code for sliding images. Its working pretty fine.
But i do have 1 more concern.
i am placing the images in an array.
And if i want to come back to same screen with some random image of the array. I want it should have the previous and next images of the array,
sliding,
But the problem that i am facing is that i am able to scroll to next images but previous images dont come as i set the image of 1st view as that random image. So how can i resolve this problem.
Hi all,
Has anyone found a solution on the flickering?
Thanks
Post a Comment