基本套路:
1、先安装node,配置好npm config set cache 和npm config set prefix
2、安装android sdk 和 java 配置环境变量
3、执行npm 命令安装 npm install -g cordova 和 npm install -g ionic
4、运行 ionic start app(名字随意) 生成如下
运行 ionic build android 时 app目录下config.xml 文件里 android-minSdkVersion 的value 最小要对应 要和 安装的androidsdk 的 api 最小版本
5、ionic platform add android
6、套路最后一步 ionic run android
对于做web开发,重点的套路还是在www 文件里
接下来 套路里用到了几种撩的技术,我不是一个好的僚机,实现如下的tab切换,粗略撩吧,撩不好就撸。。。
当然小白撩的也有不对的地方,还是很明显的,希望互相帮助啦
僚机目录结构 主要用到了 angular,ionic是把angular封装了的,还有requirejs(模块载入框架)
main.js 需要的js文件
require.config({ // baseUrl:'../',paths:{ cordova:'cordova',fastclick:'../lib/fastclick',async:'../lib/async',//帮助异步引入类似下面百度地图的js domReady:'../lib/domReady',BMap:'http://api.map.baidu.com/api?v=2.0&ak=A796271dae48229367c041db82735a4c&services=false',angular:'../lib/ionic/js/angular/angular',angularAnimate:'../lib/ionic/js/angular/angular-animate',angularSanitize:'../lib/ionic/js/angular/angular-sanitize',uiRouter:'../lib/ionic/js/angular-ui/angular-ui-router',ngResource:'../lib/ionic/js/angular/angular-resource',ionic:'../lib/ionic/js/ionic',ionicAngular:'../lib/ionic/js/ionic-angular',app:'app',config:'config',services:'services/services',mainServices:'services/mainServices',indexServices:'services/indexServices',mapServices:'services/mapServices',mainCtrl:'controllers/mainCtrl',indexCtrl:'controllers/indexCtrl',sortCtrl:'controllers/sortCtrl',memberCtrl:'controllers/memberCtrl',cartCtrl:'controllers/cartCtrl',mapCtrl:'controllers/mapCtrl',controllers:'controllers/controllers',directives:'directives/directives',mainDirective:'directives/mainDirective' },waitSeconds: 40,shim:{ angular : {exports : 'angular'},angularAnimate : {deps: ['angular']},angularSanitize : {deps: ['angular']},uiRouter : {deps: ['angular']},ngResource: {deps: ['angular']},ionic : {deps: ['angular'],exports : 'ionic'},ionicAngular: {deps: ['angular','ionic','uiRouter','angularAnimate','angularSanitize','ngResource']} },priority:['angular','ionic'],deps:['bootstrap'] });
define(['app',function (app) { 'use strict'; return angular.module('app.config',['ionic']).config(function($ionicConfigProvider) { $ionicConfigProvider.platform.android.tabs.style('standard'); $ionicConfigProvider.platform.android.tabs.position('standard'); $ionicConfigProvider.platform.ios.navBar.alignTitle('center'); $ionicConfigProvider.platform.android.navBar.alignTitle('center'); $ionicConfigProvider.platform.android.views.transition('android'); $ionicConfigProvider.platform.ios.views.transition('ios'); }); });
bootstrap.js angular 初始化
define(['ionic','angular','app','routes','fastclick'],function (ionic,angular,app) { 'use strict'; var $html,onDeviceReady = function () { angular.bootstrap(document,app.name); }; document.addEventListener("deviceready",onDeviceReady,false); if (typeof cordova === 'undefined') { $html = angular.element(document.getElementsByTagName('html')[0]); angular.element().ready(function () { try { angular.bootstrap(document,[app.name]); } catch (e) { console.error(e.stack || e.message || e); } }); } window.addEventListener('load',function() { //fastclick 初始化 new FastClick(document.body); },false); });
app.js angular 创建app module
define(['angular','services','controllers','directives','ionicAngular'],function (angular,uiRouter) { 'use strict'; var app = angular.module('app',[ 'ionic','ngResource','app.controllers','app.directives','app.services','ui.router']); return app; });
define(['app'],function(app) { 'use strict'; app.config(['$stateProvider','$urlRouterProvider',function($stateProvider,$urlRouterProvider) { $stateProvider .state('tab',{ url: '/tab',abstract: true,templateUrl: 'templates/tabs.html' }) .state('tab.index',{ url: '/index',views: { 'tab-index': { templateUrl: 'templates/site/index.html',controller: 'indexCtrl' } } }) .state('tab.sort',{ url: '/sort',views: { 'tab-sort': { templateUrl: 'templates/sort/index.html',controller: 'sortCtrl' } } }) .state('tab.cart',{ url: '/cart',views: { 'tab-cart': { templateUrl: 'templates/cart/index.html',controller: 'cartCtrl' } } }) .state('tab.member',{ url: '/member',views: { 'tab-member': { templateUrl: 'templates/member/index.html',controller: 'memberCtrl' } } }) // 地图 .state('map',{ url: '/map',templateUrl: 'templates/etc/map.html',controller: 'mapCtrl' }); // if none of the above states are matched,use this as the fallback $urlRouterProvider.otherwise('/tab/index'); }]); });
angular 每一个模块需要一个总模块
controllers.js
define(['app','mainCtrl','indexCtrl','sortCtrl','memberCtrl','cartCtrl','mapCtrl','services'],function(app){ 'use strict'; var controllers = angular.module('app.controllers',['app.services','app.config']); controllers.controller('mainCtrl',require('mainCtrl')); controllers.controller('indexCtrl',require('indexCtrl')); controllers.controller('sortCtrl',require('sortCtrl')); controllers.controller('memberCtrl',require('memberCtrl')); controllers.controller('cartCtrl',require('cartCtrl')); controllers.controller('mapCtrl',require('mapCtrl')); controllers.run(['$rootScope',function($rootScope) { $rootScope.sampleParam = "value"; }]); return controllers; });
indexCtrl.js 首页 依赖 indexService
define(function () { 'use strict'; function ctrl($scope,$mainServices,$indexServices,$ionicTabsDelegate,$ionicSlideBoxDelegate) { // 加载等待中 $mainServices.showLoading(); $mainServices.hideLoding(); //首页数据 $indexServices.get(function(data){ $scope.bannerList = data.banner.item; $scope.couponList = data.coupon.item; $scope.dazheList = data.tejia.item; $scope.addr = data.addr; }); } ctrl.$inject = ['$scope','$mainServices','$indexServices','$ionicTabsDelegate','$ionicSlideBoxDelegate']; return ctrl; });
mapCtrl.js
define(function () { 'use strict'; function ctrl($scope,$mapServices) { $mapServices.goFunc(); } ctrl.$inject = ['$scope','$mapServices']; return ctrl; });
mainCtrl.js 个模块都需要用的ctrl,包括 底部more 显示隐藏
define(function () { 'use strict'; function ctrl($scope,$ionicTabsDelegate) { $scope.tabmore = { show: false }; $scope.header = { show: true }; // more 隐藏显示 $scope.showToggle = function(target){ $scope[target].show = !$scope[target].show; }; } ctrl.$inject = ['$scope','$ionicTabsDelegate']; return ctrl; });
services.js
define(['app','config','mainServices','indexServices','mapServices'],function (app) { 'use strict'; var config = require('config'),services = angular.module('app.services',['app.config','ngResource']); services.factory('$mainServices',require('mainServices')); services.factory('$mapServices',require('mapServices')); services.service('$indexServices',require('indexServices')); return services; });
define(function(){ 'use strict' var service = function($http){ return { get:function(callback){ $http.get('json/index.json').success(function(data){ return callback(data); }); } } }; service.$inject = ['$http']; return service; });
请求的 json 数据如下 随意写的 当然暂时 有的没用到
{ "banner": { "item":[ { "img":"a.jpg","url":"www.baidu.com" },{ "img":"b.jpg","url":"http://www.sina.com.cn/" },{ "img":"c.jpg","url":"http://www.qq.com/" } ] },"addr":{ "nowaddr":{ "longitude":104.061854,"latitude":34.645081,"name":"成都" },"item":[ { "longitude":104.061854,"name":"成都" },{ "longitude":114.392543,"latitude":33.848829,"name":"哈哈" },{ "longitude":204.061854,"latitude":40.645081,"name":"中国" },{ "longitude":110.187771,"latitude":40.575614,{ "longitude":114.264138,"latitude":34.891853,"name":"嘿嘿" },{ "longitude":113.971186,"latitude":90.82062,"name":"太平洋" } ] },"coupon": { "item": [ { "time": "2016.01.01-2017.05.14","money": 787,"use": 7878,"isGet": 0,"url": "http://www.qq.com/" },{ "time": "2016.01.01-2017.05.14 ","isGet": 1,"url": "http://www.qq.com/" } ] },"dazhe": { "item": [ { "url": "http://www.qq.com/","jiage": 1000,"use": 1200 },{ "url": "http://www.qq.com/","jiage": 1800,"use": 12200 } ] },"tejia": { "item": [ { "url": "http://www.qq.com/","img": "t.png","name": "玉皇大帝","nowMoney": 40,"oldMoeny": 45 },"img": "y.png","oldMoeny": 45 } ] },"tuijian": { "item": [ { "url": "http://www.qq.com/","img": "e.png","name": "你好" },"img": "c.png","img": "b.png","name": "nimei" },"img": "a.jpg","name": "kao" } ] } }
define(['domReady','async!BMap'],function(domReady){ 'use strict' var factory = function(){ var map = new BMap.Map("bmap"); map.centerAndZoom(new BMap.Point(116.404,39.915),12); map.enableScrollWheelZoom(); var start = "魏公村",end = "百度大厦"; var transit = new BMap.TransitRoute(map,{ renderOptions: {map: map} }); transit.search(start,end); var myIcon = new BMap.Icon("http://developer.baidu.com/map/jsdemo/img/location.gif",new BMap.Size(14,23)); return { goFunc:function(){ //设置起终点图标 transit.setMarkeRSSetCallback(function(result){ result[0].marker.setIcon(myIcon); result[1].marker.setIcon(myIcon); }) } } } factory.$inject = []; return factory; });
directives
define(['app','mainDirective'],function(app){ 'use strict'; var directives = angular.module('app.directives',['app.services']); //tabs tabMore 当然这样做 是不对的 在tabs.html 写data-src {'test1':'www.baidu.com','test2':'www.imooc.com'}" directives.directive('tabMore',[function(){ return { restrict:'A',replace:false,link:function(scope,element,attrs){ let src = JSON.parse(attrs.src.replace(/'/g,"\"")); let htmlStr=''; for(let i in src){ htmlStr += '<a href="'+ src[i] +'">'+ i +'</a>'; } angular.element(document.querySelector('#tabsmore')).append(htmlStr); } }; }]); //地图 directives.directive('goaddr',[function(){ return { restrict: 'A',replace: false,attrs){ } } }]); return directives; });
html
index.html
<!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>TEST</title> <link type="text/css" href="lib/ionic/css/ionic.css" rel="stylesheet"> <link rel="stylesheet" href="css/index.css"> </head> <body ng-controller="mainCtrl as mc"> <ion-header-bar class="bar bar-header" ng-show="header.show"> <a href="javascript:;" class="icon-right ion-arrow-down-b button button-clear" ng-click="showToggle('header')">成都</a> <label class="item item-input stable-dark icon ion-search"> <input type="search" class="dark" placeholder="search"/> </label> </ion-header-bar> <ion-nav-view></ion-nav-view> <script src='cordova.js'></script> <script data-main="js/main" src="lib/require.js"></script> </body> </html>
tabs.html
<ion-tabs class="tabs-icon-top tabs-color-active-positive"> <ion-tab title="首页" icon-off="ion-ios-home-outline" icon-on="ion-ios-home" href="#/tab/index"> <ion-nav-view name="tab-index"></ion-nav-view> <!-- name 对应路由 tab-index --> </ion-tab> <ion-tab title="分类" icon-off="ion-ios-keypad-outline" icon-on="ion-ios-keypad" href="#/tab/sort"> <ion-nav-view name="tab-sort"></ion-nav-view> </ion-tab> <ion-tab title="购物车" icon-off="ion-ios-cart-outline" icon-on="ion-ios-cart" href="#/tab/cart"> <ion-nav-view name="tab-cart"></ion-nav-view> </ion-tab> <ion-tab title="会员" icon-off="ion-ios-person-outline" icon-on="ion-ios-person" href="#/tab/member"> <ion-nav-view name="tab-member"></ion-nav-view> </ion-tab> <ion-tab title="更多" icon-on="ion-ios-more-outline" tab-More="tab-More" icon-off="ion-ios-more" src="{'test1':'www.baidu.com','test2':'www.imooc.com'}" ng-click="showToggle('tabmore')" > <!-- <ion-nav-view></ion-nav-view> --> </ion-tab> <div class="tabsmore" id="tabsmore" ng-show="tabmore.show"></div> </ion-tabs>
site/index.html 首页
<ion-view> <!-- overflow-scroll='false' 安卓端滚动 效果css3--> <ion-content class="has-header" overflow-scroll='false'> <ion-slide-Box auto-play="true" does-continue="true" slide-interval="2000"> <ion-slide ng-repeat="b_item in bannerList" > <a href="{{b_item.url}}" > <img ng-src="{{b_item.img}}" class="full-image"> </a> </ion-slide> </ion-slide-Box> <div class="pane-list row addr-now"> <span ng-bind="addr.nowaddr.name" ></span> <!-- goaddr 地图指令 --> <a class="addr-get" goaddr="goaddr" href="#/map" data-latitude="{{addr.nowaddr.latitude}}" data-longitude="{{addr.nowaddr.longitude}}"> 导航<em class="addr-icon"></em> </a> </div> <div class="pane-list"> <ul class="row justify coupon-list"> <li class="item coupon-item" ng-repeat="coupon_item in couponList"> <div class="coupon-con "> <div class="row justify"> <div class="coupon-avatar"> <img src="images/store_coupon.png"> </div> <div class="coupon-msg"> <p class="coupon_jg">¥{{coupon_item.money}}</p> <p class="coupon_tj">满{{coupon_item.use}}使用</p> </div> </div> <p class="coupon-line"></p> <time class="coupon-time" ng-bind="coupon_item.time"></time> </div> </li> </ul> <a href="#" class="row coupon-more center">更多好券,去优惠券中心看看<em></em></a> </div> <div class="pane-list pane-list-te"> <div class="pane-list-top row"> <em>特</em> <h3>本周特价</h3> <a href="" class="pane-list-top-btn">查看更多</a> </div> <ul class="row"> <li class="col col-50" ng-repeat="t_item in dazheList"> <a href="{{t_item.url}}"> <img ng-src="{{t_item.img}}"> </a> <p class="pane-list-te-name" ng-bind="t_item.name"></p> <div> <span class="pane-list-te-nm" ng-bind="'¥'+t_item.nowMoney"></span> <span class="pane-list-te-om" ng-bind="'¥'+t_item.oldMoeny"></span> </div> </li> </ul> </div> <div class="addr-list" ng-show="!header.show"> <div class="addr-title"> <a href="javascript:;" class="cancel" ng-click="showToggle('header')"></a> 切换 </div> <ion-list> <ion-item ng-repeat="addr_item in addr.item" ng-bind="addr_item.name" data-latitude="{{addr_item.latitude}}" data-longitude="{{addr_item.longitude}}"> </ion-item> </ion-list> </div> </ion-content> </ion-view>
css
@media only screen and (max-device-width: 320px) and (orientation: portrait){ .coupon-time { display: block; position: relative; width: 140px; transform: scale(0.85); left: -7px; } } .pane { background-color: #f0f0f0; } ins,a { text-decoration: none; } .ionic-logo { display: block; margin: 15px auto; width: 96px; height: 96px; } .u-list{ margin-top: 5px; margin-bottom: 0; background-color: #ffffff; } .u-title{ padding: 4px 2.66666667%; } .row{ padding: 0; } .u-list .col-33{ margin: 0 0.5%; } .u-list .col-33 img{ max-width: 100%; } .u-list .col-33{ text-align: center; } .row.item{ border: 0; } .pane-list { background-color: #ffffff; padding: 10px 0; margin-bottom: 10px; } .prefix{ display: block; font-size: 12px; height: 14px; width: 14px; color: #fff; text-align: center; line-height: 14px; float: left; margin: 3px 4px 0 0; background-color: #4198f7; } .justify{ -webkit-Box-pack: justify; Box-pack: justify; justify-content: space-around; -webkit-justify-content: space-around; } .center { -webkit-Box-align: center; -moz-Box-align: center; -ms-flex-pack: center; -webkit-justify-content: center; -moz-justify-content: center; justify-content: center; -webkit-Box-pack: center; -moz-Box-pack: center; -ms-flex-align: center; -webkit-align-items: center; -moz-align-items: center; align-items: center; } .bar-header{ background-color: #ff332a; } .bar-footer{ background-color: #333333; } .bar-header .button-clear.button{ font-size: 13px; color: #ffffff; } .bar.bar-header .button.button-clear:before{ font-size: inherit; } .bar-header .item-input{ border: 1px solid #dcdcdc; border-radius: 5px; width: 70%; margin-left: 5%; } .bar-header .ion-search:before{ margin-right: 5px; color: inherit; color: #b2b2b2; } .slider-pager .slider-pager-page { color: #ff332a; } .tabs-icon-top > .tabs .tab-item { color: #ffffff; } .tabs-icon-top.tabs-color-active-positive .tab-item.tab-item-active { color: #ff332a; } .tab-nav.tabs .tab-item.activated { color: #ffffff; } .tab-nav.tabs { background-color: #333333; padding: 4px 0; height: 54px; } .tabsmore { position: absolute; background-color: #404040; width: 100px; right: 0px; bottom: 53px; text-align: left; overflow: hidden; } .tabsmore a { font-size: 13px; color: #cccccc; overflow: hidden; line-height: 34px; display: block; padding: 0 6px 0 10px; border-bottom: 1px solid #333333; } .coupon-item.item{ border: 0; padding: 0; -webkit-border-radius: 8px; -moz-border-radius: 8px; -ms-border-radius: 8px; -o-border-radius: 8px; border-radius: 8px; overflow: hidden; width: 47%; background: url('/images/yhq_b.png') no-repeat right center; background-size: contain; padding-right: 34.5px; } .coupon-con { height: 88px; background-color: #ffffff; Box-sizing: border-Box; padding: 4px 0 0 2%; border: 1px solid #dadada; border-right: none; border-top-left-radius: 8px; border-bottom-left-radius: 8px; flex: 10; background-repeat: no-repeat; background-position: right top; background-size: 70px auto; } .coupon-avatar img{ margin-right: 2px; width: 45px; min-width: 30px; display: block; -webkit-border-radius: 50%; -moz-border-radius: 50%; -ms-border-radius: 50%; -o-border-radius: 50%; border-radius: 50%; margin: 0 auto; } .item .coupon_jg{ font-size: 19px; text-align: left; color: #3991f2; } .item .coupon_tj{ background-color: #88bdf7; height: 14px; line-height: 14px; padding: 0 5px; font-size: 12px; color: #fff; -webkit-border-radius: 4px; -moz-border-radius: 4px; -ms-border-radius: 4px; -o-border-radius: 4px; border-radius: 4px; overflow: hidden; white-space: nowrap; } .coupon-line{ height: 4px; margin-top: 6px; background: url('/images/yhq_yd.png') repeat-x center center; background-size: contain; } .coupon-time{ color: #707070; font-size: 12px; margin-top: 1px; } .coupon-more.center{ font-size: 14px; color: #ff4a4a; margin-top: 15px; text-align: center; } .coupon-more em { display: block; width: 29px; height: 17px; background: url('/images/icon_go.png') no-repeat center center; background-size: contain; margin-left: 1.5%; animation: morego 2s ease-in-out infinite; -webkit-animation: morego 2s ease-in-out infinite; transform: translateX(0); -webkit-transform: translateX(0); opacity: 0.1; } @keyframes morego { form { transform: translateX(5px); -moz-transform: translateX(5px); -o-transform: translateX(5px); -webkit-transform: translateX(5px); opacity:0.1; } to { transform: translateX(12px); -moz-transform: translateX(12px); -o-transform: translateX(12px); -webkit-transform: translateX(12px); opacity:1; } } @-webkit-keyframes morego { form { transform: translateX(5px); -moz-transform: translateX(5px); -o-transform: translateX(5px); -webkit-transform: translateX(5px); opacity:0.1; } to { transform: translateX(12px); -moz-transform: translateX(12px); -o-transform: translateX(12px); -webkit-transform: translateX(12px); opacity:1; } } .pane-list-top{ overflow: hidden; padding: 0 2.66666667%; margin-bottom: 8px; } .pane-list-top em { display: block; font-size: 12px; height: 14px; width: 14px; text-align: center; line-height: 14px; margin: 3px 4px 0 0; color: #fff; } .pane-list-top h3{ padding: 0; margin: 0; font-size:17px; flex: 1; } .pane-list-top-btn{ font-size: 12px; text-align: center; height: 18px; line-height: 18px; padding: 0 6px; -webkit-border-radius: 5px; -moz-border-radius: 5px; -ms-border-radius: 5px; -o-border-radius: 5px; border-radius: 5px; color: #ffffff; margin-top: 1px; } .pane-list-te .pane-list-top em{ background-color: #ff332a; } .pane-list-te .pane-list-top-btn{ background-color: #ff332a; } .pane-list-te .row{ flex-wrap: wrap; } .pane-list-te ul a { text-align:center; display: block; height: 110px; } .pane-list-te ul img{ max-height: 100%; max-width: 100%; } .pane-list-te-name{ display: -webkit-Box; display: -moz-Box; overflow: hidden; text-overflow: ellipsis; word-break: break-all; -webkit-Box-orient: vertical; -webkit-line-clamp: 2; margin: 6px 0 5px; font-size: 13px; color: #595959; } .pane-list-te-nm { font-size: 14px; color: #ff332a; } .pane-list-te-om { color: #b2b2b2; font-size: 12px; text-decoration: line-through; padding-left: 4px; } .addr-now { padding: 10px 1.66666667%; justify-content: space-between; -webkit-justify-content: space-between; } .addr-now span{ display: block; max-width: 72.5%; color: #666666; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; } .addr-get{ width: 56px; font-size: 14px; color: #f352a5; position: relative; } .addr-icon{ display: block; position: absolute; transform: rotateX(10deg) rotateZ(20deg); -moz-transform: rotateX(10deg) rotateZ(20deg); -o-transform: rotateX(10deg) rotateZ(20deg); -webkit-transform: rotateX(10deg) rotateZ(20deg); top: -1px; right: 4%; background: url('/images/icon_navigationr.png') no-repeat center center; background-size: contain; height: 22px; width: 22px; animation: navigationicon 1.5s linear infinite alternate; -webkit-animation: navigationicon 1.5s linear infinite alternate; } @keyframes navigationicon { form { transform: rotateX(0deg) rotateZ(0deg); -moz-transform: rotateX(0deg) rotateZ(0deg); -o-transform: rotateX(0deg) rotateZ(0deg); -webkit-transform: rotateX(0deg) rotateZ(0deg); } to { transform: rotateX(50deg) rotateZ(70deg); -moz-transform: rotateX(50deg) rotateZ(70deg); -o-transform: rotateX(50deg) rotateZ(70deg); -webkit-transform: rotateX(50deg) rotateZ(70deg); } } @-webkit-keyframes navigationicon { form { transform: rotateX(0deg) rotateZ(0deg); -moz-transform: rotateX(0deg) rotateZ(0deg); -o-transform: rotateX(0deg) rotateZ(0deg); -webkit-transform: rotateX(0deg) rotateZ(0deg); } to { transform: rotateX(50deg) rotateZ(70deg); -moz-transform: rotateX(50deg) rotateZ(70deg); -o-transform: rotateX(50deg) rotateZ(70deg); -webkit-transform: rotateX(50deg) rotateZ(70deg); } } .addr-list { position: absolute; top: 0; background-color: #ffffff; min-height: 100%; width: 100%; z-index: 9; } .addr-title{ font-size: 19px; color: #000000; text-align: center; line-height: 44px; height: 44px; border-bottom: 1px solid #dcdcdc; background-color: #f5f5f5; position: relative; } .cancel{ position: absolute; top: 2px; height: 40px; width: 28px; background: url('/images/icon_search.png') no-repeat center -19px; background-size: 18px 75.15px; left: 2.66666667%; }