Build Your First Mobile App with Ionic – Part 1
I believe one of the really good ways of properly learning something is taking baby steps.
I started learning how to build mobile applications with Ionic Framework last week and I am excited to share my learning process and knowledge with you.
Let’s let to build mobile apps with our existing web skills together. You need to have some knowledge of HTML, CSS and JAVASCRIPT to move along. A little knowledge of AngularJS is also necessary.
Step 1
- Make sure you have an up-to-date version of Node.js installed on your system. If you don’t have Node.js installed, you can install it from here.
- Open a terminal (Mac) or a command interpreter (cmd, Windows), and install Cordova and Ionic:
- npm install -g cordova
- npm install -g ionic
- On a Mac, you may have to use sudo depending on your system configuration: sudo npm install -g cordova ionic
- If you already have Cordova and Ionic installed on your computer, make sure you update to the latest version:
- npm update -g cordova
- npm update -g ionic
- Or sudo npm update -g cordova ionic
Follow these links if you want more information:
Step 2
Ionic comes bundled with some predefined boilerplate templates that just makes it easier for you to build untop of.
Run ionic templates
on your terminal
Let’s use the sidemenu template.
The name of the app we will be building is called Devangelist.
Devangelist will be an app that gets top developers from Github, analyzes their repos and gives us the status of these open source contributors.
So, go ahead and run thisionic start devangelist sidemenu
on your terminal.
Now, that the template is downloaded, go ahead and run ionic serve --lab
on your terminal.
This brings up the app in iOs and Android view. I love to develop this way so I can see both platforms at thesame time.
Right now, this is how it looks on my browser:
You can as well just run ionic serve
and it will run the app in your browser.
This is the result of ionic serve
on your browser with the side menu toggled:
Step 3:
Let’s explore the folder structure
hooks –
platforms – these are the where platform specific files reside
plugins – home for the all the cordova and ionic plugins used in the project
scss – home for our sass files. Ionic is bundled with Sass which makes it a lot easier to use mixins and global variables.
www – home for our app logic. It contains css
, img
, js
, lib
, templates
folders and index.html
file.
templates houses the various view files.
js houses all our controllers
, services
and app.js
where our routes will be. Ionic makes use of Angular UI router which involves the use of states.
Open app.js file
Change the name of the module from starter
to devangelist
, starter.controllers
will also become devangelist.controllers
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
angular.module('devangelist', ['ionic', 'devangelist.controllers']) .run(function($ionicPlatform) { $ionicPlatform.ready(function() { // Hide the accessory bar by default (remove this to show the accessory bar above the keyboard // for form inputs) if (window.cordova && window.cordova.plugins.Keyboard) { cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true); cordova.plugins.Keyboard.disableScroll(true); } if (window.StatusBar) { // org.apache.cordova.statusbar required StatusBar.styleDefault(); } }); }) |
..the run method is invoked once the application loads and $ionicPlatform
is an ionic inbuilt service that has a ready method that can be called on it. It is triggered when the mobile device is ready. It hides the keyboard and disables scroll by default.
Now this wouldn’t work unless we download the cordova plugin that is responsible for handling the native mobile keyboard. There are several cordova plugins that makes it possible to interact with the native functionalites and features of a device like the camera, accelerometer, sharing, device battery et.c. The list of those plugins can be found here.
ionic plugin add com.ionic.keyboard
Run the above command in your terminal to add the keyboard to your app.
Now open controllers.js
Get rid of the contents of all the controllers, let be like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
angular.module('devangelist.controllers', []) .controller('AppCtrl', function($scope, $ionicModal, $timeout) { }) .controller('PlaylistsCtrl', function($scope) { }) .controller('PlaylistCtrl', function($scope, $stateParams) { }); |
Now, you’ll discover that the app reloads automatically after each change to any file which is totally cool, saves us the stress of having to reload the browser everytime.
Open index.html which is resident in the templates folder
This is the file that links everything together. You’ll see the link to the ionic bundle script, app.js, controllers.js and all the styles.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width"> <title></title> <link href="lib/ionic/css/ionic.css" rel="stylesheet"> <link href="css/style.css" rel="stylesheet"> <!-- IF using Sass (run gulp sass first), then uncomment below and remove the CSS includes above <link href="css/ionic.app.css" rel="stylesheet"> --> <!-- ionic/angularjs js --> <script src="lib/ionic/js/ionic.bundle.js"></script> <!-- cordova script (this will be a 404 during development) --> <script src="cordova.js"></script> <!-- your app's js --> <script src="js/app.js"></script> <script src="js/controllers.js"></script> </head> <body ng-app="devangelist"> <ion-nav-view></ion-nav-view> </body> </html> |
<ion-nav-view></ion-nav-view> is where all the UI for the app will actually be rendered. It’s an ionic directive for navigation views.
Note: I changed the ng-app value from starter
to devangelist
. Now our app is back online and working.
We are going to have 3 main menu views in our app:
1. Developer – this when clicked will give us developers information
2. Location – this when clicked will put the developers on a map based on their location
3. About – this when clicked will show us simply what the app is about.
Open menu.html in the templates folder, this is it:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
<ion-side-menus enable-menu-with-back-views="false"> <ion-side-menu-content> <ion-nav-bar class="bar-stable"> <ion-nav-back-button> </ion-nav-back-button> <ion-nav-buttons side="left"> <button class="button button-icon button-clear ion-navicon" menu-toggle="left"> </button> </ion-nav-buttons> </ion-nav-bar> <ion-nav-view name="menuContent"></ion-nav-view> </ion-side-menu-content> <ion-side-menu side="left"> <ion-header-bar class="bar-stable"> <h1 class="title">Left</h1> </ion-header-bar> <ion-content> <ion-list> <ion-item menu-close ng-click="login()"> Login </ion-item> <ion-item menu-close href="#/app/search"> Search </ion-item> <ion-item menu-close href="#/app/browse"> Browse </ion-item> <ion-item menu-close href="#/app/playlists"> Playlists </ion-item> </ion-list> </ion-content> </ion-side-menu> </ion-side-menus> |
Replace it with this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
<ion-side-menus enable-menu-with-back-views="false"> <ion-side-menu-content> <ion-nav-bar class="bar app-top-bar"> <ion-nav-back-button> </ion-nav-back-button> <ion-nav-buttons side="left"> <button class="button button-icon button-clear ion-navicon" menu-toggle="left"> </button> </ion-nav-buttons> </ion-nav-bar> <ion-nav-view name="menuContent"></ion-nav-view> </ion-side-menu-content> <ion-side-menu class="main-menu" side="left"> <ion-content scroll="false"> <ion-list> <ion-item class="item item-icon-right" nav-clear menu-close ui-sref="app.developers"> <i class="icon ion-person-stalker"></i> <h2 class="menu-text">Developers</h2> </ion-item> <ion-item class="item item-icon-right" nav-clear menu-close ui-sref="app.location"> <i class="icon ion-location"></i> <h2 class="menu-text">Location</h2> </ion-item> <ion-item class="item item-icon-right" nav-clear menu-close ui-sref="app.about"> <i class="icon ion-speakerphone"></i> <h2 class="menu-text">About</h2> </ion-item> </ion-list> </ion-content> </ion-side-menu> </ion-side-menus> |
Like i said earlier, Ionic has a lot of components – directives and icons.
You can read the component documentation here and ionic icons here
Now our view should look like this:
We have:
<ion-side-menus>
,
<ion-side-menu-content>
,
<ion-nav-bar>
,
<ion-nav-buttons>
,
<ion-nav-view>
,
ion-side-menu>
,
<ion-content>
,
<ion-list>
<ion-item>
You can experiment with these components for various types of layout for the menu.
The ui-sref
attributes point to the different states we want the app to navigate to when the item is clicked. We’ll cover that soon.
The menu-close
attribute directive ensures that the menu item closes/disappears when it calls another state, and opens a new view.
Step 4:
Let’s set up the routing for the views.
Open app.js,
let the the .config section be like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
.config(function($stateProvider, $urlRouterProvider) { $stateProvider .state('app', { url: '/app', abstract: true, templateUrl: 'templates/menu.html', controller: 'AppCtrl' }) .state('app.developers', { url: '/developers', views: { 'menuContent': { templateUrl: 'templates/developers.html', controller: 'DeveloperCtrl' } } }) .state('app.location', { url: '/location', views: { 'menuContent': { templateUrl: 'templates/location.html', controller: 'LocationCtrl' } } }) .state('app.about', { url: '/about', views: { 'menuContent': { templateUrl: 'templates/about.html', controller: 'AboutCtrl' } } }); // if none of the above states are matched, use this as the fallback $urlRouterProvider.otherwise('/app/developers'); }); |
We have different controllers for the various views and we have about 3 states.
By default, when the app is opened, it shows the developers view, it routes to that state.
$urlRouterProvider.otherwise(‘/app/developers’);
Now create the following files in the templates folder:
– location.html
– developers.html
– about.html
Step 5:
Let’s deal with the developers view. The developers view will have two tabs namely PHP and JS. Let’s set it up:
developers.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
<ion-view class="developer-view"> <ion-nav-title class="has-tabs-top"> <span>Developers</span> </ion-nav-title> <ion-tabs class="tabs-striped tabs-top tabs-color-light"> <ion-tab class="tab-title" title="PHP"> <ion-pane> <ion-content class="padding"> <ion-item ng-repeat="dev in developers"></ion-item> </ion-content> </ion-pane> </ion-tab> <ion-tab class="tab-title" title="JS"> <ion-pane> <ion-content class="padding"> <ion-item ng-repeat="dev in developers"></ion-item> </ion-content> </ion-pane> </ion-tab> </ion-tabs> </ion-view> |
Right now, if you check the app, it looks weird, there are two tabs but it’s just plain white.
Let’s setup Sass for our project. Run ionic setup sass
.
Now, create devangelist.scss and dump this in it: This is where will we define the values of our global css variables and mixins
devangelist.scss
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
@mixin cssCalc($property, $expression) { #{$property}: calc(#{$expression}); } @mixin flexbox() { display: -webkit-box; display: -moz-box; display: -ms-flexbox; display: -webkit-flex; display: flex; } @mixin flex-wrap($value) { flex-wrap: $value; -webkit-flex-wrap: $value; } $content-bg: #EAEAEA; $content-color: #444444; $top-bar-bg: #254164; $top-bar-color: #FFFFFF; $loading-color: #FFFFFF; $main-menu-bg: #FFC900; $main-menu-color: #FFFFFF; $loading-color: #FFFFFF; $speaker-actions-bg: #FFFFFF; $workshop-bg-color: #00B454; $talk-bg-color: #FF7C00; $keynote-bg-color: #FF3900; $global-bg-color: #DDDDDD; $event-color: #FFFFFF; $get-directions-btn-bg: #419e61; $get-directions-btn-color: #FFFFFF; //App settings $category-margin: 20px; $font-size:12px; $menu-title-font-size: 30px; $venue-map-porcentage: 65; *{ color: $content-color; } .bar.app-top-bar { background-color: $top-bar-bg; .title { color: $top-bar-color !important; * { color: $top-bar-color !important; } } .button { color: $top-bar-color !important; * { color: $top-bar-color !important; } } } .menu-header-bar{ background-color: $top-bar-bg; .menu-header-bar-title{ color: $top-bar-color; } } .loading-container .loading { * { color: $loading-color; } } |
Also, create developers.scss and dump this in it:
developers.scss
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 |
.developer-view { background: $content-bg; .tabs-striped .tabs { background-color: $top-bar-bg; .tab-item { max-width: none; } } .tab-title{ color: $top-bar-color; @include cssCalc("font-size", "#{($font-size)} + 2px"); font-weight:400; } .tab-title.tab-item.tab-item-active{ border-color: $main-menu-bg; margin-top: 0px; border-width: 0px 0px 4px 0px !important; .tab-title{ font-weight:600; } } .event-content { text-decoration: none; background-color: darken($global-bg-color, 5); background-size: 73vw; background-position-y: 15%; min-height: 40vw; padding: 14px; border-radius: 5px; position: relative; background-size: 100%; &.global{ min-height: 20vw; } &.talk, &.workshop, &.keynote { margin-bottom: 25px; border-radius: 5px 5px 0px 0px; .event-title, .event-room{ color: $event-color; } } .event-title{ @include cssCalc("font-size", "#{($font-size)} + 4px"); font-weight:500; margin:0px; position:relative; z-index: 100; } .event-room{ font-size:$font-size; z-index: 100; position:relative; margin-bottom:0px; } .event-speakers { z-index: 100; position:relative; font-size:$font-size; font-weight:500; margin-bottom:0px; * { color:$event-color; } } .event-type-tag { position: absolute; bottom: -25px; left: 0px; width: 100%; border-radius: 0px 0px 4px 4px; height: 25px; line-height: 25px; padding: 0px 14px; } } } |
There are so many selectors here we will be changing through the course of this tutorial, so don’t worry if you see somethings that are odd.
Now, we need to import these files in ionic.app.scss
ionic.app.scss
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
/* To customize the look and feel of Ionic, you can override the variables in ionic's _variables.scss file. For example, you might change some of the default colors: $light: #fff !default; $stable: #f8f8f8 !default; $positive: #387ef5 !default; $calm: #11c1f3 !default; $balanced: #33cd5f !default; $energized: #ffc900 !default; $assertive: #ef473a !default; $royal: #886aea !default; $dark: #444 !default; */ // The path for our ionicons font files, relative to the built CSS in www/css $ionicons-font-path: "../lib/ionic/fonts" !default; // Include all of Ionic @import "../../../../2016_2F01_2F01_2Fbuild-your-first-mobile-app-with-ionic-part-1_2F/www/lib/ionic/scss/ionic.css"; // Include custom styles @import "../../../../2016_2F01_2F01_2Fbuild-your-first-mobile-app-with-ionic-part-1_2F/scss/devangelist.css"; @import "../../../../2016_2F01_2F01_2Fbuild-your-first-mobile-app-with-ionic-part-1_2F/scss/developers.css"; |
Can you see the custom styles?..Nice
Now, check your app, this how it should look like now:
Conclusion
Our app is been whipped into shape gradually. Take ample time to explore the components we have currently and the styles we have in the sass files.
In the next post, we will start adding logic to our controllers and also start using the GitHub API to fetch results into our app.
Please, let me know if you have any questions or observations in the comments sections.
- How to build your own Youtube – Part 10 - August 1, 2016
- How to build your own Youtube – Part 9 - July 25, 2016
- How to build your own Youtube – Part 8 - July 23, 2016
- How to build your own Youtube – Part 6 - July 6, 2016
- Introducing Laravel Password v1.0 - July 3, 2016
- How to build your own Youtube – Part 5 - June 28, 2016
- How to build your own Youtube – Part 4 - June 23, 2016
- How to build your own Youtube – Part 3 - June 15, 2016
- How to build your own Youtube – Part 2 - June 8, 2016
- How to build your own Youtube – Part 1 - June 1, 2016