最新版本我将会放在:http://www.cnblogs.com/mlzs/p/3382229.html这里的示例里面,这里不会再做更新

代码:

 /*
*模仿且改进NavigationView
*返回时自动销毁视图,节约内存
*/
Ext.define('ux.CardPanel', {
extend: 'Ext.Container',
xtype: 'cardPanel',
requires: ['Ext.TitleBar'],
config: {
//顶部导航条
navBar: {
docked: 'top'
},
//布局,type不可更改
layout: {
type: 'card',
animation: {
duration: 300,
easing: 'ease-out',
type: 'slide',
direction: 'left'
}
},
//顶部控件组,在子项中配置
navBarItems: null,
//返回按钮
backBtn: {
align: 'left',
ui: 'back'
},
//返回按钮显示状态,在子项中配置
backHide: false,
//临时cls,在子项中配置
pCls: null,
//底部导航栏、可选格式btmBar:'xtype',在子项中配置
btmBar: null,
//当子项被激活后移除除了指定项之外的项,在子项中配置
nRemove: null
},
//初始化
initialize: function () {
var layout = this.getLayout();
if (layout && !layout.isCard) {
Ext.Logger.error('CardPanel中layout的布局只能是card布局');
}
this.initStatus();
},
//初始化历史记录
initStatus: function () {
if (!this.viewStack) {
//历史记录
this.viewStack = [];
//视图加载状态
this.viewStatus = {};
}
},
//更新返回按钮显示状态
updateBackHide: function (newItem, oldItem) {
var backBtn = this.getBackBtn();
if (newItem) {
backBtn.hide();
} else {
backBtn.show();
}
},
//更新底部导航栏
updateBtmBar: function (newItem, oldItem) {
if (oldItem) {
oldItem = this.down(oldItem);
this.remove(oldItem);
}
if (newItem) {
newItem = Ext.create(newItem);
this.add(newItem);
}
},
//创建导航栏控件组
applyNavBarItems: function (newItems) {
if (!newItems) return false;
var me = this,
navItems = [],
i,
ln;
newItems = Ext.Array.from(newItems);
for (i = 0, ln = newItems.length; i < ln; i++) {
navItems.push(me.factoryItem(newItems[i]));
}
return navItems;
},
//更新导航栏控件组
updateNavBarItems: function (newItem, oldItem) {
var navBar = this.getNavBar();
if (oldItem) {
var i, ln;
for (i = 0, ln = oldItem.length; i < ln; i++) {
navBar.remove(oldItem[i]);
}
}
if (newItem) {
navBar.add(newItem);
}
},
//创建顶部导航栏
applyNavBar: function (config) {
return Ext.factory(config, Ext.TitleBar, this.getNavBar());
},
//更新顶部导航栏
updateNavBar: function (newItem, oldItem) {
if (oldItem) {
this.remove(oldItem);
}
if (newItem) {
this.add(newItem);
}
},
//更新临时cls
updatePCls: function (newItem, oldItem) {
if (oldItem) {
this.removeCls(oldItem);
}
if (newItem) {
this.addCls(newItem);
}
},
//创建返回按钮
applyBackBtn: function (config) {
return Ext.factory(config, Ext.Button, this.getBackBtn());
},
//更新返回按钮
updateBackBtn: function (newItem, oldItem) {
if (oldItem) {
this.getNavBar().remove(oldItem);
}
if (newItem) {
this.getNavBar().add(newItem);
newItem.on({
scope: this,
tap: this.onBackButtonTap
});
}
},
//更新移除
updateNRemove: function (newItem, oldItem) {
var animation = this.getLayout().getAnimation();
if (oldItem) {
//移除动画结束监听
animation.un({
scope: this,
animationend: 'onAnimationend'
});
}
if (newItem) {
//添加动画结束监听
animation.on({
scope: this,
animationend: 'onAnimationend'
});
}
},
/**
* 移除历史记录
* @private
*/
viewStackPop: function (count) {
for (var i = 0; i < count; i++) {
this.viewStack.pop();
}
},
//添加视图
//注意xtype是指alternateClassName
push: function (xtype, params) {
var me = this,
view = this.getActiveItem(),
oldXtype = view && (view.config.xtype || view.getItemId());
/*过滤已经添加的视图*/
if (!this.viewStatus[xtype]) {
params = params || {};
params.itemId = xtype;
view = Ext.create(xtype, params);
this.add(view);
} else if (oldXtype != xtype) {
this.viewStack.push(xtype);
this.setActiveItem(xtype);
}
},
//当动画效果结束时,子项配置了nRemove属性将会激活
onAnimationend: function () {
// console.log('animationend');
this.popAll(this.getNRemove());
},
//项被激活
onActivate: function (view) {
var config = view.config;
// console.log('activate', config.xtype || view.getItemId());
//更新后退按钮
// console.log('setBackHide', this.viewStack);
this.setBackHide(config.backHide || this.viewStack.length == 1);
//更新按钮组
var items = config.navBarItems || false;
this.setNavBarItems(items);
//更新cls
var pCls = config.pCls || false;
this.setPCls(pCls);
//更新标题
var title = config.title || '';
this.getNavBar().setTitle(title);
//更新底部导航栏
var btmBar = config.btmBar || false;
this.setBtmBar(btmBar);
//更新移除
var nRemove = config.nRemove || false;
this.setNRemove(nRemove);
},
//项被销毁
onDestroy: function (view) {
// console.log('onDestroy', view.config.xtype || view.getItemId());
this.viewStatus[view.config.xtype || view.getItemId()] = false;
},
/**
* 不填写参数时,移除当前项,返回到上一项
* 如果参数是数字,则从最后一项开始移除指定数目的项
* 如果参数是string,则移除指定类型的项
* 如果参数是项,则移除传入的项
* 不论参数如何,都会保留一个活动项
* @return {Ext.Component} 当前活动项
*/
pop: function (count) {
if (this.beforePop(count)) {
return this.doPop();
}
},
/**
* @private
*删除指定项
*/
beforePop: function (count) {
var me = this,
innerItems = me.getInnerItems();
if (Ext.isString(count) || Ext.isObject(count)) {
var last = innerItems.length - 1,
i;
for (i = last; i >= 0; i--) {
if ((Ext.isString(count) && Ext.ComponentQuery.is(innerItems[i], count)) || (Ext.isObject(count) && count == innerItems[i])) {
//获得移除项序号
count = last - i;
break;
}
}
if (!Ext.isNumber(count)) {
return false;
}
}
var ln = innerItems.length,
toRemove;
//默认移除一项
if (!Ext.isNumber(count) || count < 1) {
count = 1;
}
//当我们试图移除更多视图时
count = Math.min(count, ln - 1);
if (count) {
this.viewStackPop(count);
//开始移除视图
toRemove = innerItems.splice(-count, count - 1);
for (i = 0; i < toRemove.length; i++) {
this.remove(toRemove[i]);
}
return true;
}
return false;
},
/**
* @private
*移除最后一项
*/
doPop: function () {
var me = this,
innerItems = this.getInnerItems(),
ord = innerItems[innerItems.length - 1];
me.remove(ord);
//触发被移除项的事件
return this.getActiveItem();
},
doResetActiveItem: function (innerIndex) {
var me = this,
innerItems = me.getInnerItems(),
animation = me.getLayout().getAnimation();
if (innerIndex > 0) {
if (animation && animation.isAnimation) {
animation.setReverse(true);
}
me.setActiveItem(innerIndex - 1);
}
},
/**
* @private
*执行移除项,调用remove方法后自动执行
*/
doRemove: function () {
var animation = this.getLayout().getAnimation();
if (animation && animation.isAnimation) {
animation.setReverse(false);
}
this.callParent(arguments);
},
/**
* @private
*执行添加项,调用add方法后自动执行
*/
onItemAdd: function (item, index) {
if (item.isInnerItem()) {
var xtype = item.config.xtype || item.getItemId();
//如果配置了items,会先于initialize执行,所以需要初始化历史纪录
this.initStatus();
this.viewStatus[xtype] = true;
this.viewStack.push(xtype);
//添加监听
item.on({
scope: this,
activate: 'onActivate',
destroy: 'onDestroy'
});
}
this.doItemLayoutAdd(item, index);
if (!this.isItemsInitializing && item.isInnerItem()) {
this.setActiveItem(item);
}
if (this.initialized) {
this.fireEvent('add', this, item, index);
}
},
/**
* 移除第一项和最后项之间的所有项(包括最后项)
* @return {Ext.Component} 当前活动视图
*/
reset: function (noUp) {
return this.pop(this.getInnerItems().length);
},
//除了指定项,从倒数第二项开始移除
popAll: function (xtype) {
var me = this,
innerItems = this.getInnerItems(),
length = innerItems.length - 1,
oldXtype,
ord,
i;
this.viewStack = [xtype];
for (i = length; i > -1; i--) {
/*过滤掉需要显示的视图*/
ord = innerItems[i];
oldXtype = ord.config.xtype || ord.getItemId();
if (i == length) {
me.viewStack.push(oldXtype);
} else if (oldXtype != xtype) {
me.remove(ord, true);
}
}
},
//返回上一个历史记录
onBackButtonTap: function () {
this.pop();
this.fireEvent('back', this);
}
});

主视图js:

 /*
*主视图,负责视图切换
*/
Ext.define('app.view.Main', {
extend: 'ux.CardPanel',
requires: ['app.view.Home', 'Ext.picker.Picker', 'app.view.uitl.MyBar', 'app.view.user.Site'],
xtype: 'main',
config: {
id: 'main',
cls: 'cardPanel',
backBtn: {
iconCls: 'reply',
iconMask: true,
cls: 'replyBtn'
},
//items只能配置一项
items: [{
xtype: 'home'
}]
}
});

子视图js:

 Ext.define('app.view.message.List', {
alternateClassName: 'messageList',
extend: 'Ext.List',
xtype: 'messageList',
requires: ['Ext.plugin.ListPaging'],
config: {
cls: 'list',
//标题
title: '校园资讯',
//用于控制navBarItems中的css
pCls: '',
//底部导航栏,直接填写alternateClassName
btmBar: 'myBar',
//额外的按钮组,只能是按钮组。不能添加其他属性
navBarItems: [{
itemId: 'mBtn',
xtype: 'button',
align: 'right',
iconMask: true,
cls: 'nBg',
iconCls: 'search',
action: 'show',
show: 'messageSearch'
}],
plugins: [{
xclass: 'Ext.plugin.ListPaging'
}],
itemTpl: '<div class="title">{Title}</div><div class="sm">时间 {Time}&nbsp;&nbsp;&nbsp;&nbsp;发布来源:{Auth}</div><div class="like"><div class="ico comment">0</div></div>',
store: 'messageList'
}
});

2013.9.6

更改CardPanel

优化navBarItems结构,itemId不再必须设置

优化for循环结果

修复popAll方法中ord为全局变量的问题

2013.9.6

更改push方法,可以在传入配置参数(只在第一次创建视图时有效)

2013.10.7

优化代码细节

2013.10.10

更改pop方法,将代码this.setActiveItem(this.getLateViewStack());移动到onBackButtonTap方法中,以解决pop后再push无动画效果的问题

2013.10.18

参照NavigationView大幅度修改代码,去除一些无用代码

2013.10.22

更新push方法,更好的配置自定义参数

移除debug标签,解决cmd压缩后出错的问题。感谢@低碳哥指出

2013.10.23

优化代码,移除了除了back之外的所有自定义事件。如需使用可以考虑用 activate与deactivate事件代替

相关代码:http://www.cnblogs.com/mlzs/p/3382909.html

sencha touch 自定义cardpanel控件 模仿改进NavigationView 灵活添加按钮组,导航栏,自由隐藏返回按钮(废弃 仅参考)的更多相关文章

  1. sencha touch 扩展官方NavigationView 灵活添加按钮组,导航栏,自由隐藏返回按钮(2014-5-15)

    扩展视频讲解:http://www.cnblogs.com/mlzs/p/3652094.html官方NavigationView详解:http://www.cnblogs.com/mlzs/p/35 ...

  2. ios之自定义导航栏上的返回按钮

    导航栏的按钮,右边的按钮是可以自己随意添加的.但左边的返回按钮怎么定制?你会说,添加一个自己的按钮呗!你可以试试看,这样行不行. 正确的答案是重载UINavigationController类的pus ...

  3. Android自定义组合控件详细示例 (附完整源码)

    在我们平时的Android开发中,有时候原生的控件无法满足我们的需求,或者经常用到几个控件组合在一起来使用.这个时候,我们就可以根据自己的需求创建自定义的控件了,一般通过继承View或其子类来实现. ...

  4. iOS开发UI篇—Quartz2D(自定义UIImageView控件)

    iOS开发UI篇—Quartz2D(自定义UIImageView控件) 一.实现思路 Quartz2D最大的用途在于自定义View(自定义UI控件),当系统的View不能满足我们使用需求的时候,自定义 ...

  5. 安卓自定义组合控件--toolbar

    最近在学习安卓APP的开发,用到了toolbar这个控件, 最开始使用时include layout这种方法,不过感觉封装性不好,就又改成了自定义组合控件的方式. 使用的工具为android stud ...

  6. Android自定义控件之自定义组合控件

    前言: 前两篇介绍了自定义控件的基础原理Android自定义控件之基本原理(一).自定义属性Android自定义控件之自定义属性(二).今天重点介绍一下如何通过自定义组合控件来提高布局的复用,降低开发 ...

  7. asp.net webform 自定义分页控件

    做web开发一直用到分页控件,自己也动手实现了个,使用用户自定义控件. 翻页后数据加载使用委托,将具体实现放在在使用分页控件的页面进行注册. 有图有真相,给个直观的认识: 自定义分页控件前台代码: & ...

  8. arcgis api for js共享干货系列之二自定义Navigation控件样式风格

    arcgis api for js默认的Navigation控件样式风格如下图: 这样的风格不能说不好,各有各的爱好,审美观,这里也不是重点,这里的重点是如何自定义一套自己喜欢的样式风格呢:自己自定义 ...

  9. 论如何在手机端web前端实现自定义原生控件的样式

    手机开发webapp的同学一定遇到过这样问题,如何为丑极了的手机元素应用自定义的样式.首先,要弄清楚为什么要定义手机原生控件的样式,就需要看看手机的那些原生框样式的丑陋摸样: android: ios ...

