ListItem.ts 6.0 KB

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