import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; import 'package:keyboard/module/keyboard_guide/keyboard_guide_controller.dart'; import 'package:keyboard/router/app_pages.dart'; import 'package:keyboard/utils/toast_util.dart'; import 'package:lottie/lottie.dart'; import '../../base/base_page.dart'; import '../../data/bean/keyboard_guide_msg.dart'; import '../../resource/assets.gen.dart'; import '../../resource/colors.gen.dart'; import '../../resource/string.gen.dart'; import '../../utils/clipboard_util.dart'; import '../../utils/url_launcher_util.dart'; import '../../widget/app_lifecycle_widget.dart'; import '../intimacy_scale/intimacy_scale_page.dart'; import 'enums/keyboard_guide_msg_type.dart'; /// 键盘引导页面 class KeyboardGuidePage extends BasePage { const KeyboardGuidePage({super.key}); /// 跳转到键盘引导页 static void start() { Get.toNamed(RoutePath.keyboardGuide); } /// 跳转并关闭当前页 static void startAndOffMe() { Get.offNamed(RoutePath.keyboardGuide); } @override immersive() { return false; } @override Widget buildBody(BuildContext context) { return Scaffold( backgroundColor: backgroundColor(), body: AppLifecycleWidget( onAppLifecycleCallback: (isForeground) { // 完成教程 controller.setNotFirstShowKeyboardTutorial(); if (isForeground) { // 切换到前台时,重新检查设置,更新按钮状态 controller.checkSetting(); // 如果选择为默认键盘了,则尝试显示引导弹窗 if (controller.isDefaultKeyboard.value) { controller.showGuideOverlayDialog(); } } }, child: Column( children: [ // 标题栏 _buildTitleBar(), // 消息列表 Expanded(flex: 1, child: _buildContent()), // 底部输入栏 _buildBottomInput(), ], ), ), ); } // 标题栏 Widget _buildTitleBar() { return Container( color: backgroundColor(), height: kToolbarHeight, padding: EdgeInsets.symmetric(horizontal: 16.0), child: Row( children: [ // 返回按钮 GestureDetector( onTap: controller.clickBack, child: Assets.images.iconMineBackArrow.image( width: 24.w, height: 24.h, ), ), // 标题 Expanded( child: Container( alignment: Alignment.center, child: Text("", style: const TextStyle(fontSize: 18)), ), ), // 右侧按钮 GestureDetector( onTap: () async { bool result = await UrlLauncherUtil.openWeChat(); if (!result) { ToastUtil.show(StringName.keyboardGuideWechatNotInstall); } }, child: Container( padding: EdgeInsets.only( left: 12.w, right: 14.w, top: 10.w, bottom: 10.w, ), decoration: BoxDecoration( image: DecorationImage( image: Assets.images.bgGoApp.provider(), fit: BoxFit.fill, ), ), child: Row( children: [ Assets.images.iconWechat.image(height: 22.w, width: 22.w), SizedBox(width: 1.0), Text( StringName.keyboardGuideGoWechat, style: TextStyle( color: ColorName.black80, fontSize: 12, fontWeight: FontWeight.w400, ), ), ], ), ), ), ], ), ); } /// 内容 Widget _buildContent() { return Obx(() { // 选择了默认键盘,显示聊天列表 if (controller.isDefaultKeyboard.value) { return _buildChatList(); } else { // 未选择,显示引导动画 return _buildGuideAnimation(); } }); } /// 引导动画 Widget _buildGuideAnimation() { return Container( child: Lottie.asset( Assets.anim.animKeyboardFloatingWindowChooseKeyboard, repeat: true, ), ); } /// 聊天列表 Widget _buildChatList() { return Obx(() { return ListView.builder( controller: controller.scrollController, itemCount: controller.msgList.length, itemBuilder: (BuildContext context, int index) { KeyboardGuideMsg msg = controller.msgList[index]; return _buildMsgItem(msg, index); }, ); }); } /// 构建底部输入框 Widget _buildBottomInput() { return Center( child: Column( children: [ Container( color: ColorName.msgInputBar, padding: const EdgeInsets.symmetric( vertical: 11.0, horizontal: 12.0, ), child: Row( mainAxisAlignment: MainAxisAlignment.start, children: [ Expanded( flex: 1, // 输入框的圆角边框 child: Container( decoration: BoxDecoration( color: ColorName.white, borderRadius: BorderRadius.circular(10.0), ), child: TextField( style: TextStyle( color: ColorName.black80, fontSize: 14.0, fontWeight: FontWeight.w500, ), // 设置光标颜色 cursorColor: ColorName.inputCursor, // 光标宽度 cursorWidth: 2.0, // 光标圆角 cursorRadius: Radius.circular(2), // 设置按钮显示为发送 textInputAction: TextInputAction.send, // 用户点击软键盘的发送按钮时,触发回调 onSubmitted: (value) { var msg = controller.editingController.text; controller.sendMsg(msg); }, // 输入框焦点 focusNode: controller.inputFocusNode, // 点击外部区域,关闭软键盘 // onTapUpOutside: (event) { // controller.inputFocusNode.unfocus(); // }, // 输入框控制器 controller: controller.editingController, decoration: InputDecoration( // 提示文字 hintText: StringName.keyboardGuideInputHint, hintStyle: TextStyle( fontSize: 14.0, fontWeight: FontWeight.w400, color: ColorName.black40, ), // 去掉默认的边框 border: InputBorder.none, // 设置输入框的内边距 contentPadding: EdgeInsets.symmetric( horizontal: 9.0, vertical: 13.0, ), ), ), ), ), ], ), ), ], ), ); } /// 构建聊天气泡 Widget _buildMsgBubble(KeyboardGuideMsg msg) { // 设置气泡的外边距,让气泡不易过长 double marginValue = 35.0; EdgeInsets marginEdgeInsets; if (msg.isMe) { marginEdgeInsets = EdgeInsets.only(left: marginValue); } else { marginEdgeInsets = EdgeInsets.only(right: marginValue); } // 圆角大小 double radiusSize = 14.0; // 背景圆角 BorderRadius bgBorderRadius; if (msg.isMe) { bgBorderRadius = BorderRadius.only( topLeft: Radius.circular(radiusSize), topRight: Radius.circular(0), bottomLeft: Radius.circular(radiusSize), bottomRight: Radius.circular(radiusSize), ); } else { bgBorderRadius = BorderRadius.only( topLeft: Radius.circular(0), topRight: Radius.circular(radiusSize), bottomLeft: Radius.circular(radiusSize), bottomRight: Radius.circular(0), ); } // Flexible,文本超过一行时,自动换行,并且不超过最大宽度,不超过一行时,则自动包裹内容 return Flexible( child: Container( padding: EdgeInsets.symmetric(vertical: 12.0, horizontal: 10.0), margin: marginEdgeInsets, decoration: BoxDecoration( color: msg.isMe ? ColorName.msgBubbleMe : ColorName.msgBubbleTa, borderRadius: bgBorderRadius, ), child: Row( // 宽高包裹内容 mainAxisSize: MainAxisSize.min, // 图标和文本,垂直居中 crossAxisAlignment: CrossAxisAlignment.center, children: [ Flexible( // 消息文本 child: Text( msg.content, style: TextStyle( fontSize: 14.0, color: ColorName.black80, fontWeight: FontWeight.w500, height: 1.5, ), softWrap: true, ), ), // 只有对方发送的,才有操作按钮 if (!msg.isMe) Padding( padding: EdgeInsets.only(left: 8.0), child: _buildMsgActionBtn(msg), ), ], ), ), ); } /// 消息操作按钮 Widget _buildMsgActionBtn(KeyboardGuideMsg msg) { if (msg.type == KeyboardGuideMsgType.copy.type) { return GestureDetector( onTap: () { // 复制内容到剪切板 ClipboardUtil.copyToClipboard(msg.content); ToastUtil.show(StringName.copySuccess); }, child: Assets.images.iconCopy.image(width: 18.w, height: 18.w), ); } else if (msg.type == KeyboardGuideMsgType.intimacySetting.type) { return GestureDetector( onTap: () { // 跳转到亲密度设置页 IntimacyScalePage.start(); }, child: Assets.images.iconSetting.image(width: 18.w, height: 18.w), ); } else { return SizedBox.shrink(); } } /// 构建聊天消息列表项 Widget _buildMsgItem(KeyboardGuideMsg msg, int index) { return Obx(() { Widget content; // 自己发的 if (msg.isMe) { content = Row( // 如果是自己发的,则在右边 mainAxisAlignment: MainAxisAlignment.end, // 顶部对齐 crossAxisAlignment: CrossAxisAlignment.start, children: [ // 聊天气泡 _buildMsgBubble(msg), SizedBox(width: 9.w), // 头像 _buildAvatar(msg), ], ); } else { // 对方发的 content = Row( // 如果是自己发的,则在右边 mainAxisAlignment: MainAxisAlignment.start, // 顶部对齐 crossAxisAlignment: CrossAxisAlignment.start, children: [ // 头像 _buildAvatar(msg), SizedBox(width: 9.w), // 聊天气泡 _buildMsgBubble(msg), ], ); } bool isTargetGuildMsg = controller.guideMsgIndex.value == index; return Container( margin: EdgeInsets.symmetric(horizontal: 16.w, vertical: 8.0.h), child: isTargetGuildMsg ? Container(key: controller.guideMsgGlobalKey, child: content) : content, ); }); } /// 构建头像 Widget _buildAvatar(KeyboardGuideMsg msg) { double avatarSize = 36.0; return CircleAvatar( radius: 20, child: msg.isMe ? Assets.images.iconDefaultAvatar.image( height: avatarSize, width: avatarSize, ) : Assets.images.iconTaAvatar.image( height: avatarSize, width: avatarSize, ), ); } }