ListItem.ts 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. /******************************************
  2. * @author kL <klk0@qq.com>
  3. * @date 2019/6/6
  4. * @doc 列表Item组件.
  5. * 说明:
  6. * 1、此组件须配合List组件使用。(配套的配套的..)
  7. * @end
  8. ******************************************/
  9. const { ccclass, property, disallowMultiple, menu, executionOrder } = cc._decorator;
  10. import List from './List';
  11. enum SelectedType {
  12. NONE = 0,
  13. TOGGLE = 1,
  14. SWITCH = 2,
  15. }
  16. @ccclass
  17. @disallowMultiple()
  18. @menu('自定义组件/List Item')
  19. @executionOrder(-5001) //先于List
  20. export default class ListItem extends cc.Component {
  21. //图标
  22. @property({ type: cc.Sprite, tooltip: CC_DEV && '图标' })
  23. icon: cc.Sprite = null;
  24. //标题
  25. @property({ type: cc.Node, tooltip: CC_DEV && '标题' })
  26. title: cc.Node = null;
  27. //选择模式
  28. @property({
  29. type: cc.Enum(SelectedType),
  30. tooltip: CC_DEV && '选择模式'
  31. })
  32. selectedMode: SelectedType = SelectedType.NONE;
  33. //被选标志
  34. @property({
  35. type: cc.Node, tooltip: CC_DEV && '被选标志',
  36. visible() { return this.selectedMode > SelectedType.NONE }
  37. })
  38. selectedFlag: cc.Node = null;
  39. //被选择的SpriteFrame
  40. @property({
  41. type: cc.SpriteFrame, tooltip: CC_DEV && '被选择的SpriteFrame',
  42. visible() { return this.selectedMode == SelectedType.SWITCH }
  43. })
  44. selectedSpriteFrame: cc.SpriteFrame = null;
  45. //未被选择的SpriteFrame
  46. _unselectedSpriteFrame: cc.SpriteFrame = null;
  47. //自适应尺寸
  48. @property({
  49. tooltip: CC_DEV && '自适应尺寸(宽或高)',
  50. })
  51. adaptiveSize: boolean = false;
  52. //选择
  53. _selected: boolean = false;
  54. set selected(val: boolean) {
  55. this._selected = val;
  56. if (!this.selectedFlag)
  57. return;
  58. switch (this.selectedMode) {
  59. case SelectedType.TOGGLE:
  60. this.selectedFlag.active = val;
  61. break;
  62. case SelectedType.SWITCH:
  63. let sp: cc.Sprite = this.selectedFlag.getComponent(cc.Sprite);
  64. if (sp)
  65. sp.spriteFrame = val ? this.selectedSpriteFrame : this._unselectedSpriteFrame;
  66. break;
  67. }
  68. }
  69. get selected() {
  70. return this._selected;
  71. }
  72. //按钮组件
  73. private _btnCom: any;
  74. get btnCom() {
  75. if (!this._btnCom)
  76. this._btnCom = this.node.getComponent(cc.Button);
  77. return this._btnCom;
  78. }
  79. //依赖的List组件
  80. public list: List;
  81. //是否已经注册过事件
  82. private _eventReg = false;
  83. //序列id
  84. public listId: number;
  85. onLoad() {
  86. // //没有按钮组件的话,selectedFlag无效
  87. // if (!this.btnCom)
  88. // this.selectedMode == SelectedType.NONE;
  89. //有选择模式时,保存相应的东西
  90. if (this.selectedMode == SelectedType.SWITCH) {
  91. let com: cc.Sprite = this.selectedFlag.getComponent(cc.Sprite);
  92. this._unselectedSpriteFrame = com.spriteFrame;
  93. }
  94. }
  95. onDestroy() {
  96. this.node.off(cc.Node.EventType.SIZE_CHANGED, this._onSizeChange, this);
  97. }
  98. _registerEvent() {
  99. if (!this._eventReg) {
  100. if (this.btnCom && this.list.selectedMode > 0) {
  101. this.btnCom.clickEvents.unshift(this.createEvt(this, 'onClickThis'));
  102. }
  103. if (this.adaptiveSize) {
  104. this.node.on(cc.Node.EventType.SIZE_CHANGED, this._onSizeChange, this);
  105. }
  106. this._eventReg = true;
  107. }
  108. }
  109. _onSizeChange() {
  110. this.list._onItemAdaptive(this.node);
  111. }
  112. /**
  113. * 创建事件
  114. * @param {cc.Component} component 组件脚本
  115. * @param {string} handlerName 触发函数名称
  116. * @param {cc.Node} node 组件所在node(不传的情况下取component.node)
  117. * @returns cc.Component.EventHandler
  118. */
  119. createEvt(component: cc.Component, handlerName: string, node: cc.Node = null) {
  120. if (!component.isValid)
  121. return;//有些异步加载的,节点以及销毁了。
  122. component['comName'] = component['comName'] || component.name.match(/\<(.*?)\>/g).pop().replace(/\<|>/g, '');
  123. let evt = new cc.Component.EventHandler();
  124. evt.target = node || component.node;
  125. evt.component = component['comName'];
  126. evt.handler = handlerName;
  127. return evt;
  128. }
  129. showAni(aniType: number, callFunc: Function, del: boolean) {
  130. let acts: any[];
  131. switch (aniType) {
  132. case 0: //向上消失
  133. acts = [
  134. cc.scaleTo(.2, .7),
  135. cc.moveBy(.3, 0, this.node.height * 2),
  136. ];
  137. break;
  138. case 1: //向右消失
  139. acts = [
  140. cc.scaleTo(.2, .7),
  141. cc.moveBy(.3, this.node.width * 2, 0),
  142. ];
  143. break;
  144. case 2: //向下消失
  145. acts = [
  146. cc.scaleTo(.2, .7),
  147. cc.moveBy(.3, 0, this.node.height * -2),
  148. ];
  149. break;
  150. case 3: //向左消失
  151. acts = [
  152. cc.scaleTo(.2, .7),
  153. cc.moveBy(.3, this.node.width * -2, 0),
  154. ];
  155. break;
  156. default: //默认:缩小消失
  157. acts = [
  158. cc.scaleTo(.3, .1),
  159. ];
  160. break;
  161. }
  162. if (callFunc || del) {
  163. acts.push(cc.callFunc(() => {
  164. if (del) {
  165. this.list._delSingleItem(this.node);
  166. for (let n: number = this.list.displayData.length - 1; n >= 0; n--) {
  167. if (this.list.displayData[n].id == this.listId) {
  168. this.list.displayData.splice(n, 1);
  169. break;
  170. }
  171. }
  172. }
  173. callFunc();
  174. }));
  175. }
  176. this.node.runAction(cc.sequence(acts));
  177. }
  178. onClickThis() {
  179. this.list.selectedId = this.listId;
  180. }
  181. }