810 lines
15 KiB
JavaScript
810 lines
15 KiB
JavaScript
|
|
/******************************************************************
|
||
|
|
* Copyright(C) 2019 - 2020 Nx Studio
|
||
|
|
*
|
||
|
|
* 动态扩充列表(上下向)
|
||
|
|
*
|
||
|
|
* 2018.05.18
|
||
|
|
******************************************************************/
|
||
|
|
|
||
|
|
cc.Class( {
|
||
|
|
|
||
|
|
extends: cc.Component,
|
||
|
|
|
||
|
|
properties: {
|
||
|
|
|
||
|
|
svcKey: {
|
||
|
|
default : "",
|
||
|
|
displayName : "用途标签"
|
||
|
|
},
|
||
|
|
|
||
|
|
fabItem: {
|
||
|
|
default : null,
|
||
|
|
type : cc.Prefab,
|
||
|
|
displayName : "表项模板(二选一)"
|
||
|
|
},
|
||
|
|
|
||
|
|
tmpItem: {
|
||
|
|
default : null,
|
||
|
|
type : cc.Node,
|
||
|
|
displayName : "表项模板(二选一)"
|
||
|
|
},
|
||
|
|
|
||
|
|
bindSCV: {
|
||
|
|
default : null,
|
||
|
|
type : cc.ScrollView,
|
||
|
|
displayName : "操作列表"
|
||
|
|
},
|
||
|
|
|
||
|
|
autoRow: {
|
||
|
|
default : true,
|
||
|
|
displayName : "单行宽度自适应",
|
||
|
|
},
|
||
|
|
|
||
|
|
autoSpacePer: {
|
||
|
|
default : cc.v2( 1.1, 1.1 ),
|
||
|
|
displayName : "自适应间隙百分比",
|
||
|
|
},
|
||
|
|
|
||
|
|
cntInRow: {
|
||
|
|
default : 1,
|
||
|
|
displayName : "单行个数(0为自动)"
|
||
|
|
},
|
||
|
|
|
||
|
|
itemHeight: {
|
||
|
|
default : 0,
|
||
|
|
displayName : "单项高度(0为自动)"
|
||
|
|
},
|
||
|
|
|
||
|
|
jumpBottom: {
|
||
|
|
default : true,
|
||
|
|
displayName : "重置是否到底",
|
||
|
|
},
|
||
|
|
|
||
|
|
activeOnce: {
|
||
|
|
default : true,
|
||
|
|
displayName : "仅激活一次"
|
||
|
|
},
|
||
|
|
|
||
|
|
selectHookers: {
|
||
|
|
default : [],
|
||
|
|
type : cc.Component.EventHandler,
|
||
|
|
displayName : "选择回调"
|
||
|
|
},
|
||
|
|
|
||
|
|
poolOpen: {
|
||
|
|
default : false,
|
||
|
|
displayName : "开启缓存池"
|
||
|
|
},
|
||
|
|
|
||
|
|
poolName: {
|
||
|
|
default : "",
|
||
|
|
displayName : "自定义标记"
|
||
|
|
},
|
||
|
|
|
||
|
|
poolCount: {
|
||
|
|
default : 10,
|
||
|
|
displayName : "缓存池大小"
|
||
|
|
},
|
||
|
|
|
||
|
|
nodEmpty: {
|
||
|
|
default : null,
|
||
|
|
type : cc.Node,
|
||
|
|
displayName : "空展示"
|
||
|
|
},
|
||
|
|
|
||
|
|
blankPage: {
|
||
|
|
default : false,
|
||
|
|
displayName : "整页填空"
|
||
|
|
},
|
||
|
|
|
||
|
|
},
|
||
|
|
|
||
|
|
// 编辑器特性
|
||
|
|
editor: {
|
||
|
|
|
||
|
|
// 允许当前组件在编辑器模式下运行
|
||
|
|
executeInEditMode: false,
|
||
|
|
|
||
|
|
// requireComponent 参数用来指定当前组件的依赖组件
|
||
|
|
requireComponent: null,
|
||
|
|
|
||
|
|
// 当本组件添加到节点上后,禁止同类型(含子类)的组件再添加到同一个节点,防止逻辑发生冲突
|
||
|
|
disallowMultiple: true,
|
||
|
|
|
||
|
|
// menu 用来将当前组件添加到组件菜单中,方便用户查找
|
||
|
|
menu: "Nx/组件|无限滚表",
|
||
|
|
|
||
|
|
},
|
||
|
|
|
||
|
|
// 获取表项样本
|
||
|
|
getT: function() {
|
||
|
|
|
||
|
|
if( this.tmpItem ) {
|
||
|
|
this.tmpItem.active = false;
|
||
|
|
return this.tmpItem;
|
||
|
|
}
|
||
|
|
|
||
|
|
if( this.fabItem ) {
|
||
|
|
this.tmpItem = cc.instantiate( this.fabItem );
|
||
|
|
}
|
||
|
|
|
||
|
|
// 表项模板合法性判断
|
||
|
|
if( !this.tmpItem ||
|
||
|
|
!this.tmpItem.getComponent( "nx.fx.sv.expand.item" ) ) {
|
||
|
|
nx.error( "[FxExpandSV]无效的列表表项模板!" );
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
|
||
|
|
// 开启对象池
|
||
|
|
if( this.poolOpen && !this.pool ) {
|
||
|
|
|
||
|
|
let key = this.fabItem ? this.fabItem.name : this.poolName;
|
||
|
|
if( nx.dt.strEmpty( key ) ) {
|
||
|
|
nx.warn( "[SVC]开启对象池失败,无效的标记名!" );
|
||
|
|
this.poolOpen = false;
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
this.pool = nx.pools.getPool( key, this.tmpItem, this.poolCount );
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
this.tmpItem.active = false;
|
||
|
|
return this.tmpItem;
|
||
|
|
|
||
|
|
},
|
||
|
|
|
||
|
|
// 加载
|
||
|
|
onLoad: function() {
|
||
|
|
|
||
|
|
// 操作列表
|
||
|
|
if( !this.bindSCV ) {
|
||
|
|
this.bindSCV = this.node.getComponent( cc.ScrollView );
|
||
|
|
if( !this.bindSCV ) {
|
||
|
|
nx.error( "[FxExpandSV]无效的操作列表!" );
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// 表项模板合法性判断
|
||
|
|
this.getT();
|
||
|
|
|
||
|
|
// 初始化占位节点
|
||
|
|
this.initPlaceholder();
|
||
|
|
|
||
|
|
// 滚动条件设定
|
||
|
|
this.dtSroll = 0;
|
||
|
|
if( this.tmpNode ){
|
||
|
|
this.ckScroll = this.tmpNode.height * 0.25;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
},
|
||
|
|
|
||
|
|
// 显示
|
||
|
|
onEnable: function() {
|
||
|
|
|
||
|
|
// 监听列表事件
|
||
|
|
if( this.bindSCV ) {
|
||
|
|
this.bindSCV.node.on( "scrolling", this.onScrolling, this );
|
||
|
|
}
|
||
|
|
|
||
|
|
},
|
||
|
|
|
||
|
|
// 隐藏
|
||
|
|
onDisable: function() {
|
||
|
|
|
||
|
|
// 监听列表事件
|
||
|
|
if( this.bindSCV ) {
|
||
|
|
this.bindSCV.node.off( "scrolling", this.onScrolling, this );
|
||
|
|
}
|
||
|
|
|
||
|
|
},
|
||
|
|
|
||
|
|
// 清理
|
||
|
|
clean: function() {
|
||
|
|
|
||
|
|
// 清除聚焦
|
||
|
|
if( nx.dt.arrNEmpty( this.focusList ) ) {
|
||
|
|
this.cleanFocus();
|
||
|
|
}
|
||
|
|
this.focusList = [];
|
||
|
|
|
||
|
|
// 监听撤销
|
||
|
|
let content = this.bindSCV.content;
|
||
|
|
content.off( "size-changed", this.onListSizeChanged, this );
|
||
|
|
|
||
|
|
// 来源解除
|
||
|
|
this.data = null;
|
||
|
|
|
||
|
|
// 当前激活
|
||
|
|
this.actIndexs = [];
|
||
|
|
|
||
|
|
// 列表清理
|
||
|
|
let chd = content.children;
|
||
|
|
for( let i in chd ) {
|
||
|
|
let node = chd[i];
|
||
|
|
if( node.svItem ) {
|
||
|
|
node.svItem.rebind( -1, null, this.svcKey );
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// 节点回收
|
||
|
|
if( this.pool ) {
|
||
|
|
for( let i in chd ) {
|
||
|
|
let node = chd[i];
|
||
|
|
if( node.svItem ) {
|
||
|
|
this.pool.put( node.svItem.node );
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
content.removeAllChildren();
|
||
|
|
},
|
||
|
|
|
||
|
|
// 重建列表
|
||
|
|
rebuild: function( _data ) {
|
||
|
|
|
||
|
|
if( !nx.dt.arrGood( _data ) ) {
|
||
|
|
nx.error( "[FxExpandSV]无效的列表来源类型!" );
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
// 表项模板合法性判断
|
||
|
|
this.getT();
|
||
|
|
|
||
|
|
// 初始化占位节点
|
||
|
|
this.initPlaceholder();
|
||
|
|
|
||
|
|
// 滚动条件设定
|
||
|
|
this.dtSroll = 0;
|
||
|
|
this.ckScroll = this.tmpNode.height * 0.25;
|
||
|
|
|
||
|
|
this.clean();
|
||
|
|
this.data = [];
|
||
|
|
|
||
|
|
// 是否填空
|
||
|
|
if( this.blankPage ) {
|
||
|
|
let row = Math.ceil( this.bindSCV.node.height / this.tmpNode.height );
|
||
|
|
let count = this.cntInRow * row;
|
||
|
|
if( _data.length < count ) {
|
||
|
|
for( let i = _data.length; i < count; ++i ) {
|
||
|
|
_data.push( {} );
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// 批量追加
|
||
|
|
this.append( _data, true );
|
||
|
|
|
||
|
|
// 监听挂载
|
||
|
|
let content = this.bindSCV.content;
|
||
|
|
content.on( "size-changed", this.onListSizeChanged, this );
|
||
|
|
|
||
|
|
// 空展示
|
||
|
|
if( this.nodEmpty ) {
|
||
|
|
this.nodEmpty.active = nx.dt.arrEmpty( _data );
|
||
|
|
}
|
||
|
|
|
||
|
|
},
|
||
|
|
|
||
|
|
// 追加
|
||
|
|
append: function( _data, _fixPos = false ) {
|
||
|
|
|
||
|
|
if( !this.data ) {
|
||
|
|
nx.error( "[FxExpandSV]先重建后追加!" );
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
if( !nx.dt.arrGood( _data ) ) {
|
||
|
|
nx.error( "[FxExpandSV]无效的列表来源类型!" );
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
// 逐个创建
|
||
|
|
_data.forEach( _dt => {
|
||
|
|
this._appendSingle( _dt );
|
||
|
|
} );
|
||
|
|
|
||
|
|
// 强刷布局
|
||
|
|
let content = this.bindSCV.content;
|
||
|
|
let cmp = content.getComponent( cc.Layout );
|
||
|
|
if( cmp ) {
|
||
|
|
cmp.updateLayout();
|
||
|
|
}
|
||
|
|
|
||
|
|
// 位置修正
|
||
|
|
if( _fixPos ) {
|
||
|
|
|
||
|
|
if( this.jumpBottom ) {
|
||
|
|
this.bindSCV.scrollToBottom();
|
||
|
|
this.freshRange( _data.length - 1, false );
|
||
|
|
} else {
|
||
|
|
this.bindSCV.scrollToTop();
|
||
|
|
this.freshRange( 0, true );
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
this.freshRange( this.actIndexs[0], true );
|
||
|
|
}
|
||
|
|
|
||
|
|
},
|
||
|
|
|
||
|
|
// 删除
|
||
|
|
remove: function( _indexes ) {
|
||
|
|
|
||
|
|
if( nx.dt.arrEmpty( _indexes ) ) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
// 逐个销毁
|
||
|
|
_indexes.forEach( _idx => {
|
||
|
|
this._removeSingle( _idx );
|
||
|
|
} );
|
||
|
|
|
||
|
|
// 数组清理
|
||
|
|
nx.dt.arrDelete( this.data, ( _t ) => {
|
||
|
|
return _t == undefined;
|
||
|
|
}, false );
|
||
|
|
|
||
|
|
// 节点序列重排
|
||
|
|
this._reorderList();
|
||
|
|
|
||
|
|
// 强刷布局
|
||
|
|
let content = this.bindSCV.content;
|
||
|
|
let cmp = content.getComponent( cc.Layout );
|
||
|
|
if( cmp ) {
|
||
|
|
cmp.updateLayout();
|
||
|
|
}
|
||
|
|
|
||
|
|
// 刷新
|
||
|
|
this.freshRange( 0, true );
|
||
|
|
|
||
|
|
},
|
||
|
|
|
||
|
|
// 是否聚焦
|
||
|
|
isFocus: function( _index ) {
|
||
|
|
return nx.dt.arrMember( this.focusList, _index );
|
||
|
|
},
|
||
|
|
|
||
|
|
// 添加聚焦
|
||
|
|
addFocus: function( _index ) {
|
||
|
|
|
||
|
|
if( !this.data ) {
|
||
|
|
nx.warn( "[FxExpandSV]無法添加聚焦,暫無數據!" );
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
// 越界
|
||
|
|
if( _index < 0 ||
|
||
|
|
_index >= this.data.length ) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
// 是否聚焦
|
||
|
|
if( this.isFocus( _index ) ) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
this.focusList.push( _index );
|
||
|
|
|
||
|
|
let chd = this.bindSCV.content.children;
|
||
|
|
let cur = chd[_index];
|
||
|
|
if( cur && cur.svItem ) {
|
||
|
|
cur.svItem.onFocus();
|
||
|
|
}
|
||
|
|
|
||
|
|
},
|
||
|
|
|
||
|
|
// 移除聚焦
|
||
|
|
removeFocus: function( _index, _justArray = false ) {
|
||
|
|
|
||
|
|
if( !_justArray ) {
|
||
|
|
let chd = this.bindSCV.content.children;
|
||
|
|
let item = chd[_index];
|
||
|
|
if( item && item.svItem ) {
|
||
|
|
item.svItem.outFocus();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
nx.dt.arrDelete( this.focusList, ( _t ) => {
|
||
|
|
return _t == _index;
|
||
|
|
} );
|
||
|
|
|
||
|
|
},
|
||
|
|
|
||
|
|
// 清除聚焦
|
||
|
|
cleanFocus: function( _justArray = false ) {
|
||
|
|
|
||
|
|
if( !_justArray &&
|
||
|
|
nx.dt.arrNEmpty( this.focusList ) ) {
|
||
|
|
let chd = this.bindSCV.content.children;
|
||
|
|
for( let i = 0; i < this.focusList.length; ++i ) {
|
||
|
|
let index = this.focusList[i];
|
||
|
|
let item = chd[index];
|
||
|
|
if( item && item.svItem ) {
|
||
|
|
item.svItem.outFocus();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
this.focusList = [];
|
||
|
|
|
||
|
|
},
|
||
|
|
|
||
|
|
// 初始化占位节点
|
||
|
|
initPlaceholder: function() {
|
||
|
|
|
||
|
|
// 计算占位符尺寸
|
||
|
|
let tempN = this.getT();
|
||
|
|
let content = this.bindSCV.content;
|
||
|
|
if( tempN ){
|
||
|
|
// 单行自动
|
||
|
|
if( this.autoRow ||
|
||
|
|
!nx.dt.numPositive( this.cntInRow, false ) ) {
|
||
|
|
this.cntInRow = Math.floor( content.width / ( tempN.width * this.autoSpacePer.x ) );
|
||
|
|
if( this.cntInRow <= 0 ) {
|
||
|
|
// nx.error( "无限列表宽度无效!" );
|
||
|
|
this.cntInRow = 1;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// 高度自适应
|
||
|
|
if( !nx.dt.numPositive( this.itemHeight, false ) ) {
|
||
|
|
this.itemHeight = tempN.height * this.autoSpacePer.y;
|
||
|
|
}
|
||
|
|
|
||
|
|
let width = Math.floor( content.width / this.cntInRow );
|
||
|
|
let height = this.itemHeight;
|
||
|
|
let ph = new cc.Node( "tmp" );
|
||
|
|
ph.width = width;
|
||
|
|
ph.height = height;
|
||
|
|
|
||
|
|
// 保存
|
||
|
|
this.tmpNode = ph;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
},
|
||
|
|
|
||
|
|
// 刷新可视区域
|
||
|
|
freshRange: function( _from, _toDn ) {
|
||
|
|
|
||
|
|
// console.log( "刷新!" );
|
||
|
|
|
||
|
|
let sy = this.bindSCV.getScrollOffset().y;
|
||
|
|
let ey = sy + this.bindSCV.node.height;
|
||
|
|
let children = this.bindSCV.content.children;
|
||
|
|
|
||
|
|
// 碰撞检测
|
||
|
|
let collision = function( _node ) {
|
||
|
|
|
||
|
|
if( !_node || !_node.active ) {
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
let y = Math.abs( _node.y );
|
||
|
|
let up = y - _node.height / 2;
|
||
|
|
let dn = y + _node.height / 2;
|
||
|
|
|
||
|
|
// 中间
|
||
|
|
if( up >= sy && dn <= ey ) {
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
// 横跨
|
||
|
|
if( up <= sy && dn >= ey ) {
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
// 上交||下交
|
||
|
|
if( ( up <= sy && dn >= sy ) ||
|
||
|
|
( up <= ey && dn >= sy ) ) {
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
return false;
|
||
|
|
};
|
||
|
|
|
||
|
|
// 扫描
|
||
|
|
let actives = [];
|
||
|
|
if( _toDn ) { // 向后扫描
|
||
|
|
|
||
|
|
let od = false;
|
||
|
|
for( let i = _from; i < children.length; ++i ) {
|
||
|
|
|
||
|
|
let nd = children[i];
|
||
|
|
if( !nd || !nd.active ) {
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
|
||
|
|
if( collision( nd ) ) {
|
||
|
|
od = true;
|
||
|
|
actives.push( i );
|
||
|
|
nd.opacity = 255;
|
||
|
|
} else {
|
||
|
|
nd.opacity = 0;
|
||
|
|
if( od ) break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else { // 向前扫描
|
||
|
|
|
||
|
|
let od = false;
|
||
|
|
for( let i = _from; i >= 0; --i ) {
|
||
|
|
|
||
|
|
let nd = children[i];
|
||
|
|
if( !nd || !nd.active ) {
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
|
||
|
|
if( collision( nd ) ) {
|
||
|
|
od = true;
|
||
|
|
actives.push( i );
|
||
|
|
nd.opacity = 255;
|
||
|
|
} else {
|
||
|
|
if( od ) break;
|
||
|
|
nd.opacity = 0;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// 排序
|
||
|
|
actives.sort( ( a, b ) => {
|
||
|
|
return a - b;
|
||
|
|
} );
|
||
|
|
|
||
|
|
// 列表项激活
|
||
|
|
this.activeItems( actives );
|
||
|
|
|
||
|
|
},
|
||
|
|
|
||
|
|
// 列表项激活
|
||
|
|
activeItems: function( _indexs ) {
|
||
|
|
|
||
|
|
// console.log( "列表项激活:" );
|
||
|
|
// console.log( "老:", this.actIndexs );
|
||
|
|
// console.log( "新:", _indexs );
|
||
|
|
|
||
|
|
if( nx.dt.arrEmpty( _indexs ) ) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
// 统计新增和过期
|
||
|
|
let adds = [];
|
||
|
|
let outs = [];
|
||
|
|
for( let i in _indexs ) {
|
||
|
|
if( !nx.dt.arrMember( this.actIndexs, _indexs[i] ) ) {
|
||
|
|
adds.push( _indexs[i] );
|
||
|
|
}
|
||
|
|
}
|
||
|
|
for( let i in this.actIndexs ) {
|
||
|
|
if( !nx.dt.arrMember( _indexs, this.actIndexs[i] ) ) {
|
||
|
|
outs.push( _indexs[i] );
|
||
|
|
}
|
||
|
|
}
|
||
|
|
// console.log( "增:", adds );
|
||
|
|
// console.log( "减:", outs );
|
||
|
|
|
||
|
|
// 更新当前激活列表
|
||
|
|
this.actIndexs = _indexs;
|
||
|
|
|
||
|
|
let open = nx.dt.arrNEmpty( this.selectHookers );
|
||
|
|
|
||
|
|
// 逐个新增
|
||
|
|
const children = this.bindSCV.content.children;
|
||
|
|
for( let i in adds ) {
|
||
|
|
|
||
|
|
let idx = adds[i]
|
||
|
|
let node = children[idx];
|
||
|
|
|
||
|
|
// 不需要新建
|
||
|
|
if( node.active && node.svItem && node.svItem.node.active ) {
|
||
|
|
// 需要inShow
|
||
|
|
if( !this.activeOnce && !node.svShow ) {
|
||
|
|
node.svShow = true;
|
||
|
|
node.svItem.inShow();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
|
||
|
|
// 新建
|
||
|
|
if( !node.svItem ) {
|
||
|
|
let tempN = this.getT();
|
||
|
|
let item = this.pool ? this.pool.get() : cc.instantiate( tempN );
|
||
|
|
item.name = "node";
|
||
|
|
item.active = true;
|
||
|
|
item.parent = node;
|
||
|
|
item.position = cc.Vec2.ZERO;
|
||
|
|
item.svc = this;
|
||
|
|
node.svItem = item.getComponent( "nx.fx.sv.expand.item" );
|
||
|
|
node.svItem.openTouch( open, this._onTouchItem.bind( this ) );
|
||
|
|
}
|
||
|
|
|
||
|
|
node.active = true;
|
||
|
|
node.svItem.node.active = true;
|
||
|
|
node.svItem.rebind( idx, this.data[idx], this.svcKey );
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// 需要outShow
|
||
|
|
if( !this.activeOnce && outs.length > 0 ) {
|
||
|
|
|
||
|
|
for( let i in adds ) {
|
||
|
|
|
||
|
|
let idx = adds[i]
|
||
|
|
let node = children[idx];
|
||
|
|
if( !node || !node.svItem || !node.svShow ) {
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
|
||
|
|
node.svShow = false;
|
||
|
|
node.svItem.outShow();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
},
|
||
|
|
|
||
|
|
// 列表滚动
|
||
|
|
onScrolling: function() {
|
||
|
|
|
||
|
|
// 无效越界屏蔽
|
||
|
|
let y = this.bindSCV.getScrollOffset().y;
|
||
|
|
let max = this.bindSCV.getMaxScrollOffset().y;
|
||
|
|
if( y < 0 || y > max ) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
// 不需要更新
|
||
|
|
let dt = y - this.dtSroll;
|
||
|
|
if( Math.abs( dt ) < this.ckScroll ||
|
||
|
|
this.actIndexs.length == 0 ) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
// 刷新
|
||
|
|
let from = ( dt > 0 ) ? this.actIndexs[0] : this.actIndexs[this.actIndexs.length-1];
|
||
|
|
let toDn = ( dt > 0 ) ? true : false;
|
||
|
|
this.freshRange( from, toDn );
|
||
|
|
|
||
|
|
this.dtSroll = y;
|
||
|
|
|
||
|
|
},
|
||
|
|
|
||
|
|
// 列表动态长度改变
|
||
|
|
onListSizeChanged: function() {
|
||
|
|
|
||
|
|
// console.log( "onListSizeChanged" );
|
||
|
|
if( this.actIndexs.length > 0 ) {
|
||
|
|
this.freshRange( this.actIndexs[0], true );
|
||
|
|
}
|
||
|
|
},
|
||
|
|
|
||
|
|
// 单个追加
|
||
|
|
_appendSingle: function( _dt ) {
|
||
|
|
|
||
|
|
if( !_dt ) {
|
||
|
|
nx.error( "[FxExpandSV]追加失败,空数据!" );
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
// 追加数据
|
||
|
|
this.data.push( _dt );
|
||
|
|
|
||
|
|
// 列表项同步
|
||
|
|
let content = this.bindSCV.content;
|
||
|
|
let index = this.data.length - 1;
|
||
|
|
let node = content.children[index];
|
||
|
|
if( !node ) {
|
||
|
|
// 创建节点
|
||
|
|
node = cc.instantiate( this.tmpNode );
|
||
|
|
node.parent = content;
|
||
|
|
}
|
||
|
|
|
||
|
|
// 这个时候svOrder绝对不会大于0,否则视为有BUG
|
||
|
|
if( nx.dt.numPositive( node.svOrder, false ) ) {
|
||
|
|
nx.error( "[FxExpandSV]追加出错,缓存节点报错:%d", index );
|
||
|
|
}
|
||
|
|
|
||
|
|
node.active = true;
|
||
|
|
node.svShow = false;
|
||
|
|
node.svOrder = index;
|
||
|
|
|
||
|
|
},
|
||
|
|
|
||
|
|
// 单个销毁
|
||
|
|
_removeSingle: function( _index ) {
|
||
|
|
|
||
|
|
// 越界
|
||
|
|
if( _index < 0 || _index >= this.data.length ) {
|
||
|
|
nx.error( "[FxExpandSV]单个销毁失败,无效位置:%d", _index );
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
// 删除数据
|
||
|
|
delete this.data[_index];
|
||
|
|
|
||
|
|
// 聚焦移除
|
||
|
|
this.removeFocus( _index, true );
|
||
|
|
|
||
|
|
// 删除节点
|
||
|
|
let chd = this.bindSCV.content.children;
|
||
|
|
for( let i in chd ) {
|
||
|
|
let node = chd[i];
|
||
|
|
if( node && node.svOrder == _index ) {
|
||
|
|
node.destroy();
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// 失败
|
||
|
|
nx.error( "[FxExpandSV]单个销毁失败,节点销毁失败:%d", _index );
|
||
|
|
|
||
|
|
},
|
||
|
|
|
||
|
|
// 节点序列重排
|
||
|
|
_reorderList: function() {
|
||
|
|
|
||
|
|
let idx = 0;
|
||
|
|
let chd = this.bindSCV.content.children;
|
||
|
|
for( let i in chd ) {
|
||
|
|
let node = chd[i];
|
||
|
|
node.svOrder = node.active ? idx++ : -1;
|
||
|
|
if( !node.active && node.svItem ) {
|
||
|
|
if( node.svItem != -1 ) {
|
||
|
|
node.svItem.rebind( -1, null, this.svcKey );
|
||
|
|
}
|
||
|
|
node.svItem.node.active = false;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// 聚焦清理
|
||
|
|
this.cleanFocus( true );
|
||
|
|
},
|
||
|
|
|
||
|
|
// 节点点击
|
||
|
|
_onTouchItem: function( _item ) {
|
||
|
|
|
||
|
|
// 无效
|
||
|
|
if( !_item ||
|
||
|
|
!nx.dt.numPositive( _item.index, true ) ) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
// 有监听
|
||
|
|
if( nx.dt.arrNEmpty( this.selectHookers ) ) {
|
||
|
|
|
||
|
|
this.selectHookers.forEach( _hk => {
|
||
|
|
_hk.customEventData = _item;
|
||
|
|
} );
|
||
|
|
|
||
|
|
nx.dt.trycatch( () => {
|
||
|
|
cc.Component.EventHandler.emitEvents( this.selectHookers );
|
||
|
|
} )
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
},
|
||
|
|
|
||
|
|
// 数据/节点同步检测
|
||
|
|
checkData: function() {
|
||
|
|
|
||
|
|
let len = 0;
|
||
|
|
let orders = [];
|
||
|
|
let chd = this.bindSCV.content.children;
|
||
|
|
for( let i in chd ) {
|
||
|
|
let node = chd[i];
|
||
|
|
orders.push( node.svOrder );
|
||
|
|
if( node.active ) {
|
||
|
|
++len;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
nx.debug( "[FxExpandSV]同步检测:" );
|
||
|
|
nx.debug( "[FxExpandSV]\t数据:%d", this.data.length );
|
||
|
|
nx.debug( "[FxExpandSV]\t列表项: 总:%d 有效:%d", chd.length, len );
|
||
|
|
console.log( orders );
|
||
|
|
|
||
|
|
},
|
||
|
|
|
||
|
|
} );
|