sencha touch 自定义cardpanel控件 模仿改进NavigationView 灵活添加按钮组,导航栏,自由隐藏返回按钮(废弃 仅参考)
最新版本我将会放在: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} 发布来源:{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 灵活添加按钮组,导航栏,自由隐藏返回按钮(废弃 仅参考)的更多相关文章
- sencha touch 扩展官方NavigationView 灵活添加按钮组,导航栏,自由隐藏返回按钮(2014-5-15)
扩展视频讲解:http://www.cnblogs.com/mlzs/p/3652094.html官方NavigationView详解:http://www.cnblogs.com/mlzs/p/35 ...
- ios之自定义导航栏上的返回按钮
导航栏的按钮,右边的按钮是可以自己随意添加的.但左边的返回按钮怎么定制?你会说,添加一个自己的按钮呗!你可以试试看,这样行不行. 正确的答案是重载UINavigationController类的pus ...
- Android自定义组合控件详细示例 (附完整源码)
在我们平时的Android开发中,有时候原生的控件无法满足我们的需求,或者经常用到几个控件组合在一起来使用.这个时候,我们就可以根据自己的需求创建自定义的控件了,一般通过继承View或其子类来实现. ...
- iOS开发UI篇—Quartz2D(自定义UIImageView控件)
iOS开发UI篇—Quartz2D(自定义UIImageView控件) 一.实现思路 Quartz2D最大的用途在于自定义View(自定义UI控件),当系统的View不能满足我们使用需求的时候,自定义 ...
- 安卓自定义组合控件--toolbar
最近在学习安卓APP的开发,用到了toolbar这个控件, 最开始使用时include layout这种方法,不过感觉封装性不好,就又改成了自定义组合控件的方式. 使用的工具为android stud ...
- Android自定义控件之自定义组合控件
前言: 前两篇介绍了自定义控件的基础原理Android自定义控件之基本原理(一).自定义属性Android自定义控件之自定义属性(二).今天重点介绍一下如何通过自定义组合控件来提高布局的复用,降低开发 ...
- asp.net webform 自定义分页控件
做web开发一直用到分页控件,自己也动手实现了个,使用用户自定义控件. 翻页后数据加载使用委托,将具体实现放在在使用分页控件的页面进行注册. 有图有真相,给个直观的认识: 自定义分页控件前台代码: & ...
- arcgis api for js共享干货系列之二自定义Navigation控件样式风格
arcgis api for js默认的Navigation控件样式风格如下图: 这样的风格不能说不好,各有各的爱好,审美观,这里也不是重点,这里的重点是如何自定义一套自己喜欢的样式风格呢:自己自定义 ...
- 论如何在手机端web前端实现自定义原生控件的样式
手机开发webapp的同学一定遇到过这样问题,如何为丑极了的手机元素应用自定义的样式.首先,要弄清楚为什么要定义手机原生控件的样式,就需要看看手机的那些原生框样式的丑陋摸样: android: ios ...
随机推荐
- unity3d 获取游戏对象详解
原文地址:http://www.xuanyusong.com/archives/2768 我觉得Unity里面的Transform 和 GameObject就像两个双胞胎兄弟一样,这俩哥们很要好,我能 ...
- js粘贴事件paste简单解析及遇到的坑
在用户执行粘贴操作的时候,js能够获得剪切板的内容,本文讨论一下这个问题. 目前只有Chrome支持获取剪切板中的图片数据.还好需要这个功能的产品目前只支持Chrome和Safari,一些Chrome ...
- android EditText设置弹出数字输入法键盘
<EditText android:id="@+id/edit_digit_input" android:layout_width="wrap_ ...
- QT3D场景快速绘制入门学习
在QT中实现3D绘制的方式: 1) 使用QT OpenGL模块(QOpenGLWidget等) 2) 使用QT 3D C++类(QEntity等) 3) 使用QT 3D QML类(Enti ...
- sql2008,sa不能使用:不能为主体 sa 中设置凭据
打开属性对话框,为 SQL Server Administrator 帐户,然后您执行了"sa"登录使用 SQL Server Management Studio 工具.您修改为在 ...
- Javascript获取IFrame内容(兼容IE&FF)
原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://wintys.blog.51cto.com/425414/123303 作者: W ...
- ios开发之 -- NSString指定字体高亮显示
一个简单的小需求,就是在一个字符串里面,指定一部分字节高亮显示,代码如下: NSString *descStr = @"需要高亮显示的字符"; NSString *nickStr ...
- android 读书笔记 1
四层linux 内核层library java 虚拟机frameworkapplication 四组件活动(activity), 服务(service), 广播接收器(broadcast receiv ...
- 【Android】录音暂停和继续
https://www.2cto.com/kf/201410/347839.html http://blog.csdn.net/wanli_smile/article/details/7715030 ...
- chm只看到目录,看不到内容解决办法
鼠标左键->属性->解除锁定->搞定!