探索ionic轮播
ionic轮播自带标签
在ionic做的第一个轮播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<ion-view view-title="欢迎">
<ion-slide-box on-slide-changed="slideChanged(index)">
<ion-slide>
<h3>欢迎使用EffectWork</h3>
<div id="logo">
<img src="img/effectwork.jpeg" alt="加载失败">
</div>
<p>
专门为时间打造
</p>
<p>
开始我们每天的任务
</p>
</ion-slide>
<ion-slide>
<h3>我们一起出发</h3>
<div id="list">
<h5>时间</h5>
<ol>
<li>生活要以快乐为基准爱情要以互惠为原则</li>
<li>爱情不是空中楼阁,它是需要强大的物质基础来做地基做保障的。</li>
<li>时间一直在这里,流逝的是我们自己。</li>
</ol>
</div>
</ion-slide>
<ion-slide>
<h3>来到我的时间</h3>
<p>
不要浪费你的生命在你一定会后悔的地方上。
</p>
<div class="login">
<button class="button button-outline button-positive" ng-click="log()">登录</button>
<button class="button button-outline button-positive" ng-click="reg()">注册</button>
</div>
</ion-slide>
</ion-slide-box>
</ion-view>
利用了
探索ionic视图设定
这个可以称前端的视图路由
我采用了$urlRouterProvider,$stateProvider两个服务进行视图路由及视图与控制器的绑定。
具体代码如下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
42angular.module('EffectWork.routes',[])
.config(function($urlRouterProvider,$stateProvider){
$stateProvider
//欢迎界面
.state('splash', { //splash路由名称
url: '/splash', //前端路由一般就是#/splash
cache: false, //是否缓存
templateUrl: 'views/splash_screen/splash.html', //视图
controller: 'splashCtrl' //控制器
})
.state('login',{
url:'/login',
templateUrl:'views/login.html',
controller:'loginCtrl'
})
.state('register',{
url:'/register',
templateUrl:'views/register.html',
controller:'registerCtrl'
})
.state('forget',{
url:'/forget',
templateUrl:'views/forget.html',
controller:'forgetCtrl'
})
.state("tab", {
url: "/tab",
abstract: true,
templateUrl: "views/tabs.html",
controller:"tabCtrl"
})
.state('tab.home', {
url: '/home',
views: {
'tab-home': {
templateUrl: 'views/tab-home.html',
controller: "homeCtrl"
}
}
})
$urlRouterProvider.otherwise("/splash"); //默认前端路由/splash
})
路由跳转
采用$state服务
利用$state服务的go()方法,参数为指定路由名称。
具体代码如下:1
2
3
4
5
6
7
8
9angular.module('EffectWork.controllers')
.controller('splashCtrl',['$scope','$state',function($scope,$state){
$scope.log=function(){
$state.go('login');
};
$scope.reg=function(){
$state.go('register');
};
}])
关于键盘窗口挡住输入框
我所有的输入表单都用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<ion-view view-title="找回密码">
<div class="bar bar-header bar-calm">
<h1 class="title">找回密码</h1>
</div>
<ion-content class="rj-stable-content" delegate-handle="findPwd" id="findPassword">
<div class="list list-inset has-header">
<label class="item item-input">
<input type="text" placeholder="手机号">
</label>
<label class="item item-input">
<input type="password" placeholder="密码">
</label>
<label class="item item-input">
<input type="password" placeholder="再次输入密码">
</label>
<label class="item item-input item-input-inset">
<input type="text" placeholder="输入验证码">
<button class="button button-outline button-calm" style="height:10px;">
获取验证码
</button>
</label>
<button class="button button-block button-calm" ng-click="findPwd()">
找回密码
</button>
<button class="button button-clear button-positive" style="text-decoration:underline;" ng-click="backLogin()">
返回
</button>
</div>
</ion-content>
</ion-view>
关于ionic上拉菜单样式问题
ionic上拉菜单样式会有一些问题,导致很不好看,具体做法是把我下面的代码加入style.css1
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.platform-android .action-sheet-backdrop {
-webkit-transition: background-color 150ms ease-in-out;
transition: background-color 150ms ease-in-out;
position: fixed;
top: 0;
left: 0;
z-index: 11;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0);
}
.platform-android .action-sheet-backdrop.active {
background-color: rgba(0, 0, 0, 0.4);
}
.platform-android .action-sheet-wrapper {
-webkit-transform: translate3d(0, 100%, 0);
transform: translate3d(0, 100%, 0);
-webkit-transition: all cubic-bezier(0.36, 0.66, 0.04, 1) 500ms;
transition: all cubic-bezier(0.36, 0.66, 0.04, 1) 500ms;
position: absolute;
bottom: 0;
left: 0;
right: 0;
width: 100%;
max-width: 500px;
margin: auto;
}
.platform-android .action-sheet-up {
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
.platform-android .action-sheet {
margin-left: 8px;
margin-right: 8px;
width: auto;
z-index: 11;
overflow: hidden;
}
.platform-android .action-sheet .button {
display: block;
padding: 1px;
width: 100%;
border-radius: 0;
border-color: #d1d3d6;
background-color: transparent;
color: #007aff;
font-size: 21px;
}
.platform-android .action-sheet .button:hover {
color: #007aff;
}
.platform-android .action-sheet .button.destructive {
color: #ff3b30;
}
.platform-android .action-sheet .button.destructive:hover {
color: #ff3b30;
}
.platform-android .action-sheet .button.active, .platform-android .action-sheet .button.activated {
box-shadow: none;
border-color: #d1d3d6;
color: #007aff;
background: #e4e5e7;
}
.platform-android .action-sheet-has-icons .icon {
position: absolute;
left: 16px;
}
.platform-android .action-sheet-title {
padding: 16px;
color: #8f8f8f;
text-align: center;
font-size: 13px;
}
.platform-android .action-sheet-group {
margin-bottom: 8px;
border-radius: 4px;
background-color: #fff;
overflow: hidden;
}
.platform-android .action-sheet-group .button {
border-width: 1px 0px 0px 0px;
}
.platform-android .action-sheet-group .button:first-child:last-child {
border-width: 0;
}
.platform-android .action-sheet-options {
background: #f1f2f3;
}
.platform-android .action-sheet-cancel .button {
font-weight: 500;
}
.platform-android .action-sheet-open {
pointer-events: none;
}
.platform-android .action-sheet-open.modal-open .modal {
pointer-events: none;
}
.platform-android .action-sheet-open .action-sheet-backdrop {
pointer-events: auto;
}
.platform-android .action-sheet .action-sheet-title, .platform-android .action-sheet .button {
text-align: center;
}
.platform-android .action-sheet-cancel {
display: block;
}
即可解决
关于标签
利用ionic
具体代码如下1
2
3
4
5
6
7
8
9
10
11
12
13
14<ion-tabs class="tabs-icon-top tabs-color-active-balanced">
<ion-tab title="首页" icon-on="ion-ios-home positive" icon-off="ion-ios-home-outline" ui-sref="tab.home">
<ion-nav-view animation="slide-left-right" name="tab-home"></ion-nav-view>
</ion-tab>
<ion-tab title="番茄钟" icon-on="ion-ios-clock positive" icon-off="ion-ios-clock-outline" ui-sref="tab.school">
<ion-nav-view animation="slide-left-right" name="tab-school"></ion-nav-view>
</ion-tab>
<ion-tab title="消息" icon-on="ion-ios-chatbubble positive" icon-off="ion-ios-chatbubble-outline" ui-sref="tab.message">
<ion-nav-view animation="slide-left-right" name="tab-message"></ion-nav-view>
</ion-tab>
<!-- <ion-tab title="我的" icon-on="ion-ios-person positive" icon-off="ion-ios-person-outline">
<ion-nav-view animation="slide-left-right" name="tab-me"></ion-nav-view>
</ion-tab> -->
</ion-tabs>
关于ionic侧栏菜单
利用ionic
具体代码如下: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<ion-side-menus>
<ion-side-menu-content drag-content="true">
<ion-header-bar align-title="center" class="bar-stable bar-calm">
<div class="buttons">
<button class="button no-animation button-icon icon ion-ios-list-outline" ng-click="toggleLeft()">
</button>
</div>
<div class="wodivh1 title">EffectWork</div>
<div class="buttons">
<button class="button no-animation button-icon icon ion-ios-plus-outline">
</button>
</div>
</ion-header-bar>
<ion-tabs class="tabs-icon-top tabs-color-active-balanced">
<ion-tab title="首页" icon-on="ion-ios-home positive" icon-off="ion-ios-home-outline" ui-sref="tab.home">
<ion-nav-view animation="slide-left-right" name="tab-home"></ion-nav-view>
</ion-tab>
<ion-tab title="番茄钟" icon-on="ion-ios-clock positive" icon-off="ion-ios-clock-outline" ui-sref="tab.school">
<ion-nav-view animation="slide-left-right" name="tab-school"></ion-nav-view>
</ion-tab>
<ion-tab title="消息" icon-on="ion-ios-chatbubble positive" icon-off="ion-ios-chatbubble-outline" ui-sref="tab.message">
<ion-nav-view animation="slide-left-right" name="tab-message"></ion-nav-view>
</ion-tab>
<!-- <ion-tab title="我的" icon-on="ion-ios-person positive" icon-off="ion-ios-person-outline">
<ion-nav-view animation="slide-left-right" name="tab-me"></ion-nav-view>
</ion-tab> -->
</ion-tabs>
</ion-side-menu-content>
<ion-side-menu side="left" width="280" style="background-color:#4a87ee;">
<ion-content class="rj-stable-content" delegate-handle="sideScroll" id="userRegister">
<img class="radioImg" src="img/effectwork.jpeg">
<div class="row">
<div class="col col-33 col-top"></div>
<div class="col col-33 col-center word">{{name}}</div>
<div class="col col-33 col-bottom"><span class="badge badge-calm">签到</span></div>
<div class="col"><br><br><br></br></br></div>
</div>
</br>
<div class="row">
<div class="col word">金币:{{money}}</div>
</div>
<div class="row">
<div class="col word">签名:时间一直在这里,流逝的是我们自己。</div>
</div>
<div class="list">
<button class="item button icon-left ion-ios-cog-outline button-calm button-block">我的资料</button>
<button class="item button icon-left ion-ios-browsers-outline button-calm button-block">任务箱</button>
<button class="item button icon-left ion-ios-filing-outline button-calm button-block">统计情况</button>
<button class="item button icon-left ion-ios-paper-outline button-calm button-block">设置</button>
</div>
</ion-content>
</ion-side-menu>
</ion-side-menus>
关于angularjs控制器传递数据
这个我现在不是特别全面,我目前采用的是\$rootScope和angularjs服务依赖注入传递数据,为什么用这两种,第一是\$rootScope的作用域,第二是服务在整个应用中的生命周期。肯定还有其他方法,可以去尝试。还有一种方法是通过$state传递参数,但是我屡试不爽。这个没做成功。
关于cordova插件制作
我说这个是因为我觉得光用别人的插件,有好多限制啊,所以我想自己做。但是这个要做的话,要对Android,ios,windowsIphone开发要了解一点。
1、先说一下搭建cordova插件开发的环境吧
nodejs肯定是要安装的
然后全局安装cordova1
npm install -g cordova
另外Android sdk肯定是要安装的,因为我们就是针对Android的sdk进行第三方开发。
如果都安装好了,让我们开始吧!
2、创建第一个应用1
cordova create hello com.cool.hello HelloWorld
又是helloworld,你好世界!
让我来解释一下参数吧
第一个参数hello表示在工程目录中创建一个 hello 的文件夹
第二个参数com.cool.hello表示包名(反向域名),用于标志不同的 app
第三个参数HelloWorld表示项目的名称,可以在 config.xml 文件中修改
3、添加平台
进入创建的项目目录
查看已有的凭条1
$ cordova platforms list
添加所需要的平台1
$ cordova platform add android
如果想移除已经添加的平台的话cordova platform remove android 或者cordova platform rm android
4、编译项目
编译项目命令1
$ cordova build android
5、运行项目1
$ cordova run android
6、前面都是测试,我们这才开始插件开发
安装pluman1
$ npm install -g plugman
plugman安装完之后就可以创建一个插件了1
$ cordova plugin plugman create --name --plugin_id --plugin_version [--path] [--variableName=VALUE]
解释参数:
pluginName: 插件名字
pluginID: 插件id, egg:coolPlugin
oversion: 版本, egg : 0.0.1
directory:一个绝对或相对路径的目录,该目录将创建插件项目
variable NAME=VALUE: 额外的描述,如作者信息和相关描述
生成插件的目录1
2
3
4
5
6
7
8
9ExtraInfo
├── src
| ├── android
| | └── ExtraInfo.java
| ├── ios
| └── ...
├── www
| └── ExtraInfo.js
└── plugin.xml
这里的 src 对应不同的平台,www 放我们的 javascript 文件,plugin.xml 是插件的配置文件。
接下来就说配置文件plugin.xml1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<plugin id="cn.net.wenzhixin.cordova" version="0.0.1"
xmlns="http://apache.org/cordova/ns/plugins/1.0"
xmlns:android="http://schemas.android.com/apk/res/android">
<name>ExtraInfo</name>
<description>Description</description>
<js-module name="ExtraInfo" src="www/ExtraInfo.js">
<clobbers target="cordova.plugins.ExtraInfo"/>
</js-module>
<platform name="android">
<config-file parent="/*" target="res/xml/config.xml">
<feature name="ExtraInfo">
<param name="android-package" value="cn.net.wenzhixin.cordova.ExtraInfo"/>
</feature>
</config-file>
<source-file src="src/android/ExtraInfo.java" target-dir="src/cn/net/wenzhixin/cordova"/>
</platform>
</plugin>
有几个关键的字段需要解释下:
- id: 插件的标识,即发布到 plugins.cordova.io 的 ID
- name:插件的名称
- description:描述信息
- js-module:对应我们的 javascript 文件,src 属性指向 www/ExtraInfo.js
- platform:支持的平台,这里仅仅用到了 android
下面这句1
2
3<js-module src="www/barcodescanner.js" name="BarcodeScanner">
<clobbers target="cordova.plugins.barcodeScanner" />
</js-module>
这里很重要, 它指明了 插件的原始 js 文件放在哪里,clobbers target有用。等会用到,这会我们把它叫做 clobbers1
2
3
4
5
6<config-file parent="/*" target="res/xml/config.xml">
<feature name="ExtraInfo">
<param name="android-package" value="cn.net.wenzhixin.cordova.ExtraInfo"/>
</feature>
</config-file>
<source-file src="src/android/ExtraInfo.java" target-dir="src/cn/net/wenzhixin/cordova"/>
这里是插件的配置信息,最后会添加到 res/xml/config.xml 文件中,并且将我们的 src/android/ExtraInfo.java,复制到 android 的 package 包中。
feature name=”BarcodeScanner” 表示服务名为BarcodeScanner 。 记住这个服务名,有用.
value=”HXBarcodeScanner” 对应的.m文件中插件的类名
helloPlugin.js配置1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22var exec = require('cordova/exec');
var myFunc = function(){};
// arg1:成功回调
// arg2:失败回调
// arg3:将要调用类配置的标识
// arg4:调用的原生方法名
// arg5:参数,json格式
myFunc.prototype.showToast=function(success, error) {
exec(success, error, "CoolToast", "showToast", []);
};
myFunc.prototype.showshowToast=function(text, lenth,success, error) {
exec(success, error, "CoolToast", "showshowToast", [text, lenth]);
};
myFunc.prototype.openActivity=function() {
exec(null, null, "CoolToast", "openActivity", []);
};
var showt = new myFunc();
module.exports = showt;
最后还有一个java类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
47package com.cool.toast;
import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaPlugin;
import org.json.JSONArray;
import org.json.JSONException;
import com.example.hello.TestActivity;
import android.content.Intent;
import android.widget.Toast;
public class ShowToast extends CordovaPlugin {
public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
// TODO Auto-generated method stub
if("showToast".equals(action)){
Toast.makeText(cordova.getActivity(), "show...", Toast.LENGTH_SHORT).show();
callbackContext.success("success");
return true;
}else if("showshowToast".equals(action)){
String str = args.getString(0);
int len = args.getInt(1);
if(len == 0){
Toast.makeText(cordova.getActivity(), str, Toast.LENGTH_SHORT).show();
callbackContext.success("success" + str);
return true;
}else{
Toast.makeText(cordova.getActivity(), str, Toast.LENGTH_LONG).show();
callbackContext.success("success" + str);
return true;
}
}else if("openActivity".equals(action)){
openActivity();
callbackContext.success("success");
return true;
}
callbackContext.error("error");
return false;
}
private void openActivity() {
Intent intent = new Intent(cordova.getActivity(),TestActivity.class);
cordova.getActivity().startActivity(intent);
}
}
继承了 CordovaPlugin 类,并重写 execute 方法,使用 action 来判断我们在 javascript 中调用的方法名,成功的话调用 callbackContext.success(message),失败调用 callbackContext.error(message) 方法,分别对应 javascript 文件中的 success 和 error 回调函数。
当然,这里只用到 android 平台,其他的平台也是一样的,ios 使用 object-c、wp7 使用 c# 语言,例子见Plugin Development Guide。
7、插件安装
我的插件所在的路径是F:\CoolPlugin
首先切换到最初创建的hello目录 cd hello
执行插件安装命令cordova plugin addF:\CoolPlugin
执行完之后你就发现插件已经安装上去了
8、插件的使用1
2
3
4
5
6
7
8cool.toast.showToast();
cool.toast.showshowToast("hello",0, function(msg) {
alert(msg);
}, function(msg) {
alert(msg);
});
cool.toast.openActivity();
这样就可以成功调用了。
7、最后还是说说这个插件开发
我认为就分两个
一个是JavaScript interface1
2
3
4
5cordova.exec(function(winParam) {},
function(error) {},
"service",
"action",
["firstArgument", "secondArgument", 42, false]);
参数意义:1.成功的回调函数
2.失败的回调函数
3.native端的名称
4.native端的action名称
5.参数
这是翻译的,看一下原文
- function(winParam) {}: A success callback function. Assuming yourexec call completes successfully, this function executes alongwith any parameters you pass to it.
- function(error) {}: An error callback function. If the operationdoes not complete successfully, this function executes with anoptional error parameter.
- “service”: The service name to call on the native side. Thiscorresponds to a native class, for which more information isavailable in the native guides listed below.
- “action”: The action name to call on the native side. Thisgenerally corresponds to the native class method. See the nativeguides listed below.
- [/ arguments /]: An array of arguments to pass into the nativeenvironment.
官方示例:1
2
3
4
5window.echo = function(str, callback) {
cordova.exec(callback, function(err) {
callback('Nothing to echo.');
}, "Echo", "echo", [str]);
};
1 | window.echo("echome", function(echoValue) { |
第二个就是native interface
上面说的都是Android的这里说IOS吧
首先,是config.xml文件中需要配置1
2
3
4
5
6
7<platform name="ios">
<config-file target="config.xml" parent="/*">
<feature name="Echo">
<param name="ios-package" value="Echo" />
</feature>
</config-file>
</platform>
注意点:1.feature name要与exec中的service对应
2.param value要与exec中的action对应
3.param name要写成ios-package
其次,object-c的class要继承CDVPlugin
官方示例: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/********* Echo.h Cordova Plugin Header *******/
@interface Echo : CDVPlugin
- (void)echo:(CDVInvokedUrlCommand*)command;
@end
/********* Echo.m Cordova Plugin Implementation *******/
@implementation Echo
- (void)echo:(CDVInvokedUrlCommand*)command
{
CDVPluginResult* pluginResult = nil;
//获取exec中传过来的参数
NSString* echo = [command.arguments objectAtIndex:0];
if (echo != nil && [echo length] > 0) {
//返回成功,messageAsString将数据返回到JavaScript。
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:echo];
} else {
//返回失败。
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR];
}
//将结果发送给<code>self.commandDelegate</code>,这样会执行JavaScript side的成功或失败方法。
[self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
} @end
这就是cordova插件开发。
关于tabs无法置底的问题
在应用的.config1
2
3
4$ionicConfigProvider.platform.ios.tabs.style('standard');
$ionicConfigProvider.platform.ios.tabs.position('bottom');
$ionicConfigProvider.platform.android.tabs.style('standard');
$ionicConfigProvider.platform.android.tabs.position('standard');
关于ionic退回按钮
代码如下: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$ionicPlatform.registerBackButtonAction(function (e) {
//判断处于哪个页面时双击退出
if ($location.path() == '/tab/home') {
if ($rootScope.backButtonPressedOnceToExit) {
ionic.Platform.exitApp();
} else {
$rootScope.backButtonPressedOnceToExit = true;
$cordovaToast.showLongBottom('再按一次退出系统');
setTimeout(function () {
$rootScope.backButtonPressedOnceToExit = false;
}, 2000);
}
}
else if ($ionicHistory.backView()) {
$ionicHistory.goBack();
} else {
if ($rootScope.backButtonPressedOnceToExit) {
ionic.Platform.exitApp();
} else{
$rootScope.backButtonPressedOnceToExit = true;
$cordovaToast.showLongBottom('再按一次退出系统');
setTimeout(function () {
$rootScope.backButtonPressedOnceToExit = false;
}, 2000);
}
}
e.preventDefault();
return false;
}, 101);