长按弹窗.

This commit is contained in:
18631081161 2024-07-23 17:57:57 +08:00
parent 8d21b8755a
commit ef31d9a2e6
19 changed files with 1069 additions and 327 deletions

BIN
assets/images/ic_copy.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 678 B

BIN
assets/images/ic_delete.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 746 B

BIN
assets/images/ic_pearl.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

View File

@ -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<String, dynamic> json) => _$MessageBeanFromJson(json);

View File

@ -12,6 +12,7 @@ MessageBean _$MessageBeanFromJson(Map<String, dynamic> json) => MessageBean(
json['biography'] as String?,
json['iconImage'] as String?,
json['lastContactTime'] as String?,
json['lastMessage'] as String?,
);
Map<String, dynamic> _$MessageBeanToJson(MessageBean instance) =>
@ -21,4 +22,5 @@ Map<String, dynamic> _$MessageBeanToJson(MessageBean instance) =>
'biography': instance.biography,
'iconImage': instance.iconImage,
'lastContactTime': instance.lastContactTime,
'lastMessage': instance.lastMessage,
};

59
lib/common/func.dart Normal file
View File

@ -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,
),
);
}
}

View File

@ -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<TextSpan> 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);
}
}

View File

@ -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<CustomPopup> {
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: <Widget>[
LayoutId(
id: _MenuLayoutId.content,
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
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<Path> {
@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<Path> oldClipper) {
return true;
}
}

View File

@ -23,19 +23,22 @@ class _DeleteDialogState extends State<DeleteDialog> {
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<DeleteDialog> {
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(
'确定',

View File

@ -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<ChatApp> {
'/ProblemPage': (BuildContext context) => const ProblemPage(),
'/ShopPage': (BuildContext context) => const ShopPage(),
'/SettingPage': (BuildContext context) => const SettingPage(),
'/TestPage': (BuildContext context) => const TestPage(),
},
debugShowMaterialGrid: false,
//

View File

@ -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<ChatPage> {
}
///
delChat(int id, index) {
deleteChat(int id, index) {
EasyLoading.show(status: 'loading...');
delIndex = index;
List<int> ids = [id];
@ -242,10 +245,13 @@ class _ChatPageState extends State<ChatPage> {
///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<ChatPage> {
controller: _scrollController,
itemCount: chatList.length,
itemBuilder: (BuildContext context, int index) {
return _item(index);
final Key key = ValueKey<int>(index);
return _item(index, key);
}),
),
)),
@ -456,18 +463,18 @@ class _ChatPageState extends State<ChatPage> {
)),
///
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<ChatPage> {
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<ChatPage> {
}
///
_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<ChatPage> {
///
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<ChatPage> {
///
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<ChatPage> {
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<ChatPage> {
),
);
}
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)),
),
)
],
),
),
),
],
),
);
}
}

View File

@ -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<HomeChatPage> with AutomaticKeepAliveClie
bool isMore = false;
bool isHalf = true;
bool isHalf = false;
///
String text = "";
@ -140,10 +144,11 @@ class _HomeChatPageState extends State<HomeChatPage> with AutomaticKeepAliveClie
_viewmodel.getCharacterInfo(widget.characterId);
}
///
///
deleteChat(int id, index) {
EasyLoading.show(status: 'loading...');
delIndex = index;
print("delIndex==$delIndex");
List<int> ids = [id];
_viewmodel.delChatByIds(ids, widget.characterId);
}
@ -172,6 +177,11 @@ class _HomeChatPageState extends State<HomeChatPage> 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<HomeChatPage> 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<HomeChatPage> 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<HomeChatPage> 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<HomeChatPage> 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<HomeChatPage> 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<HomeChatPage> 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<HomeChatPage> 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<HomeChatPage> 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<HomeChatPage> 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<HomeChatPage> 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<HomeChatPage> 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;

View File

@ -0,0 +1,60 @@
import 'package:flutter/material.dart';
import '../../custom/custom_popup.dart';
class TestPage extends StatefulWidget {
const TestPage({super.key});
@override
State<TestPage> createState() => _TestPageState();
}
class _TestPageState extends State<TestPage> {
@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,
),
),
),
],
),
);
}
}

View File

@ -155,21 +155,21 @@ class _HomePageState extends State<HomePage> 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<HomePage> 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<HomePage> 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;
// }
},
),
),

View File

@ -130,7 +130,7 @@ class _LoginPageState extends State<LoginPage> {
left: 36,
top: 76,
child: Text(
'妙语',
'妙语星河',
style: TextStyle(color: Colors.white, fontSize: 33),
)),
Positioned(

View File

@ -52,8 +52,8 @@ class _MePageState extends State<MePage> {
context,
MaterialPageRoute(
builder: (context) => ChatPage(
characterId: id,
)),
characterId: id,
)),
);
}
@ -78,6 +78,7 @@ class _MePageState extends State<MePage> {
'',
style: TextStyle(color: Colors.white, fontSize: 18),
),
///
Positioned(
right: 15,
@ -129,21 +130,21 @@ class _MePageState extends State<MePage> {
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<MePage> {
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<MePage> {
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<MePage> {
);
}).toList();
}
}

View File

@ -160,7 +160,7 @@ class _MessagePageState extends State<MessagePage> {
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<MessagePage> {
top: 6,
child: Container(
child: Text(
'12:39',
'${data.lastContactTime}',
style: TextStyle(fontSize: 10, color: Color(0xFF8D8D8D)),
),
)),

View File

@ -80,27 +80,23 @@ class _AccountPageState extends State<AccountPage> {
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)),
),
),

View File

@ -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: