Blog

  • Customising scrollableView in titanium

    ScrollableViews in Titanium have support for paging control. However, iOS displays small dots on bottom of the screen whereas Android displays arrows on left and right hand sides.

    However, for the purpose of similarity we can make a custom scrollableView that is able to render exactly same on both platforms. We will be using this approach to make similar functionality for both platforms. The idea is to add a View on top of the window and customising this view to suit our requirement as to add bullets or screenshot and adding left or right arrows. We will make use of ScrollableView's scroll property to determine the current page index and for navigational purpose.

    Below are the steps defined to Make a custom scrollable view.
    1. Make a new Titanium Mobile (Classic) project.
    2. In the app.js , cut and paste the following code:

               var win = Ti.UI.createWindow();
    
    var view1 = Ti.UI.createView({ backgroundColor:'blue' });
    var view2 = Ti.UI.createView({ backgroundColor:'red' });
    var view3 = Ti.UI.createView({ backgroundColor:'green' });
    
    var scrollableView = Ti.UI.createScrollableView({
      views:[view1,view2,view3],
      showPagingControl:true
    });
    win.add(scrollableView);
    
    var pageController=require('customScrollableView').pagingControl(scrollableView);
    pageController.setBottom(0);
    
    win.add(pageController);
    win.open();     
            


    The above code simply creates 3 Views to be embedded in a Scrollable View. and note that we are passing the scrollable view's reference to another file where we will customise this scrollable view.

    3. Make a new file in resources directory. Name it as 'customScrollableView.js' and paste the following code in this file:

                    exports.pagingControl = function(scrollableView) {
    	var container = Titanium.UI.createView({
    		height : 40,
    		backgroundColor : "#161217",
    	});
    
    	var viewLeftArrow = Ti.UI.createView({
    		height : 16,
    		width : 10,
    		left : 15,
    		selected : false
    	});
    
    	var imageLeftArrow = Ti.UI.createImageView({
    		image : '/leftGrayArrow.png',
    		height : Ti.UI.SIZE,
    		width : Ti.UI.SIZE,
    	});
    	viewLeftArrow.add(imageLeftArrow);
    
    	container.add(viewLeftArrow);
    
    	var bulletContainer = Ti.UI.createView({
    		height : 13,
    		width : Ti.UI.SIZE
    	});
    	container.add(bulletContainer);
    
    	var viewRightArrow = Ti.UI.createView({
    		height : 16,
    		width : 10,
    		right : 15,
    		selected : true
    	});
    
    	var imageRightArrow = Ti.UI.createImageView({
    		image : '/rightBlueArrow.png',
    		height : Ti.UI.SIZE,
    		width : Ti.UI.SIZE,
    	});
    	viewRightArrow.add(imageRightArrow);
    	container.add(viewRightArrow);
    	// Keep a global reference of the available pages
    	var numberOfPages = scrollableView.getViews().length;
    
    	var pages = [];
    	// without this, the current page won't work on future references of the module
    
    	// Go through each of the current pages available in the scrollableView
    	for (var i = 0; i < numberOfPages; i++) {
    		var page = Titanium.UI.createView({
    			borderRadius : 7,
    			width : 13,
    			height : 13,
    			left : 25 * i,
    			backgroundColor : "#878686",
    		});
    		// Store a reference to this view
    		pages.push(page);
    		// Add it to the container
    		bulletContainer.add(page);
    	}
    
    	// Mark the initial selected page
    	pages[scrollableView.getCurrentPage()].setBackgroundColor("#007AC2");
    
    	if (pages.length == 1) {
    		imageLeftArrow.image = '/leftGrayArrow.png';
    		imageRightArrow.image = '/rightGrayArrow.png';
    		viewLeftArrow.selected = false;
    		viewRightArrow.selected = false;
    	} else {
    		imageLeftArrow.image = '/leftGrayArrow.png';
    		imageRightArrow.image = '/rightBlueArrow.png';
    		viewLeftArrow.selected = false;
    		viewRightArrow.selected = true;
    	}
    
    	viewLeftArrow.addEventListener('click', function(e) {
    		if (this.selected) {
    			scrollableView.currentPage -= 1;
    		}
    	});
    	viewRightArrow.addEventListener('click', function(e) {
    		if (this.selected) {
    			scrollableView.currentPage += 1;
    		}
    	});
    
    	// Callbacks
    	onScroll = function(event) {
    		if (event.currentPage || event.currentPage == 0) {
    			// Go through each and reset it's color
    			for (var i = 0; i < numberOfPages; i++) {
    				pages[i].setBackgroundColor("#878686");
    			}
    			// Bump the Color of the new current page
    			pages[event.currentPage].setBackgroundColor("#007AC2");
    
    			if (event.currentPage == 0) {
    				if (event.currentPage < pages.length - 1) {
    					imageLeftArrow.image = '/leftGrayArrow.png';
    					imageRightArrow.image = '/rightBlueArrow.png';
    					viewLeftArrow.selected = false;
    					viewRightArrow.selected = true;
    				} else {
    					imageLeftArrow.image = '/leftGrayArrow.png';
    					imageRightArrow.image = '/rightGrayArrow.png';
    					viewLeftArrow.selected = false;
    					viewRightArrow.selected = false;
    				}
    			} else if (event.currentPage < pages.length - 1) {
    				imageLeftArrow.image = '/leftBlueArrow.png';
    				imageRightArrow.image = '/rightBlueArrow.png';
    				viewLeftArrow.selected = true;
    				viewRightArrow.selected = true;
    			} else {
    				imageLeftArrow.image = '/leftBlueArrow.png';
    				imageRightArrow.image = '/rightGrayArrow.png';
    				viewLeftArrow.selected = true;
    				viewRightArrow.selected = false;
    			}
    		}
    	};
    
    	// Attach the scroll event to this scrollableView, so we know when to update things
    	scrollableView.addEventListener("scroll", onScroll);
    
    	return container;
    };
            


    Notice that we are simply creating a view and customising it according to our requirement.
    a) We placed click event on left and right arrows to navigate the Scrollable view accordingly.
    b) The 'onScroll' function uses the 'scroll' property of scrollableView and makes suitable adjustments in bullets.

    4) Now, run the project on iOS and Android and you can see the custom scrollableView rendered similarly in both.

    Hope it Helps!! :)
    Ankush Gulati
    ankush.gulati@oodlestechnologies.com

Tags: titanium