ListItem.ts 5.9 KB

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