ListItem.ts 6.2 KB

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