Loading
Anthanh
This is a live streamed presentation. You will automatically follow the presenter and see the slide they're currently on.
Anthanh Pham Trinh - @antaipt
MOBILE USAGE STATUS QUO
MOBILE IS
EVERYWHERE
2005
2013
WEB DEVELOPERS?
NATIVE
NATIVE
Performance
User experience
Hardware access
Vendor platform
Updates
Development costs
WEB
WEB
Open technologies
Updates
Development costs
Performance
User Experience
Accesibility
HYBRID
HYBRID
CrossPlatform
Web Technologies
Development costs
No UI Restrictions
Hardware access
Performance
User Experience
Updates
WHEN GO TO HYBRID
FRAMEWORKS
BOOTSTRAP PROJECT
$ ionic start ionic-example tabs
PREVIEW APP
$ ionic serve
$ ionic serve --lab
BUILD APP
$ ionic platform add android
$ ionic build android
platforms/android/ant-build/*.apk
$ ionic platform add ios
$ ionic build ios
platforms/ios/build/emulator/*.app
TEST APP
$ ionic emulate android
$ ionic run android
Local
Remote
DEVELOP
TIME!
SIDEBAR (I)
<ion-side-menus>
<!-- Center content -->
<ion-side-menu-content>
<ion-nav-bar class="bar-positive">
<ion-nav-back-button></ion-nav-back-button>
</ion-nav-bar>
<ion-nav-view></ion-nav-view>
</ion-side-menu-content>
<!-- Left menu -->
<ion-side-menu side="left">
<ion-list>
<ion-item class="item-avatar" type="item-text-wrap">
<img ng-src="{{user.avatar}}">
<h2>{{user.name}}</h2>
<p>{{user.city}}</p>
</ion-item>
<ion-item menu-close class="item-icon-right"
type="item-text-wrap"
href="#/login">
<h2>Logout</h2>
</ion-item>
</ion-list>
</ion-side-menu>
</ion-side-menus>
index.html
SIDEBAR (II)
angular.module('starter.controllers', [])
.controller('MainCtrl', function(
$scope,
$ionicSideMenuDelegate,
$ionicPopover
) {
$scope.user = {
avatar: 'http://www.gravatar.com/avatar/' +
'7e6af66d57801c031359233b5756e884.png',
name: 'Anthanh Pham Trinh',
city: 'Mordor City'
};
// ...
});
controller.js:MainCrtl
<ion-nav-bar class="bar-positive">
<ion-nav-back-button></ion-nav-back-button>
<ion-nav-buttons side="left">
<button menu-toggle="left"
class="button button-icon icon ion-navicon">
</button>
</ion-nav-buttons>
</ion-nav-bar>
index.html
POPOVER (I)
<ion-nav-bar class="bar-positive">
<!-- ... -->
<ion-nav-buttons side="right">
<button menu-toggle="right"
class="button button-icon icon ion-android-more-vertical"
ng-click="showActionsMenu($event)">
</button>
</ion-nav-buttons>
</ion-nav-bar>
index.html
<ion-popover-view> <ion-content>
<ion-list>
<ion-item menu-close
class="item-icon-right"
type="item-text-wrap"
href="#/login"
ng-click="hideActionsMenu()">
<h3>Logout</h3>
</ion-item>
</ion-list>
</ion-content> </ion-popover-view>
popover.html
POPOVER (II)
angular.module('starter.controllers', [])
.controller('MainCtrl', function(
$scope,
$ionicSideMenuDelegate,
$ionicPopover
) {
// ...
$ionicPopover.fromTemplateUrl('templates/popover.html', {
scope: $scope
}).then(function(popover) {
$scope.popover = popover;
});
$scope.showActionsMenu = function($event) {
$scope.popover.show($event);
};
$scope.hideActionsMenu = function() {
$scope.popover.hide();
};
}));
controllers.js
LOGIN (I)
<ion-view view-title="Login">
<ion-content>
<div class="list">
<label class="item item-input item-floating-label">
<span class="input-label">Email</span>
<input type="text" placeholder="Email">
</label>
<label class="item item-input item-floating-label">
<span class="input-label">Password</span>
<input type="password" placeholder="Password">
</label>
</div>
<div class="padding">
<button
class="button button-block button-positive"
ng-click="login()">login</button>
</div>
</ion-content>
</ion-view>
templates/login.html
LOGIN (II)
.controller('LoginCtrl', function($scope, $state) {
$scope.login = function() {
$state.go('tab.dash');
};
})
controllers.js:LoginCtrl
$stateProvider.state('login', {
url: '/login',
templateUrl: 'templates/login.html',
controller: 'LoginCtrl'
});
app.js
ON-SCROLL REFRESH
<ion-view view-title="Chats">
<ion-content>
<ion-refresher
pulling-text="Pull to refresh..."
on-refresh="doRefresh()">
</ion-refresher>
<ion-list>
<!-- ... -->
<ion-list>
</ion-content>
</ion-view>
tab-chats.html
.controller('ChatsCtrl', function($scope, $timeout) {
$scope.doRefresh = function() {
$timeout(function() { // async emulation
$scope.$broadcast('scroll.refreshComplete');
}, 1000);
};
})
app.js
STYLING
$ ionic setup sass
.menu.menu-left .item-avatar {
background-color: $royal;
h2, p {
color: white;
}
}
.popover {
height: 4em;
}
scss/ionic.app.scss
[{
"id": "0",
"name": "Ben Sparrow",
"lastText": "You on your way?",
"face": "https://pbs.twimg.com/profile_images/514549811765211136/9SgAuHeY.png"
}, ... ]
res/chats.json
$scope.doRefresh = function() {
Chats.more().success(function(chats) {
$scope.chats = $scope.chats.concat(chats);
$scope.$broadcast('scroll.refreshComplete');
}).error(function() {
$scope.$broadcast('scroll.refreshComplete');
});
};
controllers.js:ChatsCrtl
BACKEND RESOURCES
.factory('Chats', function($http) {
return {
more: function() {
return $http.get('res/chats.json');
},
...
};
});
services.js
EXAMPLE PROJECT
https://github.com/anthanh/ionic-example
MUCH MORE!
DON'T TRY IT ALONE! GET INSPIRED
THANKS!
Anthanh Pham Trinh - @antaipt