Occasionally we will want to tailor the layout of our app to suit the device that the User is viewing it on. Generally we want to do this to take advantage of the increased screen real estate made available by devices such as tablets compared to the usual phone or iPod. For example, showing a list of search results alongside a map rather than having them one behind the other in a card layout.
or view the live demo (please use Safari, Google Chrome or your Smartphone!)
The theory behind achieving this is pretty simple. We decide if we’re on a phone or a tablet and then alter the defined ‘layout‘ config accordingly. We’ll set up a simple example with a list and a map in a card layout initially, with a button in a docked toolbar that will switch between them.
[javascript]
Ext.ns(‘SwarmOnline’);
SwarmOnline.CardPanel = Ext.extend(Ext.Panel, {
initComponent: function(){
var layoutCustom = ‘card’;
var itemCustom = [{
xtype: 'list',
itemTpl: '{firstName} {lastName}',
indexBar: true,
store: store,
disableSelection: true
}, {
xtype: 'map'
}];
var dockedItems = [{
dock: 'top',
xtype: 'toolbar',
items: [{
text: 'Switch',
handler: this.onSwitchTap,
scope: this
}]
}];
Ext.apply(this, {
fullscreen: true,
layout: layoutCustom,
items: itemCustom,
dockedItems: dockedItems
});
SwarmOnline.CardPanel.superclass.initComponent.call(this);
},
onSwitchTap: function(){
this.setActiveItem(this.getActiveItem() === this.items.get(0) ? 1 : 0);
}
});
var cardPanel = new SwarmOnline.CardPanel();
[/javascript]
If you open the demo for this step (by clicking the above) you will see a list and then a map if you click the Switch button. That’s a great start and is how most apps would display such data but what if the user is using an iPad? That list will be stretched hugely in the x-axis and will probably look pretty naff, so why not show both?
Before we move on, note that we defined the items and layout config options in variables and then put them into the Ext.apply call, we did this so we can fiddle with them before doing the final configuration.
So what we want to do is display the list at one side of the screen and the map alongside it so they can be viewed simultaneously giving a much better experience to the user and also improving the appearance of the list greatly. To do this we add a new method to decide what sort of device we’re on and then alter the ‘layout‘ variable depending on the result. In this case if it isn’t a Phone/iPod then we’re going to make it use an hbox layout with a 1/3 flex.
[javascript highlight="4,11,26-30"]
initComponent: function(){
var layout = ‘card’;
var items = [{
flex: 1,
xtype: 'list',
itemTpl: '{firstName} {lastName}',
indexBar: true,
store: store,
disableSelection: true
}, {
flex: 3,
xtype: 'map'
}];
var dockedItems = [{
dock: 'top',
xtype: 'toolbar',
items: [{
text: 'Switch',
handler: this.onSwitchTap,
scope: this
}]
}];
if (!this.isPhone()) {
layout = {
type: ‘hbox’,
align: ‘stretch’,
pack: ‘justify’
};
dockedItems = [];
}
}
[/javascript]
..and then the method to decide what device the user is on…
[javascript]
…
isPhone: function(){
return Ext.is.Phone || Ext.is.iPod;
}
…
[/javascript]
As you can see on Line 4 and 11 we add a flex config option – this will be ignored if we are using a card layout so it can be set straight away no matter what the device. We then call our isPhone method, and if it isn’t a Phone/iPod then we change the value of the layout variable to be an hbox config (Line 26-30) and reset the dockedItems array so the Switch button doesn’t show. If you run this code (or click the Step 2 header) then you should see (assuming your on a PC/Mac and not a phone) the List and Map side by side.
So there we go, dynamic layouts based on the user’s device – easy!
Please post a comment or email us if you have any problems or suggestions!
or view the live demo (please use Safari, Google Chrome or your Smartphone!)