4 changed files with 523 additions and 229 deletions
@ -0,0 +1,190 @@ |
|||||
|
import 'package:flutter/material.dart'; |
||||
|
import 'package:flutter_screenutil/flutter_screenutil.dart'; |
||||
|
import 'package:get/get.dart'; |
||||
|
import '../controllers/agent_controller.dart'; |
||||
|
|
||||
|
/// 底部弹出式文本编辑器组件 |
||||
|
class FullScreenEditor extends StatefulWidget { |
||||
|
const FullScreenEditor({super.key}); |
||||
|
|
||||
|
@override |
||||
|
State<FullScreenEditor> createState() => _FullScreenEditorState(); |
||||
|
} |
||||
|
|
||||
|
class _FullScreenEditorState extends State<FullScreenEditor> { |
||||
|
late TextEditingController _textController; |
||||
|
late FocusNode _focusNode; |
||||
|
final AgentController controller = AgentController.to; |
||||
|
|
||||
|
@override |
||||
|
void initState() { |
||||
|
super.initState(); |
||||
|
// 使用与主界面相同的文本控制器,保持内容同步 |
||||
|
_textController = controller.textController; |
||||
|
_focusNode = FocusNode(); |
||||
|
|
||||
|
// 延迟聚焦,确保界面完全加载后再聚焦 |
||||
|
WidgetsBinding.instance.addPostFrameCallback((_) { |
||||
|
_focusNode.requestFocus(); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
@override |
||||
|
void dispose() { |
||||
|
_focusNode.dispose(); |
||||
|
super.dispose(); |
||||
|
} |
||||
|
|
||||
|
@override |
||||
|
Widget build(BuildContext context) { |
||||
|
final isDarkMode = Theme.of(context).brightness == Brightness.dark; |
||||
|
final primaryColor = Theme.of(context).primaryColor; |
||||
|
final keyboardHeight = MediaQuery.of(context).viewInsets.bottom; // 获取键盘高度 |
||||
|
|
||||
|
return Container( |
||||
|
height: MediaQuery.of(context).size.height * 0.95, // 占屏幕高度的90% |
||||
|
decoration: BoxDecoration( |
||||
|
color: isDarkMode ? Colors.grey[900] : Colors.white, |
||||
|
borderRadius: BorderRadius.only( |
||||
|
topLeft: Radius.circular(20.r), |
||||
|
topRight: Radius.circular(20.r), |
||||
|
), |
||||
|
), |
||||
|
child: Stack( |
||||
|
children: [ |
||||
|
// 主要内容区域 |
||||
|
Column( |
||||
|
children: [ |
||||
|
// 主要编辑区域 |
||||
|
Expanded( |
||||
|
child: Container( |
||||
|
padding: EdgeInsets.fromLTRB(16.w, 60.w, 16.w, 16.w), |
||||
|
child: TextField( |
||||
|
controller: _textController, |
||||
|
focusNode: _focusNode, |
||||
|
maxLines: null, |
||||
|
expands: true, |
||||
|
keyboardType: TextInputType.multiline, |
||||
|
textInputAction: TextInputAction.newline, |
||||
|
style: TextStyle( |
||||
|
fontSize: 16.sp, |
||||
|
color: isDarkMode ? Colors.white : Colors.black87, |
||||
|
height: 1.5, |
||||
|
), |
||||
|
decoration: InputDecoration( |
||||
|
hintText: '在这里输入你的消息...', |
||||
|
hintStyle: TextStyle( |
||||
|
color: isDarkMode ? Colors.white54 : Colors.grey[500], |
||||
|
fontSize: 16.sp, |
||||
|
), |
||||
|
border: InputBorder.none, |
||||
|
contentPadding: EdgeInsets.zero, |
||||
|
), |
||||
|
), |
||||
|
), |
||||
|
), |
||||
|
|
||||
|
// 底部操作区域 |
||||
|
Container( |
||||
|
margin: |
||||
|
EdgeInsets.only(bottom: keyboardHeight), // 关键修改:添加键盘高度的边距 |
||||
|
padding: EdgeInsets.all(16.w), |
||||
|
decoration: BoxDecoration( |
||||
|
color: isDarkMode ? Colors.grey[800] : Colors.grey[50], |
||||
|
border: Border( |
||||
|
top: BorderSide( |
||||
|
color: isDarkMode ? Colors.grey[700]! : Colors.grey[200]!, |
||||
|
width: 1, |
||||
|
), |
||||
|
), |
||||
|
), |
||||
|
child: Row( |
||||
|
children: [ |
||||
|
// 字符计数 |
||||
|
Expanded( |
||||
|
child: ValueListenableBuilder<TextEditingValue>( |
||||
|
valueListenable: _textController, |
||||
|
builder: (context, value, child) { |
||||
|
return Text( |
||||
|
'${value.text.length} 字符', |
||||
|
style: TextStyle( |
||||
|
color: isDarkMode |
||||
|
? Colors.white60 |
||||
|
: Colors.grey[600], |
||||
|
fontSize: 14.sp, |
||||
|
), |
||||
|
); |
||||
|
}, |
||||
|
), |
||||
|
), |
||||
|
|
||||
|
// 发送按钮 - 保持与主界面一致的样式 |
||||
|
Obx(() { |
||||
|
final hasText = controller.hasTextInput.value; |
||||
|
return GestureDetector( |
||||
|
onTap: hasText |
||||
|
? () async { |
||||
|
await controller.sendMessageFromFullScreen(); |
||||
|
if (context.mounted) { |
||||
|
Navigator.of(context).pop(); |
||||
|
} |
||||
|
} |
||||
|
: null, |
||||
|
child: Container( |
||||
|
width: 44.w, |
||||
|
height: 44.h, |
||||
|
decoration: BoxDecoration( |
||||
|
color: hasText |
||||
|
? primaryColor |
||||
|
: (isDarkMode |
||||
|
? Colors.grey[800] |
||||
|
: Colors.grey[300]), |
||||
|
borderRadius: BorderRadius.circular(22.r), |
||||
|
), |
||||
|
child: Icon( |
||||
|
Icons.send, |
||||
|
color: hasText |
||||
|
? Colors.white |
||||
|
: (isDarkMode |
||||
|
? Colors.grey[600] |
||||
|
: Colors.grey[500]), |
||||
|
size: 22.sp, |
||||
|
), |
||||
|
), |
||||
|
); |
||||
|
}), |
||||
|
], |
||||
|
), |
||||
|
), |
||||
|
], |
||||
|
), |
||||
|
|
||||
|
// 右上角关闭按钮 |
||||
|
Positioned( |
||||
|
top: 16.h, |
||||
|
right: 16.w, |
||||
|
child: GestureDetector( |
||||
|
onTap: () { |
||||
|
controller.closeFullScreenEdit(); |
||||
|
Navigator.of(context).pop(); |
||||
|
}, |
||||
|
child: Container( |
||||
|
width: 32.w, |
||||
|
height: 32.h, |
||||
|
decoration: BoxDecoration( |
||||
|
color: isDarkMode ? Colors.grey[800] : Colors.grey[200], |
||||
|
borderRadius: BorderRadius.circular(16.r), |
||||
|
), |
||||
|
child: Icon( |
||||
|
Icons.close, |
||||
|
color: isDarkMode ? Colors.white : Colors.black87, |
||||
|
size: 20.sp, |
||||
|
), |
||||
|
), |
||||
|
), |
||||
|
), |
||||
|
], |
||||
|
), |
||||
|
); |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue