注(
原创地址:http://www.cnblogs.com/mlzs/archive/2013/06/09/3128318.html
原创作者:魔狼再世
)
代码:
/* *模仿且改进NavigationView *返回时自动销毁视图,节约内存 */ Ext.define('ux.CardPanel', { extend: 'Ext.Container', xtype: 'cardPanel', requires: ['Ext.TitleBar'], config: { //布局,type不可更改 layout: { type: 'card', animation: { duration: 300, easing: 'ease-out', type: 'slide', direction: 'left' } }, //初始视图xtype defItemId: null, //顶部导航条 navBar: { docked: 'top' }, //顶部控件组,在子视图中配置 navBarItems: null, //返回按钮 backBtn: { align: 'left', ui: 'back' }, //返回按钮显示状态,在子视图中配置 backHide: false, //临时cls,在子视图中配置 pCls: null, //底部导航栏、可选格式btmBar:'xtype',在子视图中配置 btmBar: null }, //初始化 initialize: function () { var me = this; //监控界面切换事件 me.on({ activeitemchange: me.onActiveitemchange, scope: me }); //初始化 //历史记录 me.viewStack = []; //视图加载状态 me.viewStatus = {}; //<debug> var layout = me.getLayout(), itemId = me.getDefItemId(); if (layout && !layout.isCard) { Ext.Logger.error('CardPanel中layout的布局只能是card布局'); } //</debug> if (itemId) { this.push(itemId); this.upView(this.getActiveItem()); } }, //更新返回按钮显示状态 updateBackHide: function (newItem, oldItem) { var backBtn = this.getBackBtn(); if (newItem) { backBtn.hide(); } else { backBtn.show(); } }, //更新底部导航栏 updateBtmBar: function (newItem, oldItem) { if (newItem == oldItem) return; 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()); }, //更新临时cls updatePCls: function (newItem, oldItem) { if (oldItem) { this.removeCls(oldItem); } if (newItem) { this.addCls(newItem); } }, //更新顶部导航栏 updateNavBar: function (newItem, oldItem) { if (oldItem) { this.remove(oldItem); } if (newItem) { this.add(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 }); } }, //添加历史记录 viewStackPush: function (xtype) { if (!xtype) return; this.viewStatus[xtype] = true; this.viewStack.push(xtype); }, //移除最后一个历史记录 viewStackPop: function () { var last = this.getLateViewStack(); if (!last) return; this.viewStatus[last] = false; this.viewStack.pop(); }, //获得最后一个元素 getLateViewStack: function () { var viewStack = this.viewStack, vLength = viewStack.length - 1; if (vLength > -1) { return viewStack[vLength]; } return null; }, //只保留指定纪录,清空其他纪录 viewStackOne: function (xtype) { this.viewStack = [xtype]; this.viewStatus = { xtype: true }; }, //界面切换,处理后退 onActiveitemchange: function (t, newView, oldView) { this.upView(newView); }, //更新视图 upView: function (view) { if (!view) return; //更新后退按钮 this.setBackHide(view.config.backHide || this.viewStack.length == 1); //更新按钮组 var items = view.config.navBarItems || false; this.setNavBarItems(items); //更新cls var pCls = view.config.pCls || false; this.setPCls(pCls); //更新标题 var title = view.config.title || ''; this.getNavBar().setTitle(title); //更新底部导航栏 var btmBar = view.config.btmBar || false; this.setBtmBar(btmBar); //触发被显示视图的事件 view.fireEvent('showView', view, this); }, //添加视图 //注意xtype是指alternateClassName push: function (xtype, params) { var me = this, view = this.getActiveItem(); /*过滤已经添加的视图*/ if (!this.viewStatus[xtype]) { view = Ext.create(xtype, { itemId: xtype }); if (params) { view.setConfig(params); } this.viewStackPush(xtype); this.setActiveItem(view); } else if (view.getItemId() != xtype) { this.viewStackPush(xtype); this.setActiveItem(xtype); } }, //移除最后一个视图 pop: function () { var me = this, innerItems = this.getInnerItems(), ord = innerItems[innerItems.length - 1]; if (ord) { //触发被移除视图的事件 ord.fireEvent('removrView', ord, this); me.viewStackPop(); if (!ord.config.isNoHide) { // 先隐藏防止出错,在pop时可能会隐藏掉切换动画 // 如果出现这种情况为子视图添加 isNoHide: true ord.hide(); } //强制销毁,防止销毁不完全引发错误 me.remove(ord, true); } }, //除了指定视图,移除其他视图 popAll: function (xtype, isHide) { var me = this, innerItems = this.getInnerItems(), i, ord; me.viewStackOne(xtype); for (i = innerItems.length - 1; i > -1; i--) { /*过滤掉需要显示的视图*/ ord = innerItems[i]; if (ord.getItemId() != xtype) { if (isHide) { //直接隐藏,去掉界面切换动画 //如果后续动作是添加新的视图必须如此,否则会出错 ord.hide(); } me.remove(ord, true); } } }, //返回上一个历史记录 onBackButtonTap: function () { this.pop(); this.setActiveItem(this.getLateViewStack()); this.fireEvent('back', this); } });
主视图js:
/* *主视图,负责视图切换 */ Ext.define('app.view.Main', { extend: 'ux.CardPanel', requires: ['app.view.Home', 'Ext.picker.Picker','app.view.uitl.MyBar'], xtype: 'main', config: { id: 'main', cls: 'cardPanel', backBtn: { iconCls: 'reply', iconMask: true, cls: 'replyBtn' }, //默认显示的界面itemId defItemId: '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', //解决pop时没有切换效果的问题 isNoHide: true, //额外的按钮组,只能是按钮组。不能添加其他属性 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} 发布来源:{Auth}</div><div class="like"><div class="ico comment">0</div></div>', store: 'messageList' } });Tip:
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无动画效果的问题