zoukankan      html  css  js  c++  java
  • sencha touch 自定义cardpanel控件 模仿改进NavigationView 灵活添加按钮组,导航栏,自由隐藏返回按钮(废弃 仅参考)

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

    代码:

      1 /*
      2 *模仿且改进NavigationView
      3 *返回时自动销毁视图,节约内存
      4 */
      5 Ext.define('ux.CardPanel', {
      6     extend: 'Ext.Container',
      7     xtype: 'cardPanel',
      8     requires: ['Ext.TitleBar'],
      9     config: {
     10         //顶部导航条
     11         navBar: {
     12             docked: 'top'
     13         },
     14         //布局,type不可更改
     15         layout: {
     16             type: 'card',
     17             animation: {
     18                 duration: 300,
     19                 easing: 'ease-out',
     20                 type: 'slide',
     21                 direction: 'left'
     22             }
     23         },
     24         //顶部控件组,在子项中配置
     25         navBarItems: null,
     26         //返回按钮
     27         backBtn: {
     28             align: 'left',
     29             ui: 'back'
     30         },
     31         //返回按钮显示状态,在子项中配置
     32         backHide: false,
     33         //临时cls,在子项中配置
     34         pCls: null,
     35         //底部导航栏、可选格式btmBar:'xtype',在子项中配置
     36         btmBar: null,
     37         //当子项被激活后移除除了指定项之外的项,在子项中配置
     38         nRemove: null
     39     },
     40     //初始化
     41     initialize: function () {
     42         var layout = this.getLayout();
     43         if (layout && !layout.isCard) {
     44             Ext.Logger.error('CardPanel中layout的布局只能是card布局');
     45         }
     46         this.initStatus();
     47     },
     48     //初始化历史记录
     49     initStatus: function () {
     50         if (!this.viewStack) {
     51             //历史记录
     52             this.viewStack = [];
     53             //视图加载状态
     54             this.viewStatus = {};
     55         }
     56     },
     57     //更新返回按钮显示状态
     58     updateBackHide: function (newItem, oldItem) {
     59         var backBtn = this.getBackBtn();
     60         if (newItem) {
     61             backBtn.hide();
     62         } else {
     63             backBtn.show();
     64         }
     65     },
     66     //更新底部导航栏
     67     updateBtmBar: function (newItem, oldItem) {
     68         if (oldItem) {
     69             oldItem = this.down(oldItem);
     70             this.remove(oldItem);
     71         }
     72         if (newItem) {
     73             newItem = Ext.create(newItem);
     74             this.add(newItem);
     75         }
     76     },
     77     //创建导航栏控件组
     78     applyNavBarItems: function (newItems) {
     79         if (!newItems) return false;
     80         var me = this,
     81         navItems = [],
     82         i,
     83         ln;
     84         newItems = Ext.Array.from(newItems);
     85         for (i = 0, ln = newItems.length; i < ln; i++) {
     86             navItems.push(me.factoryItem(newItems[i]));
     87         }
     88         return navItems;
     89     },
     90     //更新导航栏控件组
     91     updateNavBarItems: function (newItem, oldItem) {
     92         var navBar = this.getNavBar();
     93         if (oldItem) {
     94             var i, ln;
     95             for (i = 0, ln = oldItem.length; i < ln; i++) {
     96                 navBar.remove(oldItem[i]);
     97             }
     98         }
     99         if (newItem) {
    100             navBar.add(newItem);
    101         }
    102     },
    103     //创建顶部导航栏
    104     applyNavBar: function (config) {
    105         return Ext.factory(config, Ext.TitleBar, this.getNavBar());
    106     },
    107     //更新顶部导航栏
    108     updateNavBar: function (newItem, oldItem) {
    109         if (oldItem) {
    110             this.remove(oldItem);
    111         }
    112         if (newItem) {
    113             this.add(newItem);
    114         }
    115     },
    116     //更新临时cls
    117     updatePCls: function (newItem, oldItem) {
    118         if (oldItem) {
    119             this.removeCls(oldItem);
    120         }
    121         if (newItem) {
    122             this.addCls(newItem);
    123         }
    124     },
    125     //创建返回按钮
    126     applyBackBtn: function (config) {
    127         return Ext.factory(config, Ext.Button, this.getBackBtn());
    128     },
    129     //更新返回按钮
    130     updateBackBtn: function (newItem, oldItem) {
    131         if (oldItem) {
    132             this.getNavBar().remove(oldItem);
    133         }
    134         if (newItem) {
    135             this.getNavBar().add(newItem);
    136             newItem.on({
    137                 scope: this,
    138                 tap: this.onBackButtonTap
    139             });
    140         }
    141     },
    142     //更新移除
    143     updateNRemove: function (newItem, oldItem) {
    144         var animation = this.getLayout().getAnimation();
    145         if (oldItem) {
    146             //移除动画结束监听
    147             animation.un({
    148                 scope: this,
    149                 animationend: 'onAnimationend'
    150             });
    151         }
    152         if (newItem) {
    153             //添加动画结束监听
    154             animation.on({
    155                 scope: this,
    156                 animationend: 'onAnimationend'
    157             });
    158         }
    159     },
    160     /**
    161     * 移除历史记录
    162     * @private
    163     */
    164     viewStackPop: function (count) {
    165         for (var i = 0; i < count; i++) {
    166             this.viewStack.pop();
    167         }
    168     },
    169     //添加视图
    170     //注意xtype是指alternateClassName
    171     push: function (xtype, params) {
    172         var me = this,
    173         view = this.getActiveItem(),
    174         oldXtype = view && (view.config.xtype || view.getItemId());
    175         /*过滤已经添加的视图*/
    176         if (!this.viewStatus[xtype]) {
    177             params = params || {};
    178             params.itemId = xtype;
    179             view = Ext.create(xtype, params);
    180             this.add(view);
    181         } else if (oldXtype != xtype) {
    182             this.viewStack.push(xtype);
    183             this.setActiveItem(xtype);
    184         }
    185     },
    186     //当动画效果结束时,子项配置了nRemove属性将会激活
    187     onAnimationend: function () {
    188         //        console.log('animationend');
    189         this.popAll(this.getNRemove());
    190     },
    191     //项被激活
    192     onActivate: function (view) {
    193         var config = view.config;
    194         //        console.log('activate', config.xtype || view.getItemId());
    195         //更新后退按钮
    196         //        console.log('setBackHide', this.viewStack);
    197         this.setBackHide(config.backHide || this.viewStack.length == 1);
    198         //更新按钮组
    199         var items = config.navBarItems || false;
    200         this.setNavBarItems(items);
    201         //更新cls
    202         var pCls = config.pCls || false;
    203         this.setPCls(pCls);
    204         //更新标题
    205         var title = config.title || '';
    206         this.getNavBar().setTitle(title);
    207         //更新底部导航栏
    208         var btmBar = config.btmBar || false;
    209         this.setBtmBar(btmBar);
    210         //更新移除
    211         var nRemove = config.nRemove || false;
    212         this.setNRemove(nRemove);
    213     },
    214     //项被销毁
    215     onDestroy: function (view) {
    216         //        console.log('onDestroy', view.config.xtype || view.getItemId());
    217         this.viewStatus[view.config.xtype || view.getItemId()] = false;
    218     },
    219     /**
    220     * 不填写参数时,移除当前项,返回到上一项
    221     * 如果参数是数字,则从最后一项开始移除指定数目的项
    222     * 如果参数是string,则移除指定类型的项
    223     * 如果参数是项,则移除传入的项
    224     * 不论参数如何,都会保留一个活动项
    225     * @return {Ext.Component} 当前活动项
    226     */
    227     pop: function (count) {
    228         if (this.beforePop(count)) {
    229             return this.doPop();
    230         }
    231     },
    232     /**
    233     * @private
    234     *删除指定项
    235     */
    236     beforePop: function (count) {
    237         var me = this,
    238         innerItems = me.getInnerItems();
    239         if (Ext.isString(count) || Ext.isObject(count)) {
    240             var last = innerItems.length - 1,
    241             i;
    242             for (i = last; i >= 0; i--) {
    243                 if ((Ext.isString(count) && Ext.ComponentQuery.is(innerItems[i], count)) || (Ext.isObject(count) && count == innerItems[i])) {
    244                     //获得移除项序号
    245                     count = last - i;
    246                     break;
    247                 }
    248             }
    249             if (!Ext.isNumber(count)) {
    250                 return false;
    251             }
    252         }
    253         var ln = innerItems.length,
    254         toRemove;
    255         //默认移除一项
    256         if (!Ext.isNumber(count) || count < 1) {
    257             count = 1;
    258         }
    259         //当我们试图移除更多视图时
    260         count = Math.min(count, ln - 1);
    261         if (count) {
    262             this.viewStackPop(count);
    263             //开始移除视图
    264             toRemove = innerItems.splice(-count, count - 1);
    265             for (i = 0; i < toRemove.length; i++) {
    266                 this.remove(toRemove[i]);
    267             }
    268             return true;
    269         }
    270         return false;
    271     },
    272     /**
    273     * @private
    274     *移除最后一项
    275     */
    276     doPop: function () {
    277         var me = this,
    278         innerItems = this.getInnerItems(),
    279         ord = innerItems[innerItems.length - 1];
    280         me.remove(ord);
    281         //触发被移除项的事件
    282         return this.getActiveItem();
    283     },
    284     doResetActiveItem: function (innerIndex) {
    285         var me = this,
    286         innerItems = me.getInnerItems(),
    287         animation = me.getLayout().getAnimation();
    288         if (innerIndex > 0) {
    289             if (animation && animation.isAnimation) {
    290                 animation.setReverse(true);
    291             }
    292             me.setActiveItem(innerIndex - 1);
    293         }
    294     },
    295     /**
    296     * @private 
    297     *执行移除项,调用remove方法后自动执行
    298     */
    299     doRemove: function () {
    300         var animation = this.getLayout().getAnimation();
    301         if (animation && animation.isAnimation) {
    302             animation.setReverse(false);
    303         }
    304         this.callParent(arguments);
    305     },
    306     /**
    307     * @private 
    308     *执行添加项,调用add方法后自动执行
    309     */
    310     onItemAdd: function (item, index) {
    311         if (item.isInnerItem()) {
    312             var xtype = item.config.xtype || item.getItemId();
    313             //如果配置了items,会先于initialize执行,所以需要初始化历史纪录
    314             this.initStatus();
    315             this.viewStatus[xtype] = true;
    316             this.viewStack.push(xtype);
    317             //添加监听
    318             item.on({
    319                 scope: this,
    320                 activate: 'onActivate',
    321                 destroy: 'onDestroy'
    322             });
    323         }
    324         this.doItemLayoutAdd(item, index);
    325         if (!this.isItemsInitializing && item.isInnerItem()) {
    326             this.setActiveItem(item);
    327         }
    328         if (this.initialized) {
    329             this.fireEvent('add', this, item, index);
    330         }
    331     },
    332     /**
    333     * 移除第一项和最后项之间的所有项(包括最后项)
    334     * @return {Ext.Component} 当前活动视图
    335     */
    336     reset: function (noUp) {
    337         return this.pop(this.getInnerItems().length);
    338     },
    339     //除了指定项,从倒数第二项开始移除
    340     popAll: function (xtype) {
    341         var me = this,
    342         innerItems = this.getInnerItems(),
    343         length = innerItems.length - 1,
    344         oldXtype,
    345         ord,
    346         i;
    347         this.viewStack = [xtype];
    348         for (i = length; i > -1; i--) {
    349             /*过滤掉需要显示的视图*/
    350             ord = innerItems[i];
    351             oldXtype = ord.config.xtype || ord.getItemId();
    352             if (i == length) {
    353                 me.viewStack.push(oldXtype);
    354             } else if (oldXtype != xtype) {
    355                 me.remove(ord, true);
    356             }
    357         }
    358     },
    359     //返回上一个历史记录
    360     onBackButtonTap: function () {
    361         this.pop();
    362         this.fireEvent('back', this);
    363     }
    364 });

    主视图js:

     1 /*
     2 *主视图,负责视图切换
     3 */
     4 Ext.define('app.view.Main', {
     5     extend: 'ux.CardPanel',
     6     requires: ['app.view.Home', 'Ext.picker.Picker', 'app.view.uitl.MyBar', 'app.view.user.Site'],
     7     xtype: 'main',
     8     config: {
     9         id: 'main',
    10         cls: 'cardPanel',
    11         backBtn: {
    12             iconCls: 'reply',
    13             iconMask: true,
    14             cls: 'replyBtn'
    15         },
    16         //items只能配置一项
    17         items: [{
    18             xtype: 'home'
    19         }]
    20     }
    21 });

    子视图js:

     1 Ext.define('app.view.message.List', {
     2     alternateClassName: 'messageList',
     3     extend: 'Ext.List',
     4     xtype: 'messageList',
     5     requires: ['Ext.plugin.ListPaging'],
     6     config: {
     7         cls: 'list',
     8         //标题
     9         title: '校园资讯',
    10         //用于控制navBarItems中的css
    11         pCls: '',
    12         //底部导航栏,直接填写alternateClassName
    13         btmBar: 'myBar',
    16         //额外的按钮组,只能是按钮组。不能添加其他属性
    17         navBarItems: [{
    18             itemId: 'mBtn',
    19             xtype: 'button',
    20             align: 'right',
    21             iconMask: true,
    22             cls: 'nBg',
    23             iconCls: 'search',
    24             action: 'show',
    25             show: 'messageSearch'
    26         }],
    27         plugins: [{
    28             xclass: 'Ext.plugin.ListPaging'
    29         }],
    30         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>',
    31         store: 'messageList'
    32     }
    33 });

    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

  • 相关阅读:
    第4月第1天 makefile automake
    第3月30天 UIImage imageWithContentsOfFile卡顿 Can't add self as subview MPMoviePlayerControlle rcrash
    第3月第27天 uitableviewcell复用
    learning uboot fstype command
    learning uboot part command
    linux command dialog
    linux command curl and sha256sum implement download verification package
    learning shell script prompt to run with superuser privileges (4)
    learning shell get script absolute path (3)
    learning shell args handing key=value example (2)
  • 原文地址:https://www.cnblogs.com/mlzs/p/3294889.html
Copyright © 2011-2022 走看看