From a77db6d5d91f7da9545a9e0720cad611cb2e152f Mon Sep 17 00:00:00 2001 From: Jolie <412895109@qq.com> Date: Tue, 11 Nov 2025 17:41:57 +0800 Subject: [PATCH] =?UTF-8?q?feat(chat):=20=E6=B7=BB=E5=8A=A0=E8=81=8A?= =?UTF-8?q?=E5=A4=A9=E8=BE=93=E5=85=A5=E6=A0=8F=E6=9B=B4=E5=A4=9A=E9=80=89?= =?UTF-8?q?=E9=A1=B9=E5=8A=9F=E8=83=BD-=E5=B1=95=E5=BC=80=20=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=E6=9B=B4=E5=A4=9A=E9=80=89=E9=A1=B9=E8=A7=86=E5=9B=BE?= =?UTF-8?q?=EF=BC=8C=E6=94=AF=E6=8C=81=E5=9B=BE=E7=89=87=E5=92=8C=E7=9B=B8?= =?UTF-8?q?=E6=9C=BA=E5=8A=9F=E8=83=BD=20-=20=E5=AE=9E=E7=8E=B0=E7=82=B9?= =?UTF-8?q?=E5=87=BB=E6=9B=B4=E5=A4=9A=E6=8C=89=E9=92=AE=E5=88=87=E6=8D=A2?= =?UTF-8?q?=E9=80=89=E9=A1=B9=E9=9D=A2=E6=9D=BF=E6=98=BE=E7=A4=BA=E7=8A=B6?= =?UTF-8?q?=E6=80=81-=20=E6=B7=BB=E5=8A=A0=E5=9B=BE=E7=89=87=E5=92=8C?= =?UTF-8?q?=E7=9B=B8=E6=9C=BA=E5=9B=BE=E6=A0=87=E8=B5=84=E6=BA=90=E5=BC=95?= =?UTF-8?q?=E7=94=A8=20-=E4=BC=98=E5=8C=96=E9=94=AE=E7=9B=98=E6=94=B6?= =?UTF-8?q?=E8=B5=B7=E9=80=BB=E8=BE=91=EF=BC=8C=E6=8F=90=E5=8D=87=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E4=BD=93=E9=AA=8C-=20=E4=BD=BF=E7=94=A8=E5=8A=A8?= =?UTF-8?q?=E7=94=BB=E6=95=88=E6=9E=9C=E5=A2=9E=E5=BC=BA=E6=9B=B4=E5=A4=9A?= =?UTF-8?q?=E9=80=89=E9=A1=B9=E9=9D=A2=E6=9D=BF=E5=B1=95=E5=BC=80=E6=94=B6?= =?UTF-8?q?=E8=B5=B7=E4=BD=93=E9=AA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assets/images/camera.png | Bin 0 -> 2378 bytes assets/images/photo.png | Bin 0 -> 2256 bytes lib/generated/assets.dart | 2 + lib/widget/message/chat_input_bar.dart | 207 ++++++++++++++++++------- 4 files changed, 150 insertions(+), 59 deletions(-) create mode 100644 assets/images/camera.png create mode 100644 assets/images/photo.png diff --git a/assets/images/camera.png b/assets/images/camera.png new file mode 100644 index 0000000000000000000000000000000000000000..7670c55b9e325f45f1e04ddfdf6c20fa549d1d17 GIT binary patch literal 2378 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 literal 0 HcmV?d00001 diff --git a/assets/images/photo.png b/assets/images/photo.png new file mode 100644 index 0000000000000000000000000000000000000000..1b12978c3227d88f2f239fae99ed80d7559d4004 GIT binary patch literal 2256 zcmV;>2ru`EP)r004>z1^@s6b%)Yq00001b5ch_0Itp) z=>Px#1am@3R0s$N2z&@+hyVZxdPzh0+2bCbK7bh7`q1p@2W`E#2&5XbdmVFrwThtDP9S^|f$d zfiD0!U(~hnrI6@al)cHZ#t71MC(2ReSi=HeJqpu}C`T7$PH$1BxhNvYdwLP3nJ6Mi z98Q>KEv6=-+$MVsnzlj&t?DpUMR8H&yXHCfN^N1PiE^LpH>8+hrKT*!MUlEld1?q# zR1~R;)T6X4#Y7QF>QhpdBBDrrq$%d}qCU6}$|{P~N4kMs7B*3&>DwO`_~7cGV-ZCp z=@%|pP7K!qk)&S~@Ev6TC6g_RtGEgs!_oT8Dte@KGZa}B+~kOIo9q=L$w+8-&yq-r zDAJiWE~%Yz(V~bX`hFG^vyE6( zurymju8JbjWSQFYX)4O{wz(`3B@WYKmYzGODSe)Ifnik?i6*b)6gRiYMs;w_X&qG- zJKUtJ{*~Ap<-YKj4z>Ga0T&%yF=i;oJ71K!P4=tw1MH6fa!re^p8I5N$%`2g*JLFT zQ@@L?^VGOEOMmN2(Ie61m6&J}+Xzs=pZjFVd95{yprvb($}9ou6MvuVcVf|?BYw{$ z96ySsYk3hxDzRxWq=u4G6h((8>zhtjw=N zik@u@;WL`?e3WAu#`7&Q7ytC`hXRe2b@iJcD-#{Qc#6U?n{1B|`#Ch@DL0Q*Yr((J zi7=w*mrn|tlz6~;d}yVPlF5i0AW#XbBB$WZUdqP9)1!P+^lU&Z1`OjVH;+}ZXnLMU ziXH}P^lP-jOL+=k2(M7O3^;RCh+{dL>wHvvM5%t_y}>b9M@>7ZT%Xi{6g?D32}cYm zi!s@Ao7cmIm+}<85LVHY52dCo#w2UE8jq8rhd|8G#^*(S#6*_Z#H9wqEE)im%mkzn zdqdY!Asxm7e`71b4X2%ch$s={EX8@7tj_I7Yn7sEfsYfU*ddeiG&4xj@?qA}>WL$I z0U8c^SXfa+i6?7y#aMcou_>Y?;8GT^rO%U*tj&&yl1S_{ix_T`)jcittbpGq>1@kF zyS3)8TnBVTO*fKwR8QuPPU=brL7z((#moXmL@9({&ka~#>@N^Q*SoSLL==I9kq$S3 zf^@hEG(;4Egoq-LIHBTtroyloi6{aI5k(*&q6j2J6k!t!{5|b?mYcwbL==I9h$4_6 zZxvS%Vt}}H->J;k zT=kh|9VY+{ivr3_EXvu4k%IxU#)jeZqLhy)27IBr_!epue6+becC(Nula2v+E3>9V z@sf+rVHIK0@C}S#{)I}9C|wFNClp3xiO2V&n1tUo7WnwQsN{*;E%4jL*4or@2N=Lr zW)oI4=%OByi>&0Zjo;+yxziK1<-@&8r*ED3*RxJF6P)))XB=k~lbHzXEQzxDWpPR3 zX2WrGlCjl~dYKH~8PAe~-0I0$LwU7e!VS<0_`Xlprp^VfxpR2}X5n8oo<+|}#V)zh+CwPMnG4*ol52qf4=(iq4eNSb z-+Q=Q>5pwoXZ4gMNqP`uMpBVfSr+5MJnN80=GfPd`@beik|aI19#W!91zDnTS z^Y812D1H;gSV;!zkBEK%3jJ-(db6p*%s0s@svNjhJYu|QT&v|q-&2T6cu3vcmnT1vQ27G+RLp2RNLmm`boULc>V7UzpHu81+S zAI)E<6+NR%5|XlXc|gXsqP(G$EUmxOl;}dLqqN$2 zst356xxGZ_SXoFtvmGb%6o+fem7XL405^=GBR)^#$WaBzZuWL1Nyt(!>=NX$o+C#U zAU(45EJ@7R6y>|&tJ`a_MgUX*0000 { final TextEditingController _textController = TextEditingController(); + bool _isMoreOptionsVisible = false; void _handleSendMessage() { if (_textController.text.isNotEmpty) { @@ -28,73 +29,161 @@ class _ChatInputBarState extends State { } } + // 切换更多选项的显示状态 + void _toggleMoreOptions() { + setState(() { + _isMoreOptionsVisible = !_isMoreOptionsVisible; + // 收起键盘 + FocusManager.instance.primaryFocus?.unfocus(); + }); + } + @override Widget build(BuildContext context) { - return Container( - padding: EdgeInsets.only(left: 16.w, right: 16.w, bottom: 16.w), - color: Colors.white, - child: Column( - children: [ - SizedBox(height: 10.h), - Row( + return Column( + mainAxisSize: MainAxisSize.min, + children: [ + Container( + padding: EdgeInsets.only(left: 16.w, right: 16.w, bottom: 16.w), + color: Colors.white, + child: Column( children: [ - Expanded( - child: Container( - height: 40.h, - decoration: BoxDecoration( - color: Color(0xffF5F5F5), - borderRadius: BorderRadius.circular(5.h), - ), - padding: EdgeInsets.symmetric(horizontal: 16.w), - child: TextField( - controller: _textController, - decoration: InputDecoration( - border: InputBorder.none, - hintText: "请输入聊天内容~", - hintStyle: TextStyle(fontSize: 14.sp, color: Colors.grey), + SizedBox(height: 10.h), + Row( + children: [ + Expanded( + child: Container( + height: 40.h, + decoration: BoxDecoration( + color: Color(0xffF5F5F5), + borderRadius: BorderRadius.circular(5.h), + ), + padding: EdgeInsets.symmetric(horizontal: 16.w), + child: TextField( + controller: _textController, + decoration: InputDecoration( + border: InputBorder.none, + hintText: "请输入聊天内容~", + hintStyle: TextStyle(fontSize: 14.sp, color: Colors.grey), + ), + style: TextStyle(fontSize: 14.sp, color: Colors.black), + ), ), - style: TextStyle(fontSize: 14.sp, color: Colors.black), ), - ), + SizedBox(width: 12.w), + // 发送按钮 + Container( + padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 8.h), + decoration: BoxDecoration( + color: Colors.blue, + borderRadius: BorderRadius.circular(5.h), + ), + child: Text( + "发送", + style: TextStyle( + fontSize: 14.sp, + color: Colors.white, + fontWeight: FontWeight.w500, + ), + ), + ).onTap(_handleSendMessage), + ], + ), + SizedBox(height: 12.h), + // 底部工具栏 + Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + // 语音按钮 + Image.asset(Assets.imagesAudio, width: 24.w, height: 24.w), + // 视频按钮 + Image.asset(Assets.imagesVideo, width: 24.w, height: 24.w), + // 礼物按钮 + Image.asset(Assets.imagesGift, width: 24.w, height: 24.w), + // 表情按钮 + Image.asset(Assets.imagesEmoji, width: 24.w, height: 24.w), + // 更多按钮 + Image.asset(Assets.imagesAdd, width: 24.w, height: 24.w).onTap(_toggleMoreOptions), + ], ), - SizedBox(width: 12.w), - // 发送按钮 - Container( - padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 8.h), - decoration: BoxDecoration( - color: Colors.blue, - borderRadius: BorderRadius.circular(5.h), - ), - child: Text( - "发送", - style: TextStyle( - fontSize: 14.sp, - color: Colors.white, - fontWeight: FontWeight.w500, - ), - ), - ).onTap(_handleSendMessage), - ], - ), - SizedBox(height: 12.h), - // 底部工具栏 - Row( - mainAxisAlignment: MainAxisAlignment.spaceAround, - children: [ - // 语音按钮 - Image.asset(Assets.imagesAudio, width: 24.w, height: 24.w), - // 视频按钮 - Image.asset(Assets.imagesVideo, width: 24.w, height: 24.w), - // 礼物按钮 - Image.asset(Assets.imagesGift, width: 24.w, height: 24.w), - // 表情按钮 - Image.asset(Assets.imagesEmoji, width: 24.w, height: 24.w), - // 更多按钮 - Image.asset(Assets.imagesAdd, width: 24.w, height: 24.w), ], ), - ], - ), + ), + // 更多选项展开视图 + _buildMoreOptionsView(), + ], + ); + } + + // 构建更多选项展开视图 + Widget _buildMoreOptionsView() { + return AnimatedContainer( + duration: Duration(milliseconds: 300), + height: _isMoreOptionsVisible ? 180.h : 0, + color: Colors.white, + child: _isMoreOptionsVisible + ? Container( + padding: EdgeInsets.symmetric(horizontal: 20.w, vertical: 20.h), + child: Column( + children: [ + SizedBox(height: 10.h), + // 第一行选项 + Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + // 图片选项 + Column( + children: [ + Container( + width: 60.w, + height: 60.w, + decoration: BoxDecoration( + color: Color(0xffF0F5FF), + borderRadius: BorderRadius.circular(8.w), + ), + padding: EdgeInsets.all(10.w), + child: Image.asset(Assets.imagesPhoto, width: 40.w, height: 40.w), + ), + SizedBox(height: 8.h), + Text( + "图片", + style: TextStyle( + fontSize: 12.sp, + color: Colors.black, + ), + ), + ], + ), + SizedBox(width: 40.w), + // 相机选项 + Column( + children: [ + Container( + width: 60.w, + height: 60.w, + decoration: BoxDecoration( + color: Color(0xffF0F5FF), + borderRadius: BorderRadius.circular(8.w), + ), + padding: EdgeInsets.all(10.w), + child: Image.asset(Assets.imagesCamera, width: 40.w, height: 40.w), + ), + SizedBox(height: 8.h), + Text( + "相机", + style: TextStyle( + fontSize: 12.sp, + color: Colors.black, + ), + ), + ], + ), + ], + ), + ], + ), + ) + : null, ); } }