diff --git a/assets/images/ic_copy.png b/assets/images/ic_copy.png new file mode 100644 index 0000000..c8eaa89 Binary files /dev/null and b/assets/images/ic_copy.png differ diff --git a/assets/images/ic_delete.png b/assets/images/ic_delete.png new file mode 100644 index 0000000..39c3934 Binary files /dev/null and b/assets/images/ic_delete.png differ diff --git a/assets/images/ic_pearl.png b/assets/images/ic_pearl.png new file mode 100644 index 0000000..6f6b91e Binary files /dev/null and b/assets/images/ic_pearl.png differ diff --git a/lib/beans/message_bean.dart b/lib/beans/message_bean.dart index 8ee332c..f82651e 100644 --- a/lib/beans/message_bean.dart +++ b/lib/beans/message_bean.dart @@ -10,8 +10,9 @@ class MessageBean { String? biography; String? iconImage; String? lastContactTime; + String? lastMessage; - MessageBean(this.id, this.name, this.biography, this.iconImage, this.lastContactTime); + MessageBean(this.id, this.name, this.biography, this.iconImage, this.lastContactTime, this.lastMessage); factory MessageBean.fromJson(Map json) => _$MessageBeanFromJson(json); diff --git a/lib/beans/message_bean.g.dart b/lib/beans/message_bean.g.dart index 8cd17c8..f59dc05 100644 --- a/lib/beans/message_bean.g.dart +++ b/lib/beans/message_bean.g.dart @@ -12,6 +12,7 @@ MessageBean _$MessageBeanFromJson(Map json) => MessageBean( json['biography'] as String?, json['iconImage'] as String?, json['lastContactTime'] as String?, + json['lastMessage'] as String?, ); Map _$MessageBeanToJson(MessageBean instance) => @@ -21,4 +22,5 @@ Map _$MessageBeanToJson(MessageBean instance) => 'biography': instance.biography, 'iconImage': instance.iconImage, 'lastContactTime': instance.lastContactTime, + 'lastMessage': instance.lastMessage, }; diff --git a/lib/common/func.dart b/lib/common/func.dart new file mode 100644 index 0000000..c993f40 --- /dev/null +++ b/lib/common/func.dart @@ -0,0 +1,59 @@ +import 'package:flutter/material.dart'; + +class FunctionUtil { + static BuildContext? dialogContext; + + //显示中间弹窗 + static void popDialog(BuildContext context, Widget widget) { + showDialog( + context: context, + barrierDismissible: true, + builder: (BuildContext context) { + dialogContext = context; + return widget; + }); + } + + //显示底部弹窗 + static void bottomSheetDialog(BuildContext context, Widget widget) { + showModalBottomSheet( + backgroundColor: const Color(0x00FFFFFF), + context: context, + /* isDismissible: false,*/ + isScrollControlled: true, + builder: (BuildContext context) { + dialogContext = context; + return widget; + }, + ); + } + + //显示底部弹窗 + static void bottomNoSheetDialog(BuildContext context, Widget widget) { + showModalBottomSheet( + backgroundColor: Color(0x00FFFFFF), + context: context, + isDismissible: false, + isScrollControlled: true, + enableDrag: false, + builder: (BuildContext context) { + dialogContext = context; + return WillPopScope(onWillPop: () async => false, child: widget); + }); + } + + //返回上一级 + static void pop() { + Navigator.pop(dialogContext!); + } + + //push到下一级 + static Future push(BuildContext context, Widget widget) { + return Navigator.push( + context, + MaterialPageRoute( + builder: (context) => widget, + ), + ); + } +} diff --git a/lib/custom/DynamicText.dart b/lib/custom/DynamicText.dart new file mode 100644 index 0000000..343f005 --- /dev/null +++ b/lib/custom/DynamicText.dart @@ -0,0 +1,39 @@ +import 'package:flutter/cupertino.dart'; + +class DynamicText extends StatelessWidget { + final String text; + final TextStyle highlightedStyle; + final TextStyle normalStyle; + + DynamicText({required this.text, required this.highlightedStyle, required this.normalStyle}); + + @override + Widget build(BuildContext context) { + return RichText( + text: _buildTextSpan(text, highlightedStyle, normalStyle), + ); + } + + TextSpan _buildTextSpan(String text, TextStyle highlightedStyle, TextStyle normalStyle) { + List spans = []; + final RegExp regExp = RegExp(r'\*([^*]+)\*'); + int lastIndex = 0; + + for (final match in regExp.allMatches(text)) { + if (match.start > lastIndex) { + spans.add(TextSpan(text: text.substring(lastIndex, match.start), style: normalStyle)); + } + spans.add(TextSpan( + text: '(${match.group(1)})', + style: highlightedStyle, + )); + lastIndex = match.end; + } + + if (lastIndex < text.length) { + spans.add(TextSpan(text: text.substring(lastIndex), style: normalStyle)); + } + + return TextSpan(children: spans); + } +} \ No newline at end of file diff --git a/lib/custom/custom_popup.dart b/lib/custom/custom_popup.dart new file mode 100644 index 0000000..8b0d548 --- /dev/null +++ b/lib/custom/custom_popup.dart @@ -0,0 +1,409 @@ +import 'dart:io'; +import 'dart:math' as math; + +import 'package:flutter/material.dart'; + +enum PressType { + longPress, + singleClick, +} + +enum PreferredPosition { + top, + bottom, +} + +class CustomPopupMenuController extends ChangeNotifier { + bool menuIsShowing = false; + + void showMenu() { + menuIsShowing = true; + notifyListeners(); + } + + void hideMenu() { + menuIsShowing = false; + notifyListeners(); + } + + void toggleMenu() { + menuIsShowing = !menuIsShowing; + notifyListeners(); + } +} + +Rect _menuRect = Rect.zero; + +class CustomPopup extends StatefulWidget { + CustomPopup({ + required this.child, + required this.menuBuilder, + required this.pressType, + this.controller, + this.arrowColor = const Color(0xFFF14343), + this.showArrow = true, + this.barrierColor = Colors.black12, + this.arrowSize = 10.0, + this.horizontalMargin = 10.0, + this.verticalMargin = 1.0, + this.position, + this.menuOnChange, + this.enablePassEvent = true, + }); + + final Widget child; + final PressType pressType; + final bool showArrow; + final Color arrowColor; + final Color barrierColor; + final double horizontalMargin; + final double verticalMargin; + final double arrowSize; + final CustomPopupMenuController? controller; + final Widget Function() menuBuilder; + final PreferredPosition? position; + final void Function(bool)? menuOnChange; + + /// Pass tap event to the widgets below the mask. + /// It only works when [barrierColor] is transparent. + final bool enablePassEvent; + + @override + _CustomPopupState createState() => _CustomPopupState(); +} + +class _CustomPopupState extends State { + RenderBox? _childBox; + RenderBox? _parentBox; + OverlayEntry? _overlayEntry; + CustomPopupMenuController? _controller; + bool _canResponse = true; + + _showMenu() { + _overlayEntry = OverlayEntry( + builder: (context) { + Widget menu = Center( + child: Container( + constraints: BoxConstraints( + maxWidth: _parentBox!.size.width - 2 * widget.horizontalMargin, + minWidth: 0, + ), + child: CustomMultiChildLayout( + delegate: _MenuLayoutDelegate( + anchorSize: _childBox!.size, + anchorOffset: _childBox!.localToGlobal( + Offset(-widget.horizontalMargin, 0), + ), + verticalMargin: widget.verticalMargin, + position: widget.position, + ), + children: [ + LayoutId( + id: _MenuLayoutId.content, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Material( + child: widget.menuBuilder(), + color: Colors.transparent, + ), + ], + ), + ), + ], + ), + ), + ); + return Listener( + behavior: widget.enablePassEvent + ? HitTestBehavior.translucent + : HitTestBehavior.opaque, + onPointerDown: (PointerDownEvent event) { + Offset offset = event.localPosition; + // If tap position in menu + if (_menuRect.contains( + Offset(offset.dx - widget.horizontalMargin, offset.dy))) { + return; + } + _controller?.hideMenu(); + // When [enablePassEvent] works and we tap the [child] to [hideMenu], + // but the passed event would trigger [showMenu] again. + // So, we use time threshold to solve this bug. + _canResponse = false; + Future.delayed(Duration(milliseconds: 300)) + .then((_) => _canResponse = true); + }, + child: widget.barrierColor == Colors.transparent + ? menu + : Container( + color: widget.barrierColor, + child: menu, + ), + ); + }, + ); + if (_overlayEntry != null) { + Overlay.of(context)!.insert(_overlayEntry!); + } + } + + _hideMenu() { + if (_overlayEntry != null) { + _overlayEntry?.remove(); + _overlayEntry = null; + } + } + + _updateView() { + bool menuIsShowing = _controller?.menuIsShowing ?? false; + widget.menuOnChange?.call(menuIsShowing); + if (menuIsShowing) { + _showMenu(); + } else { + _hideMenu(); + } + } + + @override + void initState() { + super.initState(); + _controller = widget.controller; + if (_controller == null) _controller = CustomPopupMenuController(); + _controller?.addListener(_updateView); + WidgetsBinding.instance.addPostFrameCallback((call) { + if (mounted) { + _childBox = context.findRenderObject() as RenderBox?; + _parentBox = + Overlay.of(context)?.context.findRenderObject() as RenderBox?; + } + }); + } + + @override + void dispose() { + _hideMenu(); + _controller?.removeListener(_updateView); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + var child = Material( + child: InkWell( + hoverColor: Colors.transparent, + focusColor: Colors.transparent, + splashColor: Colors.transparent, + highlightColor: Colors.transparent, + child: widget.child, + onTap: () { + if (widget.pressType == PressType.singleClick && _canResponse) { + _controller?.showMenu(); + } + }, + onLongPress: () { + if (widget.pressType == PressType.longPress && _canResponse) { + _controller?.showMenu(); + } + }, + ), + color: Colors.transparent, + ); + if (Platform.isIOS) { + return child; + } else { + return WillPopScope( + onWillPop: () { + _hideMenu(); + return Future.value(true); + }, + child: child, + ); + } + } +} + +enum _MenuLayoutId { + arrow, + downArrow, + content, +} + +enum _MenuPosition { + bottomLeft, + bottomCenter, + bottomRight, + topLeft, + topCenter, + topRight, +} + +class _MenuLayoutDelegate extends MultiChildLayoutDelegate { + _MenuLayoutDelegate({ + required this.anchorSize, + required this.anchorOffset, + required this.verticalMargin, + this.position, + }); + + final Size anchorSize; + final Offset anchorOffset; + final double verticalMargin; + final PreferredPosition? position; + + @override + void performLayout(Size size) { + Size contentSize = Size.zero; + Size arrowSize = Size.zero; + Offset contentOffset = Offset(0, 0); + // Offset arrowOffset = Offset(0, 0); + + double anchorCenterX = anchorOffset.dx + anchorSize.width / 2; + double anchorTopY = anchorOffset.dy; + double anchorBottomY = anchorTopY + anchorSize.height; + _MenuPosition menuPosition = _MenuPosition.bottomCenter; + + if (hasChild(_MenuLayoutId.content)) { + contentSize = layoutChild( + _MenuLayoutId.content, + BoxConstraints.loose(size), + ); + } + if (hasChild(_MenuLayoutId.arrow)) { + arrowSize = layoutChild( + _MenuLayoutId.arrow, + BoxConstraints.loose(size), + ); + } + if (hasChild(_MenuLayoutId.downArrow)) { + layoutChild( + _MenuLayoutId.downArrow, + BoxConstraints.loose(size), + ); + } + + bool isTop = false; + if (position == null) { + // auto calculate position + isTop = anchorBottomY > size.height / 2; + } else { + isTop = position == PreferredPosition.top; + } + if (anchorCenterX - contentSize.width / 2 < 0) { + menuPosition = isTop ? _MenuPosition.topLeft : _MenuPosition.bottomLeft; + } else if (anchorCenterX + contentSize.width / 2 > size.width) { + menuPosition = isTop ? _MenuPosition.topRight : _MenuPosition.bottomRight; + } else { + menuPosition = + isTop ? _MenuPosition.topCenter : _MenuPosition.bottomCenter; + } + + switch (menuPosition) { + case _MenuPosition.bottomCenter: + // arrowOffset = Offset( + // anchorCenterX - arrowSize.width / 2, + // anchorBottomY + verticalMargin, + // ); + contentOffset = Offset( + anchorCenterX - contentSize.width / 2, + anchorBottomY + verticalMargin + arrowSize.height, + ); + break; + case _MenuPosition.bottomLeft: + // arrowOffset = Offset(anchorCenterX - arrowSize.width / 2, + // anchorBottomY + verticalMargin); + contentOffset = Offset( + 0, + anchorBottomY + verticalMargin + arrowSize.height, + ); + break; + case _MenuPosition.bottomRight: + // arrowOffset = Offset(anchorCenterX - arrowSize.width / 2, + // anchorBottomY + verticalMargin); + contentOffset = Offset( + size.width - contentSize.width, + anchorBottomY + verticalMargin + arrowSize.height, + ); + break; + case _MenuPosition.topCenter: + // arrowOffset = Offset( + // anchorCenterX - arrowSize.width / 2, + // anchorTopY - verticalMargin - arrowSize.height, + // ); + contentOffset = Offset( + anchorCenterX - contentSize.width / 2, + anchorTopY - verticalMargin - arrowSize.height - contentSize.height, + ); + break; + case _MenuPosition.topLeft: + // arrowOffset = Offset( + // anchorCenterX - arrowSize.width / 2, + // anchorTopY - verticalMargin - arrowSize.height, + // ); + contentOffset = Offset( + 0, + anchorTopY - verticalMargin - arrowSize.height - contentSize.height, + ); + break; + case _MenuPosition.topRight: + // arrowOffset = Offset( + // anchorCenterX - arrowSize.width / 2, + // anchorTopY - verticalMargin - arrowSize.height, + // ); + contentOffset = Offset( + size.width - contentSize.width, + anchorTopY - verticalMargin - arrowSize.height - contentSize.height, + ); + break; + } + if (hasChild(_MenuLayoutId.content)) { + positionChild(_MenuLayoutId.content, contentOffset); + } + + _menuRect = Rect.fromLTWH( + contentOffset.dx, + contentOffset.dy, + contentSize.width, + contentSize.height, + ); + bool isBottom = false; + if (_MenuPosition.values.indexOf(menuPosition) < 3) { + // bottom + isBottom = true; + } + // if (hasChild(_MenuLayoutId.arrow)) { + // positionChild( + // _MenuLayoutId.arrow, + // isBottom + // ? Offset(arrowOffset.dx, arrowOffset.dy + 0.1) + // : Offset(-100, 0), + // ); + // } + // if (hasChild(_MenuLayoutId.downArrow)) { + // positionChild( + // _MenuLayoutId.downArrow, + // !isBottom + // ? Offset(arrowOffset.dx, arrowOffset.dy - 0.1) + // : Offset(-100, 0), + // ); + // } + } + + @override + bool shouldRelayout(MultiChildLayoutDelegate oldDelegate) => false; +} + +class _ArrowClipper extends CustomClipper { + @override + Path getClip(Size size) { + Path path = Path(); + path.moveTo(0, size.height); + path.lineTo(size.width / 2, size.height / 2); + path.lineTo(size.width, size.height); + return path; + } + + @override + bool shouldReclip(CustomClipper oldClipper) { + return true; + } +} diff --git a/lib/dialog/delete_dialog.dart b/lib/dialog/delete_dialog.dart index 8335ca5..ef9f23f 100644 --- a/lib/dialog/delete_dialog.dart +++ b/lib/dialog/delete_dialog.dart @@ -23,19 +23,22 @@ class _DeleteDialogState extends State { color: Color(0x1A000000), child: Center( child: ClipRRect( - borderRadius: BorderRadius.circular(10.0), + borderRadius: BorderRadius.circular(7.0), child: Container( - width: 280, - color: Colors.white, + width: 247, + color: Color(0xFF272727), child: Column( mainAxisSize: MainAxisSize.min, children: [ Container( - margin: EdgeInsets.only(top: 34), - child: Text('确认删除该聊天记录吗'), + margin: EdgeInsets.only(top: 28), + child: Text( + '确认删除该条聊天记录吗?', + style: TextStyle(fontSize: 15, color: Color(0xFFBABABA)), + ), ), Container( - margin: EdgeInsets.only(top: 36, left: 22, right: 22, bottom: 19), + margin: EdgeInsets.only(top: 38, left: 22, right: 22, bottom: 19), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ @@ -44,30 +47,31 @@ class _DeleteDialogState extends State { Navigator.pop(context); }, child: Container( - width: 108, - height: 43, + width: 80, + height: 28, alignment: Alignment.center, decoration: BoxDecoration( - borderRadius: BorderRadius.all(Radius.circular(12)), - border: Border.all(color: Color(0xFFD9D9D9), width: 1), + borderRadius: BorderRadius.all(Radius.circular(14)), + border: Border.all(color: Color(0xFFFF9000), width: 1), ), child: Text( '取消', - style: TextStyle(color: Color(0xFFD9D9D9), fontSize: 12), + style: TextStyle(color: Color(0xFFFF9000), fontSize: 12), ), ), ), GestureDetector( onTap: () { - widget.onTap(1); + Navigator.pop(context); + widget.onTap(); }, child: Container( - width: 108, - height: 43, + width: 80, + height: 28, alignment: Alignment.center, decoration: BoxDecoration( - color: Color(0xFFD9D9D9), - borderRadius: BorderRadius.all(Radius.circular(12)), + color: Color(0xFFFF9000), + borderRadius: BorderRadius.all(Radius.circular(14)), ), child: Text( '确定', diff --git a/lib/main.dart b/lib/main.dart index d425882..d3b3dc8 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -4,6 +4,7 @@ import 'dart:io'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_easyloading/flutter_easyloading.dart'; +import 'package:talk/tools/home/test_page.dart'; import 'package:talk/tools/home_page.dart'; import 'package:talk/tools/login/login_page.dart'; import 'package:talk/tools/me/setting_page.dart'; @@ -60,6 +61,7 @@ class _ChatAppState extends State { '/ProblemPage': (BuildContext context) => const ProblemPage(), '/ShopPage': (BuildContext context) => const ShopPage(), '/SettingPage': (BuildContext context) => const SettingPage(), + '/TestPage': (BuildContext context) => const TestPage(), }, debugShowMaterialGrid: false, //显示网格 diff --git a/lib/tools/chat/chat_page.dart b/lib/tools/chat/chat_page.dart index 2b65ae5..eefd79f 100644 --- a/lib/tools/chat/chat_page.dart +++ b/lib/tools/chat/chat_page.dart @@ -3,12 +3,15 @@ import 'dart:async'; import 'package:cached_network_image/cached_network_image.dart'; import 'package:expandable_text/expandable_text.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:flutter_easyloading/flutter_easyloading.dart'; import 'package:flutter_keyboard_visibility/flutter_keyboard_visibility.dart'; import '../../beans/character_info_bean.dart'; import '../../beans/chat_info_bean.dart'; import '../../beans/send_message_bean.dart'; +import '../../custom/custom_popup.dart'; +import 'chat_info_page.dart'; import 'chat_model.dart'; class ChatPage extends StatefulWidget { @@ -150,7 +153,7 @@ class _ChatPageState extends State { } ///删除消息 - delChat(int id, index) { + deleteChat(int id, index) { EasyLoading.show(status: 'loading...'); delIndex = index; List ids = [id]; @@ -242,10 +245,13 @@ class _ChatPageState extends State { ///AI头像 GestureDetector( onTap: () { - // Navigator.push( - // context, - // MaterialPageRoute(builder: (context) => ChatInfoPage()), - // ); + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => ChatInfoPage( + data: characterInfoBean!, + )), + ); }, child: Container( margin: EdgeInsets.only(left: 2), @@ -373,7 +379,8 @@ class _ChatPageState extends State { controller: _scrollController, itemCount: chatList.length, itemBuilder: (BuildContext context, int index) { - return _item(index); + final Key key = ValueKey(index); + return _item(index, key); }), ), )), @@ -456,18 +463,18 @@ class _ChatPageState extends State { )), ///智能输入 - Container( - margin: const EdgeInsets.only(left: 14, right: 14), - child: GestureDetector( - onTap: () { - Navigator.of(context).pushNamed('/LoginPage'); - }, - child: Image( - width: 27, - image: AssetImage('assets/images/ic_smart_chat.png'), - ), - ), - ), + // Container( + // margin: const EdgeInsets.only(left: 14, right: 14), + // child: GestureDetector( + // onTap: () { + // Navigator.of(context).pushNamed('/LoginPage'); + // }, + // child: Image( + // width: 27, + // image: AssetImage('assets/images/ic_smart_chat.png'), + // ), + // ), + // ), ///功能 更多 GestureDetector( @@ -475,9 +482,12 @@ class _ChatPageState extends State { isMore = !isMore; setState(() {}); }, - child: Image( - width: 27, - image: AssetImage('assets/images/ic_more.png'), + child: Container( + margin: EdgeInsets.only(left: 14), + child: Image( + width: 27, + image: AssetImage('assets/images/ic_more.png'), + ), ), ), ], @@ -571,16 +581,18 @@ class _ChatPageState extends State { } ///聊天条目 - _item(index) { + _item(index, key) { // if (index == 0) { // return Container(); // } + CustomPopupMenuController customController = CustomPopupMenuController(); ///简介 if (chatList[index].role == 'profile') { return Center( + key: key, child: Container( - margin: EdgeInsets.only(left: 16, right: 16), + margin: EdgeInsets.only(left: 16, right: 16, bottom: 20), padding: EdgeInsets.only(left: 20, right: 20, top: 12, bottom: 12), decoration: BoxDecoration(color: Color(0x99000000), borderRadius: BorderRadius.all(Radius.circular(13))), child: ExpandableText( @@ -609,21 +621,26 @@ class _ChatPageState extends State { ///提示 if (chatList[index].role == 'tips') { return Center( - child: Container( - padding: const EdgeInsets.only(left: 9, right: 9, top: 6, bottom: 6), - decoration: const BoxDecoration( - color: Color(0xCC000000), - borderRadius: BorderRadius.all(Radius.circular(15)), - ), - child: Row( - mainAxisSize: MainAxisSize.min, - children: [ - Text(chatList[index].content!, style: TextStyle(color: Color(0xFFB6B6B6), fontSize: 10)), - Container( - margin: const EdgeInsets.only(left: 10), - child: const Text("立即增加", style: TextStyle(color: Color(0xFFFF9000), fontSize: 10)), - ), - ], + child: GestureDetector( + onTap: () { + Navigator.pushNamed(context, '/AccountPage'); + }, + child: Container( + padding: const EdgeInsets.only(left: 9, right: 9, top: 6, bottom: 6), + decoration: const BoxDecoration( + color: Color(0xCC000000), + borderRadius: BorderRadius.all(Radius.circular(15)), + ), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Text(chatList[index].content!, style: TextStyle(color: Color(0xFFB6B6B6), fontSize: 10)), + Container( + margin: const EdgeInsets.only(left: 10), + child: const Text("立即增加", style: TextStyle(color: Color(0xFFFF9000), fontSize: 10)), + ), + ], + ), ), ), ); @@ -631,10 +648,11 @@ class _ChatPageState extends State { ///聊天内容 return Padding( - padding: const EdgeInsets.symmetric(vertical: 8.0), + padding: const EdgeInsets.only(bottom: 8), child: chatList[index].role != 'user' ? Container( ///AI + key: key, alignment: Alignment.centerLeft, child: Stack( children: [ @@ -645,19 +663,22 @@ class _ChatPageState extends State { constraints: BoxConstraints( maxWidth: MediaQuery.of(context).size.width - 50, // 确保不超过屏幕宽度 ), - child: Container( - margin: const EdgeInsets.symmetric(vertical: 4, horizontal: 12), - padding: const EdgeInsets.all(11.0), - decoration: const BoxDecoration( - color: Color(0x99FF9000), - borderRadius: BorderRadius.only( - topRight: Radius.circular(16.0), bottomLeft: Radius.circular(16.0), bottomRight: Radius.circular(16.0)), - ), - child: GestureDetector( - onTap: () { - EasyLoading.showToast("status${chatList[index].id}"); - delChat(chatList[index].id!, index); - }, + child: CustomPopup( + controller: customController, + menuBuilder: () { + return popupView(chatList[index].id!, chatList[index].content!, index, customController); + }, + barrierColor: Colors.transparent, + //触发方式 + pressType: PressType.longPress, + child: Container( + margin: const EdgeInsets.symmetric(vertical: 4, horizontal: 12), + padding: const EdgeInsets.all(11.0), + decoration: const BoxDecoration( + color: Color(0x99FF9000), + borderRadius: BorderRadius.only( + topRight: Radius.circular(16.0), bottomLeft: Radius.circular(16.0), bottomRight: Radius.circular(16.0)), + ), child: Text( chatList[index].content!, style: const TextStyle( @@ -730,4 +751,61 @@ class _ChatPageState extends State { ), ); } + + popupView(int id, String content, index, customController) { + return Container( + width: 135, + height: 40, + decoration: BoxDecoration( + color: Color(0xFF222222), + borderRadius: BorderRadius.all(Radius.circular(2)), + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + Expanded( + child: GestureDetector( + onTap: () { + EasyLoading.showToast("内容已复制"); + Clipboard.setData(ClipboardData(text: content)); + customController.hideMenu(); + }, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Image(width: 11, height: 11, image: AssetImage('assets/images/ic_copy.png')), + Container( + child: Text( + '复制', + style: TextStyle(fontSize: 8, color: Color(0xFF9D9D9D)), + ), + ) + ], + ), + ), + ), + Expanded( + child: GestureDetector( + onTap: () { + customController.hideMenu(); + deleteChat(id, index); + }, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Image(width: 11, height: 11, image: AssetImage('assets/images/ic_delete.png')), + Container( + child: Text( + '删除', + style: TextStyle(fontSize: 8, color: Color(0xFF9D9D9D)), + ), + ) + ], + ), + ), + ), + ], + ), + ); + } } diff --git a/lib/tools/home/home_chat_page.dart b/lib/tools/home/home_chat_page.dart index 64443c8..a5bae2b 100644 --- a/lib/tools/home/home_chat_page.dart +++ b/lib/tools/home/home_chat_page.dart @@ -3,12 +3,16 @@ import 'dart:async'; import 'package:cached_network_image/cached_network_image.dart'; import 'package:expandable_text/expandable_text.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:flutter_easyloading/flutter_easyloading.dart'; import 'package:flutter_keyboard_visibility/flutter_keyboard_visibility.dart'; import '../../beans/character_info_bean.dart'; import '../../beans/chat_info_bean.dart'; import '../../beans/send_message_bean.dart'; +import '../../common/func.dart'; +import '../../custom/custom_popup.dart'; +import '../../dialog/delete_dialog.dart'; import '../../network/NetworkConfig.dart'; import '../chat/chat_info_page.dart'; import '../chat/chat_model.dart'; @@ -44,7 +48,7 @@ class _HomeChatPageState extends State with AutomaticKeepAliveClie bool isMore = false; - bool isHalf = true; + bool isHalf = false; ///输入框内容 String text = ""; @@ -140,10 +144,11 @@ class _HomeChatPageState extends State with AutomaticKeepAliveClie _viewmodel.getCharacterInfo(widget.characterId); } - ///删除消息 + ///删除单条或多条消息 deleteChat(int id, index) { EasyLoading.show(status: 'loading...'); delIndex = index; + print("delIndex==$delIndex"); List ids = [id]; _viewmodel.delChatByIds(ids, widget.characterId); } @@ -172,6 +177,11 @@ class _HomeChatPageState extends State with AutomaticKeepAliveClie @override Widget build(BuildContext context) { + final size = MediaQuery.of(context).size; + final h311 = size.width / 1.1575562700964; + final h30 = size.width / 12; + final h35 = size.width / 10.285714285714; + super.build(context); return Scaffold( resizeToAvoidBottomInset: false, @@ -189,7 +199,7 @@ class _HomeChatPageState extends State with AutomaticKeepAliveClie bottom: 0, child: Container( width: MediaQuery.of(context).size.width, - height: 311.67, + height: h311, decoration: BoxDecoration( gradient: LinearGradient( colors: [Color(0x00000000), Color(0x00000000), Color(0x00000000), Color(0xFF0C0909), Color(0xFF0C0909)], // 三色渐变数组 @@ -204,7 +214,7 @@ class _HomeChatPageState extends State with AutomaticKeepAliveClie ///title Container( width: double.infinity, - height: 30, + height: h30, margin: EdgeInsets.only(top: MediaQuery.of(context).padding.top + 9, left: 16, right: 16), child: Stack( alignment: Alignment.center, @@ -219,20 +229,15 @@ class _HomeChatPageState extends State with AutomaticKeepAliveClie Positioned( left: 0, child: Container( - width: 101, - height: 30, + height: h30, decoration: BoxDecoration(color: Color(0x33000000), borderRadius: BorderRadius.all(Radius.circular(14))), child: Row( crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.spaceBetween, + mainAxisSize: MainAxisSize.min, children: [ ///AI头像 GestureDetector( onTap: () { - if (NetworkConfig.userId == "") { - Navigator.of(context).pushNamed('/LoginPage'); - return; - } Navigator.push( context, MaterialPageRoute( @@ -247,7 +252,7 @@ class _HomeChatPageState extends State with AutomaticKeepAliveClie child: CachedNetworkImage( width: 23, height: 23, - imageUrl: characterInfoBean.icon!, + imageUrl: '${characterInfoBean.icon}', errorWidget: (context, url, error) => const Icon(Icons.error), ), ), @@ -256,85 +261,90 @@ class _HomeChatPageState extends State with AutomaticKeepAliveClie ///AI名 Container( - margin: EdgeInsets.only(left: 5), + margin: EdgeInsets.only(left: 5, right: 10), child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ SizedBox( - width: 35, + width: h35, child: Text( - characterInfoBean.characterName!, + "${characterInfoBean.characterName}", overflow: TextOverflow.ellipsis, style: TextStyle(fontSize: 10, color: Colors.white), ), ), - Text( - '${characterInfoBean.lookCount} 聊过', - style: TextStyle(fontSize: 7, color: Colors.white), + SizedBox( + width: h35, + child: Text( + '${characterInfoBean.lookCount} 聊过', + style: TextStyle(fontSize: 7, color: Colors.white), + ), ), ], ), ), ///心动值 - Container( - margin: EdgeInsets.only(left: 6, right: 6), - child: GestureDetector( - onTap: () { - // Navigator.push( - // context, - // MaterialPageRoute( - // builder: (context) => ChatPage( - // characterId: characterInfoBean.characterId.toString(), - // )), - // ); - }, - child: Stack( - alignment: Alignment.center, - children: [ - Image( - width: 24, - height: 21, - image: AssetImage('assets/images/ic_beckoning.png'), - ), - Text( - characterInfoBean.intimacy.toString(), - style: TextStyle(fontSize: 8, color: Colors.white), - ) - ], - ), - ), - ), + // Container( + // margin: EdgeInsets.only(left: 6, right: 6), + // child: GestureDetector( + // onTap: () { + // // Navigator.push( + // // context, + // // MaterialPageRoute( + // // builder: (context) => ChatPage( + // // id: '123', + // // )), + // // ); + // }, + // child: Stack( + // alignment: Alignment.center, + // children: [ + // Image( + // width: 24, + // height: 21, + // image: AssetImage('assets/images/ic_beckoning.png'), + // ), + // characterInfoBean != null + // ? Text( + // characterInfoBean!.intimacy.toString(), + // style: TextStyle(fontSize: 8, color: Colors.white), + // ) + // : Container(), + // ], + // ), + // ), + // ), ], ), ), ), ///关注 - Positioned( - right: 0, - child: GestureDetector( - onTap: () { - if (NetworkConfig.userId == "") { - Navigator.of(context).pushNamed('/LoginPage'); - return; - } - isHalf = !isHalf; - setState(() {}); - }, - child: Container( - width: 50, - height: 24, - alignment: Alignment.center, - decoration: BoxDecoration(color: Color(0x33000000), borderRadius: BorderRadius.all(Radius.circular(12))), - child: Text( - '+ 关注', - style: TextStyle(fontSize: 12, color: Colors.white), - ), - ), - ), - ), + // Positioned( + // right: 0, + // child: GestureDetector( + // onTap: () { + // if (NetworkConfig.userId == "") { + // Navigator.of(context).pushNamed('/LoginPage'); + // return; + // } + // isHalf = !isHalf; + // setState(() {}); + // }, + // child: Container( + // width: 50, + // height: 24, + // alignment: Alignment.center, + // decoration: BoxDecoration(color: Color(0x33000000), borderRadius: BorderRadius.all(Radius.circular(12))), + // child: Text( + // '+ 关注', + // style: TextStyle(fontSize: 12, color: Colors.white), + // ), + // ), + // ), + // ), ], ), ), @@ -453,18 +463,18 @@ class _HomeChatPageState extends State with AutomaticKeepAliveClie )), ///智能输入 - Container( - margin: const EdgeInsets.only(left: 14, right: 14), - child: GestureDetector( - onTap: () { - // Navigator.of(context).pushNamed('/OverlayView'); - }, - child: Image( - width: 27, - image: AssetImage('assets/images/ic_smart_chat.png'), - ), - ), - ), + // Container( + // margin: const EdgeInsets.only(left: 14, right: 14), + // child: GestureDetector( + // onTap: () { + // Navigator.of(context).pushNamed('/TestPage'); + // }, + // child: Image( + // width: 27, + // image: AssetImage('assets/images/ic_smart_chat.png'), + // ), + // ), + // ), ///功能 更多 GestureDetector( @@ -476,9 +486,12 @@ class _HomeChatPageState extends State with AutomaticKeepAliveClie isMore = !isMore; setState(() {}); }, - child: Image( - width: 27, - image: !isMore ? AssetImage('assets/images/ic_more.png') : AssetImage('assets/images/ic_more_no.png'), + child: Container( + margin: EdgeInsets.only(left: 14), + child: Image( + width: 27, + image: !isMore ? AssetImage('assets/images/ic_more.png') : AssetImage('assets/images/ic_more_no.png'), + ), ), ), ], @@ -579,12 +592,13 @@ class _HomeChatPageState extends State with AutomaticKeepAliveClie // if (index == 0) { // return Container(); // } + CustomPopupMenuController customController = CustomPopupMenuController(); ///简介 if (chatList[index].role == 'profile') { return Center( child: Container( - margin: EdgeInsets.only(left: 16, right: 16), + margin: EdgeInsets.only(left: 12, right: 12, bottom: 20), padding: EdgeInsets.only(left: 20, right: 20, top: 12, bottom: 12), decoration: BoxDecoration(color: Color(0x99000000), borderRadius: BorderRadius.all(Radius.circular(13))), child: ExpandableText( @@ -613,21 +627,26 @@ class _HomeChatPageState extends State with AutomaticKeepAliveClie ///提示 if (chatList[index].role == 'tips') { return Center( - child: Container( - padding: const EdgeInsets.only(left: 9, right: 9, top: 6, bottom: 6), - decoration: const BoxDecoration( - color: Color(0xCC000000), - borderRadius: BorderRadius.all(Radius.circular(15)), - ), - child: Row( - mainAxisSize: MainAxisSize.min, - children: [ - Text(chatList[index].content!, style: TextStyle(color: Color(0xFFB6B6B6), fontSize: 10)), - Container( - margin: const EdgeInsets.only(left: 10), - child: const Text("立即增加", style: TextStyle(color: Color(0xFFFF9000), fontSize: 10)), - ), - ], + child: GestureDetector( + onTap: () { + Navigator.pushNamed(context, '/AccountPage'); + }, + child: Container( + padding: const EdgeInsets.only(left: 9, right: 9, top: 6, bottom: 6), + decoration: const BoxDecoration( + color: Color(0xCC000000), + borderRadius: BorderRadius.all(Radius.circular(15)), + ), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Text(chatList[index].content!, style: TextStyle(color: Color(0xFFB6B6B6), fontSize: 10)), + Container( + margin: const EdgeInsets.only(left: 10), + child: const Text("立即增加", style: TextStyle(color: Color(0xFFFF9000), fontSize: 10)), + ), + ], + ), ), ), ); @@ -649,19 +668,22 @@ class _HomeChatPageState extends State with AutomaticKeepAliveClie constraints: BoxConstraints( maxWidth: MediaQuery.of(context).size.width - 50, // 确保不超过屏幕宽度 ), - child: Container( - margin: const EdgeInsets.symmetric(vertical: 4, horizontal: 12), - padding: const EdgeInsets.all(11.0), - decoration: const BoxDecoration( - color: Color(0x99FF9000), - borderRadius: BorderRadius.only( - topRight: Radius.circular(16.0), bottomLeft: Radius.circular(16.0), bottomRight: Radius.circular(16.0)), - ), - child: GestureDetector( - onTap: () { - EasyLoading.showToast("status${chatList[index].id}"); - // delChat(chatList[index].id!, index); - }, + child: CustomPopup( + controller: customController, + menuBuilder: () { + return popupView(chatList[index].id!, chatList[index].content!, index, customController); + }, + barrierColor: Colors.transparent, + //触发方式 + pressType: PressType.longPress, + child: Container( + margin: const EdgeInsets.symmetric(vertical: 4, horizontal: 12), + padding: const EdgeInsets.all(11.0), + decoration: const BoxDecoration( + color: Color(0x99FF9000), + borderRadius: BorderRadius.only( + topRight: Radius.circular(16.0), bottomLeft: Radius.circular(16.0), bottomRight: Radius.circular(16.0)), + ), child: Text( chatList[index].content!, style: const TextStyle( @@ -735,6 +757,69 @@ class _HomeChatPageState extends State with AutomaticKeepAliveClie ); } + popupView(int id, String content, index, customController) { + return Container( + width: 135, + height: 40, + decoration: BoxDecoration( + color: Color(0xFF222222), + borderRadius: BorderRadius.all(Radius.circular(2)), + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + Expanded( + child: GestureDetector( + onTap: () { + customController.hideMenu(); + + EasyLoading.showToast("内容已复制"); + Clipboard.setData(ClipboardData(text: content)); + }, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Image(width: 11, height: 11, image: AssetImage('assets/images/ic_copy.png')), + Container( + child: Text( + '复制', + style: TextStyle(fontSize: 8, color: Color(0xFF9D9D9D)), + ), + ) + ], + ), + ), + ), + Expanded( + child: GestureDetector( + onTap: () { + customController.hideMenu(); + + FunctionUtil.popDialog(context, DeleteDialog( + onTap: () { + deleteChat(id, index); + }, + )); + }, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Image(width: 11, height: 11, image: AssetImage('assets/images/ic_delete.png')), + Container( + child: Text( + '删除', + style: TextStyle(fontSize: 8, color: Color(0xFF9D9D9D)), + ), + ) + ], + ), + ), + ), + ], + ), + ); + } + @override // TODO: implement wantKeepAlive bool get wantKeepAlive => true; diff --git a/lib/tools/home/test_page.dart b/lib/tools/home/test_page.dart new file mode 100644 index 0000000..c38e9c7 --- /dev/null +++ b/lib/tools/home/test_page.dart @@ -0,0 +1,60 @@ +import 'package:flutter/material.dart'; + +import '../../custom/custom_popup.dart'; + +class TestPage extends StatefulWidget { + const TestPage({super.key}); + + @override + State createState() => _TestPageState(); +} + +class _TestPageState extends State { + @override + Widget build(BuildContext context) { + return Scaffold( + body: Stack( + children: [ + Positioned( + top: 400, + left: 50, + child: CustomPopup( + menuBuilder: () { + return Container( + width: 50, + height: 150, + color: Colors.lightBlue, + ); + }, + pressType: PressType.singleClick, + child: Container( + width: 50, + height: 50, + color: Colors.black, + ), + ), + ), + Positioned( + top: 400, + left: 150, + child: CustomPopup( + menuBuilder: () { + return Container( + width: 50, + height: 150, + color: Colors.lightBlue, + ); + }, + pressType: PressType.singleClick, + child: Container( + width: 50, + height: 50, + color: Colors.black, + ), + ), + ), + ], + ), + ); + } +} diff --git a/lib/tools/home_page.dart b/lib/tools/home_page.dart index 278e5e6..5a13732 100644 --- a/lib/tools/home_page.dart +++ b/lib/tools/home_page.dart @@ -155,21 +155,21 @@ class _HomePageState extends State with SingleTickerProviderStateMixin ), label: '', ), - BottomNavigationBarItem( - icon: Container( - // margin: EdgeInsets.only(top: 10), - child: Image( - width: 32, - image: AssetImage('assets/images/ic_create.png'), - ), - ), - label: '', - ), + // BottomNavigationBarItem( + // icon: Container( + // // margin: EdgeInsets.only(top: 10), + // child: Image( + // width: 32, + // image: AssetImage('assets/images/ic_create.png'), + // ), + // ), + // label: '', + // ), BottomNavigationBarItem( icon: Container( child: Text( '消息', - style: TextStyle(color: Color(currentIndex == 3 ? 0xFFFFFFFF : 0xFF7E7E7E), fontSize: 15), + style: TextStyle(color: Color(currentIndex == 2 ? 0xFFFFFFFF : 0xFF7E7E7E), fontSize: 15), ), ), label: '', @@ -178,7 +178,7 @@ class _HomePageState extends State with SingleTickerProviderStateMixin icon: Container( child: Text( '我的', - style: TextStyle(color: Color(currentIndex == 4 ? 0xFFFFFFFF : 0xFF7E7E7E), fontSize: 15), + style: TextStyle(color: Color(currentIndex == 3 ? 0xFFFFFFFF : 0xFF7E7E7E), fontSize: 15), ), ), label: '', @@ -203,20 +203,21 @@ class _HomePageState extends State with SingleTickerProviderStateMixin setState(() { currentIndex = index; }); + _tabController.animateTo(index); - switch (index) { - case 2: - break; - case 3: - _tabController.animateTo(2); - break; - case 4: - _tabController.animateTo(3); - break; - default: - _tabController.animateTo(index); - break; - } + // switch (index) { + // case 2: + // break; + // case 3: + // _tabController.animateTo(2); + // break; + // case 4: + // _tabController.animateTo(3); + // break; + // default: + // _tabController.animateTo(index); + // break; + // } }, ), ), diff --git a/lib/tools/login/login_page.dart b/lib/tools/login/login_page.dart index 81587ba..f57b479 100644 --- a/lib/tools/login/login_page.dart +++ b/lib/tools/login/login_page.dart @@ -130,7 +130,7 @@ class _LoginPageState extends State { left: 36, top: 76, child: Text( - '妙语', + '妙语星河', style: TextStyle(color: Colors.white, fontSize: 33), )), Positioned( diff --git a/lib/tools/me/me_page.dart b/lib/tools/me/me_page.dart index b86d361..2b7fe43 100644 --- a/lib/tools/me/me_page.dart +++ b/lib/tools/me/me_page.dart @@ -52,8 +52,8 @@ class _MePageState extends State { context, MaterialPageRoute( builder: (context) => ChatPage( - characterId: id, - )), + characterId: id, + )), ); } @@ -78,6 +78,7 @@ class _MePageState extends State { '', style: TextStyle(color: Colors.white, fontSize: 18), ), + ///设置按钮 Positioned( right: 15, @@ -129,21 +130,21 @@ class _MePageState extends State { margin: EdgeInsets.only(left: 16, top: 17), child: Row( children: [ - Text( - '9', - style: TextStyle(color: Colors.white, fontSize: 16), - ), + // Text( + // '9', + // style: TextStyle(color: Colors.white, fontSize: 16), + // ), + // Container( + // margin: EdgeInsets.only(left: 6), + // child: Text( + // '相册', + // style: TextStyle(color: Color(0xFF4D4D4D), fontSize: 12), + // ), + // ), Container( - margin: EdgeInsets.only(left: 6), + // margin: EdgeInsets.only(left: 18), child: Text( - '相册', - style: TextStyle(color: Color(0xFF4D4D4D), fontSize: 12), - ), - ), - Container( - margin: EdgeInsets.only(left: 22), - child: Text( - '9', + '${userInfoBean.remainingChatCount}', style: TextStyle(color: Colors.white, fontSize: 16), ), ), @@ -164,62 +165,64 @@ class _MePageState extends State { child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - GestureDetector( - onTap: () { - Navigator.pushNamed(context, '/AccountPage'); - }, - child: Container( - width: 151, - height: 38, - decoration: BoxDecoration(color: Color(0xFF2A2A2A), borderRadius: BorderRadius.all(Radius.circular(13))), - child: Row( - children: [ - Container( - margin: EdgeInsets.only(left: 15), - child: Image( - width: 23, - height: 20, - image: AssetImage('assets/images/ic_currency.png'), + Expanded( + child: GestureDetector( + onTap: () { + Navigator.pushNamed(context, '/AccountPage'); + }, + child: Container( + height: 38, + decoration: BoxDecoration(color: Color(0xFF2A2A2A), borderRadius: BorderRadius.all(Radius.circular(13))), + child: Row( + children: [ + Container( + margin: EdgeInsets.only(left: 15), + child: Image( + width: 23, + height: 20, + image: AssetImage('assets/images/ic_currency.png'), + ), ), - ), - Container( - margin: EdgeInsets.only(left: 17), - child: Text( - '货币:${userInfoBean.currency}', - style: TextStyle(color: Color(0xFFE1E1E1), fontSize: 13), + Container( + margin: EdgeInsets.only(left: 17), + child: Text( + '货币:${userInfoBean.currency}', + style: TextStyle(color: Color(0xFFE1E1E1), fontSize: 13), + ), ), - ), - ], + ], + ), ), ), ), - GestureDetector( - onTap: () { - Navigator.pushNamed(context, '/ShopPage'); - }, - child: Container( - width: 151, - height: 38, - margin: EdgeInsets.only(left: 26), - decoration: BoxDecoration(color: Color(0xFF2A2A2A), borderRadius: BorderRadius.all(Radius.circular(13))), - child: Row( - children: [ - Container( - margin: EdgeInsets.only(left: 15), - child: Image( - width: 23, - height: 20, - image: AssetImage('assets/images/ic_mall.png'), + Container(width: 15), + Expanded( + child: GestureDetector( + onTap: () { + Navigator.pushNamed(context, '/ShopPage'); + }, + child: Container( + height: 38, + decoration: BoxDecoration(color: Color(0xFF2A2A2A), borderRadius: BorderRadius.all(Radius.circular(13))), + child: Row( + children: [ + Container( + margin: EdgeInsets.only(left: 15), + child: Image( + width: 23, + height: 20, + image: AssetImage('assets/images/ic_mall.png'), + ), ), - ), - Container( - margin: EdgeInsets.only(left: 24), - child: Text( - '货币商城', - style: TextStyle(color: Color(0xFFE1E1E1), fontSize: 13), + Container( + margin: EdgeInsets.only(left: 24), + child: Text( + '货币商城', + style: TextStyle(color: Color(0xFFE1E1E1), fontSize: 13), + ), ), - ), - ], + ], + ), ), ), ), @@ -230,50 +233,55 @@ class _MePageState extends State { Container( height: 50, margin: EdgeInsets.symmetric(horizontal: 16), - child: Image( - image: AssetImage('assets/images/ic_web.png'), + child: GestureDetector( + onTap: () { + Navigator.pushNamed(context, '/LoginPage'); + }, + child: Image( + image: AssetImage('assets/images/ic_web.png'), + ), ), ), - Container( - margin: EdgeInsets.only(left: 16, top: 33), - child: Row( - children: [ - Text( - '创作中心', - style: TextStyle(color: Color(0xFFE1E1E1)), - ), - Container( - margin: EdgeInsets.only(left: 9), - child: Text( - '0', - style: TextStyle(color: Color(0xFF4D4D4D)), - ), - ), - ], - ), - ), - - Container( - margin: EdgeInsets.symmetric(horizontal: 16, vertical: 17), - child: GridView.count( - shrinkWrap: true, - //水平子Widget之间间距 - crossAxisSpacing: 12.0, - //垂直子Widget之间间距 - mainAxisSpacing: 9.0, - //GridView内边距 - padding: EdgeInsets.zero, - //一行的Widget数量 - crossAxisCount: 3, - //子Widget宽高比例 - childAspectRatio: 0.7, - //子Widget列表 - children: _item(userInfoBean.characterInfo!), - physics: NeverScrollableScrollPhysics(), - //类似 cellForRow 函数 - scrollDirection: Axis.vertical), - ), + // Container( + // margin: EdgeInsets.only(left: 16, top: 33), + // child: Row( + // children: [ + // Text( + // '创作中心', + // style: TextStyle(color: Color(0xFFE1E1E1)), + // ), + // Container( + // margin: EdgeInsets.only(left: 9), + // child: Text( + // '0', + // style: TextStyle(color: Color(0xFF4D4D4D)), + // ), + // ), + // ], + // ), + // ), + // + // Container( + // margin: EdgeInsets.symmetric(horizontal: 16, vertical: 17), + // child: GridView.count( + // shrinkWrap: true, + // //水平子Widget之间间距 + // crossAxisSpacing: 12.0, + // //垂直子Widget之间间距 + // mainAxisSpacing: 9.0, + // //GridView内边距 + // padding: EdgeInsets.zero, + // //一行的Widget数量 + // crossAxisCount: 3, + // //子Widget宽高比例 + // childAspectRatio: 0.7, + // //子Widget列表 + // children: _item(userInfoBean.characterInfo!), + // physics: NeverScrollableScrollPhysics(), + // //类似 cellForRow 函数 + // scrollDirection: Axis.vertical), + // ), ], ), ) @@ -330,5 +338,4 @@ class _MePageState extends State { ); }).toList(); } - } diff --git a/lib/tools/message/message_page.dart b/lib/tools/message/message_page.dart index 3828f33..07743d0 100644 --- a/lib/tools/message/message_page.dart +++ b/lib/tools/message/message_page.dart @@ -160,7 +160,7 @@ class _MessagePageState extends State { child: Container( width: 160, child: Text( - '你好', + '${data.lastMessage}', maxLines: 1, overflow: TextOverflow.ellipsis, style: TextStyle(fontSize: 12, color: Color(0xFF777777)), @@ -171,7 +171,7 @@ class _MessagePageState extends State { top: 6, child: Container( child: Text( - '12:39', + '${data.lastContactTime}', style: TextStyle(fontSize: 10, color: Color(0xFF8D8D8D)), ), )), diff --git a/lib/tools/shop/account_page.dart b/lib/tools/shop/account_page.dart index 3be9f4f..dbe48ac 100644 --- a/lib/tools/shop/account_page.dart +++ b/lib/tools/shop/account_page.dart @@ -80,27 +80,23 @@ class _AccountPageState extends State { child: Column( mainAxisSize: MainAxisSize.min, children: [ + Image( + width: 45, + image: AssetImage('assets/images/ic_pearl.png'), + ), Container( alignment: Alignment.center, - margin: EdgeInsets.only(top: 40), + margin: EdgeInsets.only(top: 13), child: Text( '${accountBean.currency}', style: TextStyle(fontSize: 24, color: Color(0xFFE1E1E1)), ), ), - Container( - alignment: Alignment.center, - margin: EdgeInsets.only(top: 11), - child: Text( - '货币余额', - style: TextStyle(fontSize: 10, color: Color(0xFF686868)), - ), - ), Container( alignment: Alignment.centerLeft, margin: EdgeInsets.only(top: 39), child: Text( - '货币余额', + '账户充值', style: TextStyle(fontSize: 13, color: Color(0xFFACACAC)), ), ), diff --git a/pubspec.yaml b/pubspec.yaml index 49f981e..001a31f 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -47,7 +47,6 @@ dependencies: card_swiper: ^3.0.1 flutter_slidable: ^3.1.0 flutter_keyboard_visibility: ^6.0.0 - custom_pop_up_menu: ^1.2.4 dev_dependencies: flutter_test: