Blog Archive

Sencha Touch 2 Orientation change example - Check Landscape or Portrait

In this tutorial we are going to see how to display the initial screen based on the device orientation whether it is landscape or portrait and then change the display as the orientation changes. In addition to that we will see how to use the same form Panel instance in the layouts so that the values that you entered don't disappear when you rotate the device.


Sencha Touch 2 change display based on orientation - landscape or portrait
Sencha Touch 2 change display based on orientation - landscape or portrait

We are going to take help of the Ext.Viewport class. It has a getOrientation() method to retrieve the current orientation. Also there is a orientationchange event that fires when the Viewport orientation changes.

orientationchange( Ext.Viewport this, String newOrientation, Number width, Number height, Object eOpts )
  • this : Ext.Viewport
  • newOrientation : String
    • The new orientation
  • width : Number
    • The width of the Viewport
  • height : Number
    • The height of the Viewport
  • eOpts : Object
    • The options object passed to Ext.util.Observable.addListener.

getOrientation( ) : String
  • Returns portrait or landscape

Application starting point - index.html

<!DOCTYPE html>
<html>
<head>
    <title>Sencha Touch 2 Orientation Tutorial</title>
    <link rel="stylesheet" href="sencha-touch/resources/css-debug/sencha-touch.css" type="text/css">
    <script type="text/javascript" src="sencha-touch/sencha-touch-all-debug.js"></script>
    <script type="text/javascript" src="app.js"></script>
</head>
<body></body>
</html>

Sencha Touch application file - app.js

Ext.Loader.setConfig({ 
    enabled: true 
});

Ext.application({
   
    name: 'MyApp',
    appFolder: 'app',
    requires: [
               'MyApp.view.MainPanel',
               ], 
              
    views : ['MainPanel'],          
    controllers: ['SetLayout'],
   
    launch: function() {
        console.log('Application launch');
        Ext.create('MyApp.view.MainPanel');
    }
   
});

Main panel to hold other other Panels inside - MainPanel.js

The main panel is displayed when the application launches. As you can see the main panel has no items defined in it. We are going to add panels to the main panel from the controller after we check the orientation of the device.
Ext.define('MyApp.view.MainPanel', {
    extend: 'Ext.Panel',
    alias : 'widget.mainPanel',
    
    requires: [
            'MyApp.view.LandscapePanel',
            'MyApp.view.PortraitPanel'
        ],
               
    config: {
        
        fullscreen: true,
        layout: {
            type: 'fit'
        },
        items: [
            {
                //xtype: 'landscapePanel',
            }
        ]
    }
});

Landscape Orientation - LandscapePanel.js

Ext.define('MyApp.view.LandscapePanel', {
    extend: 'Ext.Panel',
    alias : 'widget.landscapePanel',
   
    requires: [
               'MyApp.view.ScreenLayout1',
               'MyApp.view.ScreenLayout2'
           ],
          
    config: {
       
        layout: {
            type: 'hbox'
        },
        defaults: {
            margin: '3 3 3 3',
        },
    }
});

Portrait Orientation - PortraitPanel.js

Ext.define('MyApp.view.PortraitPanel', {
    extend: 'Ext.Panel',
    alias : 'widget.portraitPanel',
   
    requires: [
               'MyApp.view.ScreenLayout1',
               'MyApp.view.ScreenLayout2'
           ],
          
    config: {
       
        layout: {
            type: 'vbox'
        },
        defaults: {
            margin: '3 3 3 3',
        }
    }
});

Screen that contains a form to display - ScreenLayout1.js

Ext.define('MyApp.view.ScreenLayout1', {
    extend: 'Ext.Panel',
    alias : 'widget.screenLayout1',
   
    config: {
       
        style: 'background-color: #cdc9c9',
        flex: 1,
        layout: {
            type: 'vbox',
        },
        defaults: {
            margin: '0 0 5 0',
            labelWidth: '125',
        },
        items: [
            {
                xtype: 'label',
                html: 'This panel takes 33% of the available space',
            },   
            {
                xtype: 'sliderfield',
                label: 'Slide this to have fun',
                name: 'myslider',
                labelAlign: 'top',
                increment: 25,
            },
            {
                xtype: 'textfield',
                label: 'My Name',
            },   
            {
                xtype: 'button',
                text: 'Some Activity',
                iconCls: 'arrow_right',
                iconMask: true, 
            }
        ]
    }
  
});

Screen containing some HTML text to display - ScreenLayout2.js

Ext.define('MyApp.view.ScreenLayout2', {
    extend: 'Ext.Panel',
    alias : 'widget.screenLayout2',
   
    config: {
       
        html: 'This panel takes 67% of the available space',
        style: 'background-color: #8b8989',
        flex: 2
   
    }
  
});

Finally the controller to manage all the screens - SetLayout.js

Ext.define('MyApp.controller.SetLayout', {
    extend : 'Ext.app.Controller',
   
    config: {
        profile: Ext.os.deviceType.toLowerCase(),
        refs: {
            myContainer: 'mainPanel'
        },
        control: {
            'mainPanel': {
                activate: 'onActivate'
            },
            'viewport': {
                //capture the orientation change event
                orientationchange: 'onOrientationchange'
            }
        } 
       
    },
   
    onActivate: function() {
        console.log('Main container is active');
    },
   
    init: function() {
        console.log('Controller initialized');
    },
   
    onOrientationchange: function(viewport, orientation, width, height) {
        console.log('Viewport orientation just changed');
        Ext.Msg.alert("Orientation",orientation);
       
        //another way to check the orientation is by checking the 
        //height and width of the screen window
        //There are some issues with the orientation when the code
        //was run on an Android Tablet so you check the height and 
        //width for a temporary fix until sencha provides one.
        console.log(height);
        console.log(width);
        if(width > height){
            orientation = 'landscape';
        }
        else {
            orientation = 'portrait';
        }
        console.log('Orientation is ' + orientation);
       
        //remove all the items from the main panel
        this.getMyContainer().removeAll(false,false);
       
        //add the landscape panel based on orientation 
        if(orientation == 'landscape'){
            console.log(landscapePanel.getItems());
            landscapePanel.add([screenLayout1,screenLayout2]);
            this.getMyContainer().add([landscapePanel]);
        }
       
        //add the portrait panel based on orientation 
        if(orientation == 'portrait'){
            console.log(portraitPanel.getItems());
            portraitPanel.add([screenLayout1,screenLayout2]);
            this.getMyContainer().add([portraitPanel]);
        }
    },
   
    launch: function() {
        console.log('Controller launched');
       
        //create a single instance of all the panels as global variables
        //so we can use them to add and remove without creating them 
        //again and again. (Not sure if creating again is better approach!)
        //Also this way it keeps the information that was entered on the
        //screen when the device orientation without you saving and restoring
        //each component
        screenLayout1 = Ext.widget('screenLayout1');
        screenLayout2 = Ext.widget('screenLayout2');
        landscapePanel = Ext.widget('landscapePanel');
        portraitPanel = Ext.widget('portraitPanel');
       
        //get the device orientation
        var orientation = Ext.Viewport.getOrientation();
        Ext.Msg.alert("Orientation",orientation);
       
        //you can also get the height and width and determine the
        //orientation. This code just to show how to do it. You can
        // use either approach
        var height = Ext.Viewport.getWindowHeight();
        var width = Ext.Viewport.getWindowWidth();
        console.log(height);
        console.log(width);
        if(width > height){
            orientation = 'landscape';
        }
        else {
            orientation = 'portrait';
        }
        console.log('Orientation is ' + orientation);
       
        //set panels inside the main Panel based on orientation
        if(orientation == 'landscape'){
            landscapePanel.add([screenLayout1,screenLayout2]);
            this.getMyContainer().add([landscapePanel]);
        }
        if(orientation == 'portrait'){
            portraitPanel.add([screenLayout1,screenLayout2]);
            this.getMyContainer().add([portraitPanel]);
        }
    },
           
});