sencha touch 自定义cardpanel控件 模仿改进NavigationView 灵活添加按钮组,导航栏,*隐藏返回按钮(废弃 仅参考)

时间:2023-12-26 12:25:49

最新版本我将会放在: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