flexible message

This commit is contained in:
Chen Li
2025-08-22 16:32:13 +08:00
parent 7b57322170
commit d2546d7dbb
2 changed files with 83 additions and 89 deletions

View File

@@ -23,7 +23,8 @@ class _PartScreenState extends State<PartScreen> {
void initState() { void initState() {
super.initState(); super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) { WidgetsBinding.instance.addPostFrameCallback((_) {
final messageService = Provider.of<MessageService>(context, listen: false); final messageService =
Provider.of<MessageService>(context, listen: false);
messageService.removeNonListeningMessages(); messageService.removeNonListeningMessages();
setState(() { setState(() {
_isInitialized = true; _isInitialized = true;
@@ -65,18 +66,9 @@ class _PartScreenState extends State<PartScreen> {
if (!_isInitialized) { if (!_isInitialized) {
return const SizedBox.shrink(); return const SizedBox.shrink();
} }
final double minHeight = constraints.maxHeight * 0.18; final double minHeight = constraints.maxHeight * 0.16;
final double maxHeight = constraints.maxHeight * 0.4; final double maxHeight = constraints.maxHeight * 0.4;
final double chatWidth = constraints.maxWidth * 0.94; final double chatWidth = constraints.maxWidth * 0.94;
final int messageCount =
context.watch<MessageService>().messages.length;
double chatHeight;
if (messageCount <= 1) {
chatHeight = minHeight + 70;
} else {
final height = minHeight + (messageCount * 78);
chatHeight = height < maxHeight ? height : maxHeight;
}
return Stack( return Stack(
children: [ children: [
Positioned.fill( Positioned.fill(
@@ -103,74 +95,63 @@ class _PartScreenState extends State<PartScreen> {
padding: EdgeInsets.only(bottom: constraints.maxHeight * 0.22), padding: EdgeInsets.only(bottom: constraints.maxHeight * 0.22),
child: Align( child: Align(
alignment: Alignment.bottomCenter, alignment: Alignment.bottomCenter,
child: Selector<MessageService, int>( child: Consumer<MessageService>(
selector: (_, service) => service.messages.length, builder: (context, messageService, child) {
builder: (context, messageCount, child) {
WidgetsBinding.instance.addPostFrameCallback((_) { WidgetsBinding.instance.addPostFrameCallback((_) {
_scrollToBottom(); _scrollToBottom();
}); });
return Consumer<MessageService>( return Container(
builder: (context, messageService, child) { width: chatWidth,
return AnimatedContainer( constraints: BoxConstraints(
duration: const Duration(milliseconds: 180), minHeight: minHeight,
curve: Curves.easeInOut, maxHeight: maxHeight,
width: chatWidth, ),
height: chatHeight, child: ClipRRect(
child: ClipRRect( borderRadius: BorderRadius.circular(24),
borderRadius: BorderRadius.circular(24), child: BackdropFilter(
child: BackdropFilter( filter: ImageFilter.blur(sigmaX: 12, sigmaY: 12),
filter: ImageFilter.blur(sigmaX: 12, sigmaY: 12), child: GradientBackground(
child: GradientBackground( colors: const [
colors: const [ Color(0XBF3B0A3F),
Color(0XBF3B0A3F), Color(0xBF0E0E24),
Color(0xBF0E0E24), Color(0xBF0C0B33),
Color(0xBF0C0B33), ],
], borderRadius: BorderRadius.circular(6),
borderRadius: BorderRadius.circular(6), child: Stack(
child: Stack( children: [
children: [ Padding(
Padding( padding: const EdgeInsets.only(
padding: const EdgeInsets.only( top: 50,
top: 42, left: 6,
left: 6,
right: 6,
bottom: 6),
child: Column(
children: [
Expanded(
child: Padding(
padding: EdgeInsets.only(
top: 12, bottom: 12),
child: ChatBox(
scrollController:
_scrollController,
messages: messageService.messages,
),
),
),
],
),
),
Positioned(
top: 6,
right: 6, right: 6,
child: IconButton( bottom: 30),
icon: Image.asset( child: LayoutBuilder(
'assets/images/open_in_full.png', builder: (context, boxConstraints) {
width: 24, return ChatBox(
height: 24 scrollController: _scrollController,
), messages: messageService.messages,
onPressed: _openFullScreen, );
padding: EdgeInsets.zero, }
), ),
),
],
), ),
), Positioned(
top: 6,
right: 6,
child: IconButton(
icon: Image.asset(
'assets/images/open_in_full.png',
width: 24,
height: 24
),
onPressed: _openFullScreen,
padding: EdgeInsets.zero,
),
),
],
), ),
), ),
); ),
}, ),
); );
}, },
), ),

View File

@@ -13,23 +13,36 @@ class ChatBox extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return ListView.builder( return Container(
controller: scrollController, constraints: const BoxConstraints(
itemCount: messages.length, minHeight: 60,
reverse: true, ),
padding: const EdgeInsets.symmetric(horizontal: 12), decoration: BoxDecoration(
itemBuilder: (context, index) { border: Border.all(
final message = messages[messages.length - 1 - index]; color: Colors.grey, // 边框颜色
final isTop = index == messages.length - 1; width: 1.0, // 边框宽度
final isBottom = index == 0; ),
return Padding( borderRadius: BorderRadius.circular(8.0), // 边框圆角
padding: EdgeInsets.only( ),
top: isTop ? 0 : 6, child: ListView.builder(
bottom: isBottom ? 0 : 6, controller: scrollController,
), itemCount: messages.length,
child: ChatBubble(message: message), reverse: true,
); padding: const EdgeInsets.symmetric(horizontal: 12),
}, shrinkWrap: true,
itemBuilder: (context, index) {
final message = messages[messages.length - 1 - index];
final isTop = index == messages.length - 1;
final isBottom = index == 0;
return Padding(
padding: EdgeInsets.only(
top: isTop ? 0 : 6,
bottom: isBottom ? 0 : 6,
),
child: ChatBubble(message: message),
);
},
),
); );
} }
} }