随机推荐

  1. 前端不容错过的jQuery图片滑块插件

    作为前端开发者,我们会碰到很到各种各样的jQuery插件,但老实说,很少有自己写的.今天要分享的几款jQuery图片滑块插件,也就是jQuery焦点图插件,基本上会在每个网站都有应用,可以下载看看,也 ...

  2. linux 内存分页

    内存是计算机的主存储器.内存为进程开辟出进程空间,让进程在其中保存数据.我将从内存的物理特性出发,深入到内存管理的细节,特别是了解虚拟内存和内存分页的概念. 内存 简单地说,内存就是一个数据货架.内存 ...

  3. 用Fiddler可以设置浏览器的UA 和 手动 --Chrome模拟手机浏览器(iOS/Android)的三种方法,亲测无误!

    附加以一种软件的方法是:用Fiddler可以设置浏览器的UA 以下3种方法是手动的 通过伪装User-Agent,将浏览器模拟成Android设备. 第一种方法:新建Chrome快捷方式 右击桌面上的 ...

  4. 【python】命令行输出颜色

    http://www.cnblogs.com/chjbbs/p/5706513.html

  5. koa项目用mongoose与mongodb交互,始终报错FormModel is not defined

    koa项目用mongoose与mongodb交互,始终报错FormModel is not defined,就是自己定义的model实例始终不能找到,但是明明定义了,这时候就要看大小写了,当创建一个m ...

  6. Vue-router路由判断页面未登录跳转到登录页面

    router.beforeEach((to, from, next) => { if (to.matched.some(record => record.meta.requireAuth) ...

  7. ioncube

    FileRun多功能的VPS文件管理器使用ioncube加密的 ioncube通过将代码编译成字节码,使PHP源代码免受他人监控.剽窃以及改动 ioncube提供了一个安装的向导程序 下载地址http ...

  8. spring 定时任务corn表达式

    * * * * * * *  秒 分 时 日 月 周 年 秒 * / - 0-59 分 * / - 0-59 时 * / - 0-23 * 匹配任意数据 / 每隔多少分钟执行一次 - 区间 案例 0 ...

  9. jquery获取元素颜色css('color')的值返回RGB

    css代码如下: a, a:link, a:visited { color:#4188FB; } a:active, a:focus, a:hover { color:#FFCC00; } js代码如 ...

  10. 架构设计:系统存储(28)——分布式文件系统Ceph(挂载)

    (接上文<架构设计:系统存储(27)--分布式文件系统Ceph(安装)>) 3. 连接到Ceph系统 3-1. 连接客户端 完毕Ceph文件系统的创建过程后.就能够让客户端连接过去. Ce ...