jquerymobile提供了很多的默认配置,jquerymobile会在执行到增强页面元素的时候马上执行它,远早于document.ready事件,这些默认的配置符合大部分情形,对于开发者来说也很容易去修改这些默认的配置。
当Jquery Mobile开始执行时,他就会在document对象上触发mobileinit 事件,所以你可以绑定别的行为来覆盖默认配置。代码:
$(document).bind("mobileinit", function(){ //覆盖的代码 });
因为mobileinit事件是在执行后马上触发,所以你需要在Jquery Mobile加载之前绑定你的事件处理函数,所以我建议你如下安排你的js引用顺序。
<script src="/blog_article/Jquery.js"></script> <script src="/blog_article/custom-scripting.js"></script> <script src="/blog_article/Jquery-mobile.js"></script>
在事件绑定内部,你可以设置你的默认配置,或者是使用jq的$.extend方法扩展 $.mobile对象
$(document).bind("mobileinit", function(){ $.extend( $.mobile , { foo: bar }); });
或者单独设置它
$(document).bind("mobileinit", function(){ $.mobile.foo = bar; });
配置选项
以下是 $.mobile对象部分可配置选项以及其默认值:
subPageUrlKey (string, default: "ui-page"):
url参数用来引用由插件生成的子页面(例如那些由嵌套的listview生成的子页面) 例如: example.html&ui-page=subpageIdentifir. 在&ui-page=前的部分被jquery mobile框架用来向子页面所在的URL发送一个ajax请求.
nonHistorySelectors (string, default: "dialog"):
对于带有data-rel属性值的a标签链接 或者 带有data-role属性值的page,如果它们匹配这些选择器(即该string参数),那么它们不会在历史记录中被追踪 (即它们不会在location.hash中被更新也不会被浏览器历史所标记).
activePageClass (string, default: "ui-page-active"):
该class被分配给当前视图中的page (包括过渡状态中的)
activeBtnClass (string, default: "ui-page-active"):
该class用于"激活"button的状态 (参见css框架).
ajaxEnabled (boolean, default: true):
当可能的时候jQuery Mobile 会自动通过ajax处理链接点击以及表单提交, 如果不行,url hash 监听将会停止,url也会像常规那样发出HTTP 请求.
ajaxLinksEnabled (boolean, default: true):
只要可行的时候,jQuery Mobile 就会自动通过ajax处理链接的点击.
ajaxFormsEnabled (boolean, default: true):
只要可行的时候,jQuery Mobile 就会自动通过ajax处理页面提交.
autoInitialize (boolean, default: true):
当该选项被设置为false时 自动初始化功能将延迟嵌入页面(page)的增强功能直到
$.mobile.initializePage();
被显式调用. 默认情况下当DOM加载完毕page将会被增强.
defaultTransition (string, default: 'slide'):
设置页面过渡效果(ajax请求),设置为'none'表示没有任何过渡效果.
loadingMessage (string, default: "loading"):
设置页面加载时显示的文本. 如果设置为false, 将不会显示任何文本.
metaViewportContent (string, default: "width=device-width, minimum-scale=1, maximum-scale=1"):
配置自动生成的meta标签,如果为false,将不会为DOM添加任何meta标签.
gradeA (函数返回boolean值, default: 该函数默认返回 $.support.mediaquery 的值):
浏览器必须符合所有支持的条件才会返回 true.
strings.xml
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="app_name">msm</string> <string name="action_settings">Settings</string> <string name="number">电话号码</string> <string name="content">短信内容</string> <string name="button">发送</string> </resources>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <TextView android:id="@+id/textView1" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/number" /> <EditView android:id="@+id/number" android:layout_width="fill_parent" android:layout_height="wrap_content" /> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/content" /> <EditView android:id="@+id/content" android:layout_width="fill_parent" android:layout_height="wrap_content" android:minLines="3" /> <Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/button" /> </LinearLayout>
MainActivity.java
package com.example.msm; import android.os.Bundle; import android.app.Activity; import android.view.Menu; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } }
3楼Smallearth前天 17:36哎 我自个发现问题了 EditView改成EditText。。。哎,俺们菜鸟伤不起啊2楼sy2zczy前天 14:29写错了,你看log时会有错误提示的啊1楼Smallearth3天前 11:47哎 注定没人给我解答么。。。
CCScene一般情况是游戏里面的根节点,称之为"场景",运行游戏时需要通过CCDirector启动第一个场景。当然,游戏稍微复杂一点的话,可能会包含很多个场景,这就涉及到场景的切换,也是通过CCDirector来完成。CCScene是个抽象的概念,也没有可视化显示的功能,对比CCNode,CCScene基本上没有额外的代码:
// CCScene.h #import "CCNode.h" @interface CCScene : CCNode { } @end
// CCScene,m #import "CCScene.h" #import "Support/CGPointExtension.h" #import "CCDirector.h" @implementation CCScene -(id) init { if( (self=[super init]) ) { CGSize s = [[CCDirector sharedDirector] winSize]; // 设置position不受anchorPoint影响 self.isRelativeAnchorPoint = NO; // 设置anchorPoint anchorPoint_ = ccp(0.5f, 0.5f); // 设置CCScene的大小为屏幕大小 [self setContentSize:s]; } return self; } @end
可以发现,对比CCNode,CCScene只是重写了init方法而已,而且也只是做了一个简单的设置
1.运行第一个场景
我们一般是在应用程序代理AppDelegate的applicationDidFinishLaunching:方法结尾处运行游戏的第一个场景
[[CCDirector sharedDirector] runWithScene: [HelloWorldLayer scene]];这里的[HelloWorldLayer scene]返回的是一个CCScene对象
2.替换场景
[[CCDirector sharedDirector] replaceScene:scene];这个方法会用新的场景替换旧的场景,cocos2d会释放旧场景的内存,删除旧场景中所有的节点,停止所有动作和消息调度,因此我们不用手动释放旧场景的内存
3.推入和弹出场景
我们知道可以用replaceScene:来运行一个新场景,但是会释放掉旧场景的内存。有时候我们希望在不释放旧场景内存的前提下运行一个新场景,这时候就要用到CCDirector的pushScene:和popScene两个方法了。
1> 使用pushScene:方法推入一个新场景,新场景会层叠在旧场景的上面,但并没有释放旧场景的内存,旧场景继续保留在内存中
[[CCDirector sharedDirector] pushScene:scene];
2> 使用popScene方法弹出最上层的场景并释放其内存,使保留在内存中的旧场景重新显示出来
[[CCDirector sharedDirector] popScene];
上面介绍了场景的切换,不过都是瞬间完成的,有时候我们想在场景切换的时候有些过渡效果,即以动画的形式切换场景,我们称之为"场景过渡"。要想做场景过渡效果,就必须用CCTransitionScene的子类,CCTransitionScene本身继承了CCScene,它包含了非常多的子类,每个子类都有不同的场景过渡效果,比如CCTransitionFade是淡入淡出效果,CCTransitionPageTurn是翻页效果。
下面演示一个翻页效果:
CCTransitionPageTurn *page = [CCTransitionPageTurn transitionWithDuration:0.5 scene:scene]; [[CCDirector sharedDirector] replaceScene:page];意思是在0.5秒的时间内使用翻页效果从旧场景过渡到scene这个新场景,因为CCTransitionScene是CCScene的子类,所以可以作为replaceScene:的参数。
cocos2d中有非常多的过渡效果可以使用,都是CCTransitionScene的子类,类名一般都是以CCTransition开头的。我就不在这里一一介绍每个子类有什么效果,也没有必要,用到时自己再去查API吧。
注意:CCTransitionScene只能使用在replaceScene:和pushScene:的时候,在popScene弹出场景时是不能用这个过渡效果的
说到场景过渡,那就不得不说一下节点的生命周期,即一个节点从开始被添加到屏幕上 到 从屏幕中移除的过程,CCNode提供了相应的生命周期方法:
// 节点被添加到屏幕上 或者 重新显示到屏幕上 时调用 -(void) onEnter; // 调用完onEnter后就会调用此方法,如果使用了场景过渡效果,将在场景过渡完毕后才调用此方法 -(void) onEnterTransitionDidFinish; // 节点从屏幕中移除 或者 暂时离开屏幕 时调用 -(void) onExit;
下面演示在场景切换时,节点生命周期方法的调用顺序
假设有2个图层RedLayer和BlueLayer,它们分别在不同的场景中。点击RedLayer,就推入BlueLayer所在的场景,点击BlueLayer就弹出BlueLayer所在的场景。我们就在场景切换的过程中观察这2个图层的生命周期。
为了区分这2个图层,我让它们继承了CCLayerColor,分别设置不用的背景颜色,RedLayer为红色,BlueLayer为蓝色。
因为RedLayer和BlueLayer都继承CCLayerColor,而且都需要负责创建自己的图层、负责观察生命周期方法的调用,那么我就先抽出一个继承了CCLayerColor的公共父类BaseLayer,在它里面完成一些公共操作,然后让RedLayer和BlueLayer都继承它
BaseLayer的代码
// BaseLayer.h #import "cocos2d.h" @interface BaseLayer : CCLayerColor // 用来创建图层所在的场景 + (CCScene *)scene; // 图层的背景颜色,交给子类去实现 + (ccColor4B)bgColor; @end
// BaseLayer.m #import "BaseLayer.h" @implementation BaseLayer #pragma mark - 初始化场景 + (CCScene *)scene { // 获取当前类的背景颜色 ccColor4B color = [self bgColor]; // 根据当前类名创建图层 BaseLayer *layer = [[self class] layerWithColor:color]; // 接收触摸输入 layer.isTouchEnabled = YES; CCScene *scene = [CCScene node]; [scene addChild:layer]; return scene; } #pragma mark - 打印生命周期方法 - (void)onEnter { // _cmd 代表着当前的selector [super onEnter]; // 第一个%@是打印类名,第二个%@是打印方法名 NSLog(@"%@ --> %@", NSStringFromClass([self class]), NSStringFromSelector(_cmd)); } - (void)onEnterTransitionDidFinish { [super onEnterTransitionDidFinish]; NSLog(@"%@ --> %@", NSStringFromClass([self class]), NSStringFromSelector(_cmd)); } - (void)onExit { [super onExit]; NSLog(@"%@ --> %@", NSStringFromClass([self class]), NSStringFromSelector(_cmd)); } @end
RedLayer的代码
// RedLayer.h #import "BaseLayer.h" @interface RedLayer : BaseLayer @end
// RedLayer.m #import "RedLayer.h" #import "BlueLayer.h" @implementation RedLayer #pragma mark - 点击红色图层时,跳到蓝色图层所在的场景 - (void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { // 初始化蓝色图层所在的场景 CCScene *scene = [BlueLayer scene]; // 推入场景(暂时没有使用过渡效果) [[CCDirector sharedDirector] pushScene:scene]; } #pragma mark - 背景颜色为红色 + (ccColor4B)bgColor { return ccc4(255, 0, 0, 255); } @end
BlueLayer的代码
// BlueLayer.h #import "BaseLayer.h" @interface BlueLayer : BaseLayer @end
// BlueLayer.m #import "BlueLayer.h" @implementation BlueLayer #pragma mark - 当点击蓝色图层时,弹出场景 - (void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { [[CCDirector sharedDirector] popScene]; } #pragma mark - 背景颜色为蓝色 + (ccColor4B)bgColor { return ccc4(0, 0, 255, 255); } @end
1.在应用程序加载完毕后,即在AppDelegate的applicationDidFinishLaunching:方法中启动第一个场景 ---- 红色图层所在的场景
[[CCDirector sharedDirector] runWithScene: [RedLayer scene]];
运行完毕后,效果如下:
生命周期方法打印如下:
2013-02-22 15:47:56.473 HelloWorld[2679:c07] RedLayer --> onEnter 2013-02-22 15:47:56.474 HelloWorld[2679:c07] RedLayer --> onEnterTransitionDidFinish
2.点击红色图层,跳到蓝色图层所在的场景
这里根据有没有使用过渡效果,要分2种情况
1> 如果没有使用过渡效果
屏幕直接变为蓝色
生命周期方法打印如下:
2013-02-22 15:50:16.381 HelloWorld[2679:c07] RedLayer --> onExit 2013-02-22 15:50:16.382 HelloWorld[2679:c07] BlueLayer --> onEnter 2013-02-22 15:50:16.384 HelloWorld[2679:c07] BlueLayer --> onEnterTransitionDidFinish可以看出,是先移除红色,再添加蓝色
2> 如果使用了过渡效果
先改变下RedLayer中的代码:
#pragma mark - 点击红色图层时,跳到蓝色图层所在的场景 - (void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { // 初始化蓝色图层所在的场景 CCScene *scene = [BlueLayer scene]; // 旧场景一边旋转一边缩小,新场景一边旋转一边方法 CCTransitionRotoZoom *page = [CCTransitionRotoZoom transitionWithDuration:2 scene:scene]; // 推入场景(暂时没有使用过渡效果) [[CCDirector sharedDirector] pushScene:page]; }接下来看一下屏幕效果和打印信息
过渡效果刚开始就会打印:
2013-02-22 15:59:38.420 HelloWorld[2862:c07] BlueLayer --> onEnter说明是先初始化并添加BlueLayer
然后中间经历了长达2s的过渡效果:
红色是在一边旋转一边缩小
红色完全消失后,蓝色在一边旋转一边放大
蓝色放大到屏幕大小后
最后会出现以下打印信息:
2013-02-22 16:04:28.852 HelloWorld[2910:c07] RedLayer --> onExit 2013-02-22 16:04:28.853 HelloWorld[2910:c07] BlueLayer --> onEnterTransitionDidFinish移除红色,蓝色过渡完毕
3> 点击蓝色图层,弹出蓝色图层所在的场景,重新显示红色图层所在的场景
打印信息如下:2013-02-22 16:06:47.013 HelloWorld[2910:c07] BlueLayer --> onExit 2013-02-22 16:06:47.014 HelloWorld[2910:c07] RedLayer --> onEnter 2013-02-22 16:06:47.015 HelloWorld[2910:c07] RedLayer --> onEnterTransitionDidFinish移除蓝色,重新显示红色