keyboard_guide_controller.dart 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. import 'package:flutter/cupertino.dart';
  2. import 'package:get/get.dart';
  3. import 'package:injectable/injectable.dart';
  4. import 'package:keyboard/module/keyboard_guide/enums/keyboard_guide_msg_type.dart';
  5. import 'package:keyboard/resource/string.gen.dart';
  6. import '../../base/base_controller.dart';
  7. import '../../data/bean/keyboard_guide_msg.dart';
  8. import '../../plugins/default_keyboard_change_listener.dart';
  9. import '../../plugins/keyboard_android_platform.dart';
  10. import '../../utils/keyboard_guide_record_util.dart';
  11. import '../../utils/toast_util.dart';
  12. import 'guide_overlay/keyboard_guide_overlay_dialog.dart';
  13. /// 键盘引导页面Controller
  14. @injectable
  15. class KeyboardGuidePageController extends BaseController {
  16. /// 引导消息的GlobalKey
  17. final GlobalKey guideMsgGlobalKey = GlobalKey();
  18. /// 第几条消息为引导消息
  19. final Rx<int> guideMsgIndex = 1.obs;
  20. /// TextField操作控制器
  21. final TextEditingController editingController = TextEditingController();
  22. /// ListView的滚动控制器
  23. final ScrollController scrollController = ScrollController();
  24. /// 输入框焦点
  25. final FocusNode inputFocusNode = FocusNode();
  26. /// 消息列表
  27. final RxList<KeyboardGuideMsg> msgList = <KeyboardGuideMsg>[].obs;
  28. /// 是否选择为了默认键盘
  29. final Rx<bool> isChooseDefaultKeyboard = false.obs;
  30. @override
  31. void onInit() {
  32. super.onInit();
  33. inputFocusNode.addListener(_handleTextFieldFocusChange);
  34. // 初始化消息列表
  35. _initMsgList();
  36. // 进入页面,就获取输入框焦点
  37. // inputFocusNode.requestFocus();
  38. _registerDefaultKeyboardChangeEvent();
  39. }
  40. @override
  41. void onClose() {
  42. // 取消监听
  43. inputFocusNode.removeListener(_handleTextFieldFocusChange);
  44. inputFocusNode.dispose();
  45. editingController.dispose();
  46. scrollController.dispose();
  47. _unRegisterDefaultKeyboardChangeEvent();
  48. super.onClose();
  49. }
  50. /// 监听默认键盘切换事件
  51. void _registerDefaultKeyboardChangeEvent() {
  52. DefaultKeyboardMonitor.registerDefaultKeyboardChangeEvent(
  53. handleDefaultKeyboardChange,
  54. );
  55. }
  56. /// 取消监听默认键盘切换事件
  57. void _unRegisterDefaultKeyboardChangeEvent() {
  58. DefaultKeyboardMonitor.unRegisterDefaultKeyboardChangeEvent(
  59. handleDefaultKeyboardChange,
  60. );
  61. }
  62. /// 处理默认键盘切换
  63. void handleDefaultKeyboardChange(bool isDefaultKeyboard) {
  64. isChooseDefaultKeyboard.value = isDefaultKeyboard;
  65. }
  66. /// 关闭页面
  67. clickBack() {
  68. Get.back();
  69. }
  70. /// 发送消息
  71. void sendMsg(String msg) {
  72. if (msg.isEmpty) {
  73. ToastUtil.show("请输入要发送的消息内容");
  74. return;
  75. }
  76. //添加消息到列表中
  77. _addMsg2List(msg, true);
  78. // 延迟生成对方的回复消息
  79. // Future.delayed(const Duration(milliseconds: 150), () {
  80. // //添加消息到列表中
  81. // _addMsg2List(_replyMessage2Client(msg), false);
  82. // });
  83. //清除输入框的内容
  84. editingController.clear();
  85. }
  86. // /// 测试,生成回复消息
  87. // String _replyMessage2Client(String clientMsg) {
  88. // return clientMsg
  89. // .replaceAll("我", "你")
  90. // .replaceAll("吗", "")
  91. // .replaceAll("?", "!")
  92. // .replaceAll("?", "!");
  93. // }
  94. /// 初始化消息列表
  95. void _initMsgList() {
  96. // 添加一些默认消息
  97. msgList.add(
  98. KeyboardGuideMsg(
  99. false,
  100. StringName.keyboardGuideTaReply1,
  101. KeyboardGuideMsgType.copy.type,
  102. DateTime.now().millisecond,
  103. ),
  104. );
  105. msgList.add(
  106. KeyboardGuideMsg(
  107. false,
  108. StringName.keyboardGuideTaReply2,
  109. KeyboardGuideMsgType.copy.type,
  110. DateTime.now().millisecond,
  111. ),
  112. );
  113. msgList.add(
  114. KeyboardGuideMsg(
  115. false,
  116. StringName.keyboardGuideTaReply3,
  117. KeyboardGuideMsgType.copy.type,
  118. DateTime.now().millisecond,
  119. ),
  120. );
  121. // 亲密度设置的引导消息
  122. msgList.add(
  123. KeyboardGuideMsg(
  124. false,
  125. StringName.keyboardGuideTaReply4,
  126. KeyboardGuideMsgType.intimacySetting.type,
  127. DateTime.now().millisecond,
  128. ),
  129. );
  130. }
  131. /// 添加消息到消息列表中
  132. void _addMsg2List(String msg, bool isMe) {
  133. msgList.add(
  134. KeyboardGuideMsg(
  135. isMe,
  136. msg,
  137. KeyboardGuideMsgType.normal.type,
  138. DateTime.now().millisecond,
  139. ),
  140. );
  141. update();
  142. _scrollToBottom();
  143. }
  144. /// 滚动列表到底部
  145. void _scrollToBottom() {
  146. if (scrollController.hasClients) {
  147. scrollController.jumpTo(scrollController.position.maxScrollExtent);
  148. }
  149. }
  150. /// 处理输入框的焦点变化
  151. void _handleTextFieldFocusChange() {
  152. // 输入框获取焦点,滚动列表到底部
  153. if (inputFocusNode.hasFocus) {
  154. Future.delayed(const Duration(milliseconds: 350), () {
  155. _scrollToBottom();
  156. });
  157. }
  158. }
  159. /// 显示引导覆盖层弹窗
  160. void showGuideOverlayDialog() {
  161. // 显示过引导弹窗,则不显示
  162. if (!KeyboardGuideRecordUtil.isFirstShowKeyboardGuide()) {
  163. return;
  164. }
  165. // 首帧结束后,再显示
  166. WidgetsBinding.instance.addPostFrameCallback((_) {
  167. KeyboardGuideOverlayDialog.show(
  168. guideMsgGlobalKey,
  169. onFinishCallback: () {
  170. // 设置未非首次显示
  171. KeyboardGuideRecordUtil.setFirstShowKeyboardGuide(false);
  172. },
  173. );
  174. });
  175. }
  176. }