flutter 微信聊天输入框

news/2024/4/20 3:38:38/文章来源:https://blog.csdn.net/nicepainkiller/article/details/129256101

高仿微信聊天输入框,效果图如下(目前都是静态展示,服务还没开始开发):

大家如果观察仔细的话 应该会发现,他输入框下面的高度 刚好就是 软键盘的高度;所以在这里就需要监听软键盘的高度。还要配置

resizeToAvoidBottomInset: false,
   return Scaffold(resizeToAvoidBottomInset: false,appBar: AppBar(

因为CSDN 严格限制 gif动图大小(600kb左右) 无奈只能压缩 所以很糊)(第二张动图 是github上的不知道能放多久)

 

 

 

 这里以 单聊为例:

        遇到有个问题就是输入框行数的限制:这里这只 maxLines:null,就能自适应高度了。

就能做到 TextField多行输入了

child: TextField(// maxLength: maxLength,focusNode: focusNode,maxLines: null,maxLength: 200,cursorColor: AppColor.color3BAB71,controller: controller,textAlignVertical: TextAlignVertical.center,keyboardType: keyboardType,onEditingComplete: onEditingComplete,onSubmitted: onSubmitted,style: style ?? AppTextStyle.textStyle_28_333333,// inputFormatters: inputFormatters,decoration: InputDecoration(focusedBorder: const OutlineInputBorder(borderSide: BorderSide(width: 0, color: Colors.transparent)),disabledBorder: const OutlineInputBorder(borderSide: BorderSide(width: 0, color: Colors.transparent)),enabledBorder: const OutlineInputBorder(borderSide: BorderSide(width: 0, color: Colors.transparent)),border: OutlineInputBorder(borderSide: BorderSide.none,borderRadius: BorderRadius.circular(7.cale),//borderSide: BorderSide(width: 0, color: Colors.transparent),// borderSide: BorderSide(width: 0, color: Colors.transparent),),hintText: hintText,prefixIcon: prefixIcon,prefixIconConstraints: prefixIconConstraints,hintStyle: hintStyle ?? AppTextStyle.textStyle_28_AAAAAA,counterText: '', //取消文字计数器// border: InputBorder.none,isDense: true,errorText: errorText,contentPadding: EdgeInsets.symmetric(horizontal: 16.cale,vertical: 20.cale,),),// contentPadding://     EdgeInsets.only(left: 16.cale, right: 16.cale, top: 20.cale),// errorText: "输入错误",
),

代码结构如下:

--- chatCommon

        ------ chat_bottom.dart                 聊天底部输入框

        ------ chat_element_other.dart      聊天时别人信息的显示

        ------ chat_element_self.dart        聊天时自己信息的显示

        ------ chat_input_box.dart             聊天文本输入框封装

        ------ page_chat_group.dart         群聊

        ------ page_chat_person.dart       单聊

        ------ provider_chat_content.dart  聊天键盘显示 事件的传递 /键盘高度的处理

chat_bottom.dart

import 'package:flutter/material.dart';
import 'package:imflutter/const/app_textStyle.dart';
import 'package:imflutter/pages/chatCommon/provider_chat_content.dart';
import 'package:imflutter/wrap/extension/extension.dart';
import '../../const/app_colors.dart';
import '../../const/app_icon.dart';
import '../../wrap/widget/app_widget.dart';
import 'chat_input_box.dart';class ChatBottom extends StatefulWidget {final ProviderChatContent providerChatContent;const ChatBottom({Key? key, required this.providerChatContent}): super(key: key);State<ChatBottom> createState() => _ChatBottomState();
}class _ChatBottomState extends State<ChatBottom> with WidgetsBindingObserver {// 0 语音 1 键盘 2 表情int _inputType = 0;final TextEditingController _controller = TextEditingController();final FocusNode _focusNode = FocusNode();bool get _keyboardShow => widget.providerChatContent.contentShow;final List<Map> _listOption = [{'title': '相册', 'icon': 'assets/common/chat/ic_details_photo.webp'},{'title': '拍照', 'icon': 'assets/common/chat/ic_details_camera.webp'},{'title': '视频通话', 'icon': 'assets/common/chat/ic_details_video.webp'},{'title': '位置', 'icon': 'assets/common/chat/ic_details_localtion.webp'},{'title': '红包', 'icon': 'assets/common/chat/ic_details_red.webp'},{'title': '转账', 'icon': 'assets/common/chat/ic_details_transfer.webp'},{'title': '语音输入', 'icon': 'assets/common/chat/ic_chat_voice.webp'},{'title': '我的收藏', 'icon': 'assets/common/chat/ic_details_favorite.webp'},];@overridevoid initState() {// TODO: implement initStatesuper.initState();WidgetsBinding.instance.addObserver(this);_controller.addListener(() {setState(() {});});_focusNode.addListener(() {if (_focusNode.hasFocus) {widget.providerChatContent.updateContentShow(true);}});}@overrideWidget build(BuildContext context) {print('ChatBottom------------------------build');return Container(padding: EdgeInsets.symmetric(vertical: 20.cale),decoration: BoxDecoration(color: AppColor.colorF7F7F7,border: Border(top: BorderSide(width: 1.cale, color: AppColor.colordddddd),),),// height: 110.cale,child: Column(children: [Row(crossAxisAlignment: CrossAxisAlignment.end,children: [AnimatedSwitcher(duration: const Duration(milliseconds: 20),transitionBuilder: (Widget child, Animation<double> animation) {return FadeTransition(opacity: animation,child: child,);},child: _inputType == 0? AppWidget.inkWellEffectNone(key: const ValueKey("AppIcon.audio"),onTap: () {print('启动音频');_inputType = 1;widget.providerChatContent.updateContentShow(false);},child: Padding(padding:EdgeInsets.only(left: 20.cale, bottom: 15.cale),child: Icon(AppIcon.audio,size: 50.cale,color: Colors.black,),),): AppWidget.inkWellEffectNone(key: const ValueKey("AppIcon.keyboard"),onTap: () {_inputType = 0;widget.providerChatContent.updateContentShow(true);_focusNode.requestFocus();},child: Padding(padding:EdgeInsets.only(left: 20.cale, bottom: 15.cale),child: Icon(AppIcon.keyboard,size: 50.cale,color: Colors.black,),),),),Expanded(child: _inputType == 0? Padding(padding: EdgeInsets.symmetric(horizontal: 20.cale,),child: ChatInputBox(style: AppTextStyle.textStyle_30_000000,onEditingComplete: () {print("onEditingComplete");},onSubmitted: (str) {print("onSubmitted:$str");},controller: _controller,focusNode: _focusNode,),): AppWidget.inkWellEffectNone(onTap: () {},child: Container(margin: EdgeInsets.symmetric(horizontal: 20.cale),decoration: BoxDecoration(color: Colors.white,borderRadius: BorderRadius.circular(7.cale),),height: 80.cale,child: Center(child: Text('按住 说话',style: AppTextStyle.textStyle_30_000000,),),),),),AppWidget.inkWellEffectNone(onTap: () {print('添加表情符号');},child: Padding(padding: EdgeInsets.only(bottom: 15.cale),child: Icon(AppIcon.faceHappy,size: 50.cale,color: Colors.black,),),),AnimatedSwitcher(duration: const Duration(milliseconds: 50),transitionBuilder: (Widget child, Animation<double> animation) {return ScaleTransition(scale: animation,alignment: Alignment.centerRight,child: FadeTransition(opacity: animation,child: child,),);},child: _inputType == 0 && _controller.value.text.isNotEmpty? AppWidget.inkWellEffectNone(key: const ValueKey('发送'),onTap: () {print('发送');_controller.clear();},child: Container(margin: EdgeInsets.only(left: 20.cale, right: 24.cale, bottom: 10.cale),padding: EdgeInsets.symmetric(horizontal: 24.cale,vertical: 10.cale,),decoration: BoxDecoration(color: AppColor.color05C160,borderRadius: BorderRadius.circular(12.cale),),child: Center(child: Text('发送',style: AppTextStyle.textStyle_30_FFFFFF,)),),): AppWidget.inkWellEffectNone(key: const ValueKey('AppIcon.add'),onTap: () {print('添加附件 图片视频');setState(() {if (_focusNode.hasFocus) {_focusNode.unfocus();}widget.providerChatContent.updateContentShow(true);// print(//     '---------${DataInheritedWidget.of(context)?.dataEnvironment.keyboardHeight}');//InheritedKeyboard.of(context)?.updateKeyboard(true);});},child: Padding(padding: EdgeInsets.only(left: 10.cale, right: 20.cale, bottom: 10.cale),child: Icon(AppIcon.add,size: 58.cale,color: Colors.black,),),),),],),if (_keyboardShow)Container(width: double.infinity,margin: EdgeInsets.only(top: 20.cale,),// padding: EdgeInsets.only(bottom: 200.cale),decoration: BoxDecoration(border: Border(top: BorderSide(width: 1.cale, color: AppColor.colordddddd),),),height: widget.providerChatContent.keyboardHeight,child: Wrap(runAlignment: WrapAlignment.center,alignment: WrapAlignment.center,//crossAxisAlignment: WrapCrossAlignment.center,spacing: 75.cale,runSpacing: 60.cale,children: _listOption.asMap().map((key, value) => MapEntry(key,SizedBox(width: 100.cale,height: 150.cale,child: Column(children: [Container(width: 100.cale,height: 100.cale,decoration: BoxDecoration(color: Colors.white,borderRadius: BorderRadius.circular(25.cale),),child: Image.asset(value['icon'],width: 50.cale,height: 50.cale,),),Padding(padding: EdgeInsets.only(top: 16.cale),child: Text(value['title'],style: AppTextStyle.textStyle_20_656565,),)],),),),).values.toList(),),)],),);}///应用尺寸改变时回调,例如旋转 键盘@overridevoid didChangeMetrics() {// TODO: implement didChangeMetricssuper.didChangeMetrics();if (mounted) {// 键盘高度final double viewInsetsBottom = EdgeInsets.fromWindowPadding(WidgetsBinding.instance.window.viewInsets,WidgetsBinding.instance.window.devicePixelRatio).bottom;if (viewInsetsBottom > 0) {widget.providerChatContent.updateKeyboardHeight(viewInsetsBottom);}}}@overridevoid dispose() {// TODO: implement dispose_focusNode.dispose();_controller.dispose();WidgetsBinding.instance.removeObserver(this);super.dispose();}
}

chat_element_other.dart 

import 'package:flutter/material.dart';
import 'package:imflutter/const/app_colors.dart';
import 'package:imflutter/wrap/extension/extension.dart';
import 'package:imflutter/wrap/widget/app_widget.dart';class ChatElementOther extends StatefulWidget {/// 用户信息final Map userInfo;/// 消息final Map chatMessage;const ChatElementOther({Key? key, required this.userInfo, required this.chatMessage}): super(key: key);@overrideState<ChatElementOther> createState() => _ChatElementOtherState();
}class _ChatElementOtherState extends State<ChatElementOther> {@overrideWidget build(BuildContext context) {return Container(padding: EdgeInsets.only(top: 24.cale),child: Column(children: [Padding(padding: EdgeInsets.only(bottom: 40.cale),child: Text('11:25'),),Row(mainAxisAlignment: MainAxisAlignment.start,crossAxisAlignment: CrossAxisAlignment.start,children: [Padding(padding: EdgeInsets.only(left: 24.cale),child: AppWidget.inkWellEffectNone(onTap: () {},child: ClipRRect(borderRadius: BorderRadius.circular(7.cale),child: AppWidget.cachedImage(widget.userInfo['icon'],width: 75.cale, height: 75.cale),),),),_chatContent(),],)],),);}Widget _chatContent() {/// 1 文本/// 2 图片/// 3 语音/// 4 视频/// 5 提示消息/// 6 提示消息switch (widget.chatMessage['type']) {case 1:return _chatType1();break;case 2:return _chatType2();break;case 3:return _chatType3();break;case 4:return _chatType4();break;case 5:return _chatType5();break;case 6:return _chatType6();break;default:return Container();break;}}Widget _chatType1() {return Stack(children: [Container(margin: EdgeInsets.only(left: 25.cale),constraints: BoxConstraints(maxWidth: 500.cale),decoration: BoxDecoration(color: Colors.white,borderRadius: BorderRadius.circular(12.cale),),padding: EdgeInsets.symmetric(vertical: 18.cale,horizontal: 20.cale,),child: Text(widget.chatMessage['content_1'],softWrap: true,),),Positioned(top: 25.cale,left: 10.cale,child: CustomPaint(size: Size(20.cale, 30.cale),painter: TrianglePainter(),),),],);}Widget _chatType2() {return Container(constraints: BoxConstraints(maxWidth: 320.cale,maxHeight: 300.cale,minHeight: 120.cale,),decoration: BoxDecoration(borderRadius: BorderRadius.circular(7.cale),border: Border.all(width: 1.cale / 2, color: AppColor.color636363),),margin: EdgeInsets.only(left: 20.cale),child: ClipRRect(borderRadius: BorderRadius.circular(7.cale),child: AppWidget.cachedImage(widget.chatMessage['content_2']['picture_mini']['url'],),),);}Widget _chatType3() {return Container(color: Colors.white,padding: EdgeInsets.all(18.cale),child: Text("这是语音"),);}Widget _chatType4() {return Container(color: Colors.white,padding: EdgeInsets.all(18.cale),child: Text("这是视频"),);}Widget _chatType5() {return Container(color: Colors.white,padding: EdgeInsets.all(18.cale),child: Text("这是提示5"),);}Widget _chatType6() {return Container(color: Colors.white,padding: EdgeInsets.all(18.cale),child: Text("这是提示6"),);}
}class TrianglePainter extends CustomPainter {@overridevoid paint(Canvas canvas, Size size) {Paint paint = Paint()..color = Colors.white;Path path = Path();path.moveTo(0, size.height / 2);path.lineTo(size.width, 0);path.lineTo(size.width, size.height);path.close();canvas.drawPath(path, paint);return;}@overridebool shouldRepaint(covariant CustomPainter oldDelegate) {// TODO: implement shouldRepaintreturn false;}
}

chat_element_self.dart  

import 'package:flutter/material.dart';
import 'package:imflutter/const/app_colors.dart';
import 'package:imflutter/wrap/extension/extension.dart';
import 'package:imflutter/wrap/widget/app_widget.dart';class ChatElementSelf extends StatefulWidget {/// 用户信息final Map userInfo;/// 消息final Map chatMessage;const ChatElementSelf({Key? key, required this.userInfo, required this.chatMessage}): super(key: key);@overrideState<ChatElementSelf> createState() => _ChatElementSelfState();
}class _ChatElementSelfState extends State<ChatElementSelf> {@overrideWidget build(BuildContext context) {return Container(padding: EdgeInsets.only(top: 24.cale),child: Column(children: [Padding(padding: EdgeInsets.only(bottom: 40.cale),child: Text('11:25'),),Row(mainAxisAlignment: MainAxisAlignment.end,crossAxisAlignment: CrossAxisAlignment.start,children: [_chatContent(),Padding(padding: EdgeInsets.only(right: 24.cale),child: AppWidget.inkWellEffectNone(onTap: () {},child: ClipRRect(borderRadius: BorderRadius.circular(7.cale),child: AppWidget.cachedImage(widget.userInfo['icon'],width: 75.cale, height: 75.cale),),),),],)],),);}Widget _chatContent() {/// 1 文本/// 2 图片/// 3 语音/// 4 视频/// 5 提示消息/// 6 提示消息switch (widget.chatMessage['type']) {case 1:return _chatType1();break;case 2:return _chatType2();break;case 3:return _chatType3();break;case 4:return _chatType4();break;case 5:return _chatType5();break;case 6:return _chatType6();break;default:return Container();break;}}Widget _chatType1() {return Stack(children: [Container(margin: EdgeInsets.only(right: 25.cale),constraints: BoxConstraints(maxWidth: 500.cale),decoration: BoxDecoration(color: AppColor.color94ED6D,borderRadius: BorderRadius.circular(12.cale),),padding: EdgeInsets.symmetric(vertical: 18.cale,horizontal: 20.cale,),child: Text(widget.chatMessage['content_1'],softWrap: true,),),Positioned(top: 25.cale,right: 10.cale,child: CustomPaint(size: Size(20.cale, 30.cale),painter: TrianglePainter(),),),],);}Widget _chatType2() {return Container(constraints: BoxConstraints(maxWidth: 320.cale,maxHeight: 300.cale,minHeight: 120.cale,),decoration: BoxDecoration(borderRadius: BorderRadius.circular(7.cale),border: Border.all(width: 1.cale / 2, color: AppColor.color636363),),margin: EdgeInsets.only(right: 20.cale),child: ClipRRect(borderRadius: BorderRadius.circular(7.cale),child: AppWidget.cachedImage(widget.chatMessage['content_2']['picture_mini']['url'],),),);}Widget _chatType3() {return Container(color: Colors.white,padding: EdgeInsets.all(18.cale),child: Text("这是语音"),);}Widget _chatType4() {return Container(color: Colors.white,padding: EdgeInsets.all(18.cale),child: Text("这是视频"),);}Widget _chatType5() {return Container(color: Colors.white,padding: EdgeInsets.all(18.cale),child: Text("这是提示5"),);}Widget _chatType6() {return Container(color: Colors.white,padding: EdgeInsets.all(18.cale),child: Text("这是提示6"),);}
}class TrianglePainter extends CustomPainter {@overridevoid paint(Canvas canvas, Size size) {Paint paint = Paint()..color = AppColor.color94ED6D;Path path = Path();// path.moveTo(0, 0);// path.lineTo(0, size.height);// path.lineTo(size.width, size.height);// path.lineTo(size.width, 0);path.moveTo(0, 0);path.lineTo(0, size.height);path.lineTo(size.width, size.height / 2);path.close();canvas.drawPath(path, paint);return;}@overridebool shouldRepaint(covariant CustomPainter oldDelegate) {// TODO: implement shouldRepaintreturn false;}
}

chat_input_box.dart 

import 'package:flutter/material.dart';
import 'package:imflutter/const/app_colors.dart';
import 'package:imflutter/wrap/extension/extension.dart';import '../../const/app_textStyle.dart';class ChatInputBox extends StatelessWidget {final String? hintText;final int? maxLength;final VoidCallback? onEditingComplete;final ValueChanged<String>? onSubmitted;final EdgeInsetsGeometry? contentPadding;final TextEditingController? controller;final String? errorText;final Widget? prefixIcon;final TextInputType? keyboardType;final BoxConstraints? prefixIconConstraints;final BoxDecoration? decoration;final TextStyle? style;final TextStyle? hintStyle;final FocusNode? focusNode;const ChatInputBox({Key? key,this.maxLength = 20,this.controller,this.errorText,this.prefixIcon,this.prefixIconConstraints,this.onEditingComplete,this.onSubmitted,this.contentPadding = EdgeInsets.zero,this.decoration,this.keyboardType,this.style,this.hintStyle,this.focusNode,this.hintText,}) : super(key: key);@overrideWidget build(BuildContext context) {return Container(// height: 75.cale,// margin: EdgeInsets.all(5.cale),constraints: BoxConstraints(minHeight: 75.cale,maxHeight: 350.cale,),decoration: BoxDecoration(borderRadius: BorderRadius.circular(7.cale),color: Colors.white,),child: TextField(// maxLength: maxLength,focusNode: focusNode,maxLines: null,maxLength: 200,cursorColor: AppColor.color3BAB71,controller: controller,textAlignVertical: TextAlignVertical.center,keyboardType: keyboardType,onEditingComplete: onEditingComplete,onSubmitted: onSubmitted,style: style ?? AppTextStyle.textStyle_28_333333,// inputFormatters: inputFormatters,decoration: InputDecoration(focusedBorder: const OutlineInputBorder(borderSide: BorderSide(width: 0, color: Colors.transparent)),disabledBorder: const OutlineInputBorder(borderSide: BorderSide(width: 0, color: Colors.transparent)),enabledBorder: const OutlineInputBorder(borderSide: BorderSide(width: 0, color: Colors.transparent)),border: OutlineInputBorder(borderSide: BorderSide.none,borderRadius: BorderRadius.circular(7.cale),//borderSide: BorderSide(width: 0, color: Colors.transparent),// borderSide: BorderSide(width: 0, color: Colors.transparent),),hintText: hintText,prefixIcon: prefixIcon,prefixIconConstraints: prefixIconConstraints,hintStyle: hintStyle ?? AppTextStyle.textStyle_28_AAAAAA,counterText: '', //取消文字计数器// border: InputBorder.none,isDense: true,errorText: errorText,contentPadding: EdgeInsets.symmetric(horizontal: 16.cale,vertical: 20.cale,),),// contentPadding://     EdgeInsets.only(left: 16.cale, right: 16.cale, top: 20.cale),// errorText: "输入错误",),);}
}

page_chat_person.dart

import 'package:flutter/material.dart';
import 'package:imflutter/wrap/extension/extension.dart';
import 'package:imflutter/wrap/navigator/app_navigator.dart';
import 'package:imflutter/pages/chatCommon/chat_element_other.dart';
import 'package:provider/provider.dart';import '../../const/app_colors.dart';
import '../../const/app_icon.dart';
import '../../const/app_textStyle.dart';
import '../../wrap/widget/app_widget.dart';
import 'provider_chat_content.dart';
import 'chat_bottom.dart';
import 'chat_element_self.dart';class PageChatPerson extends StatefulWidget {final Map userInfoOther;const PageChatPerson({Key? key, required this.userInfoOther}): super(key: key);@overrideState<PageChatPerson> createState() => _PageChatPersonState();
}class _PageChatPersonState extends State<PageChatPerson> {/// 1 文本/// 2 图片/// 3 语音/// 4 视频/// 5 提示消息/// 6 提示消息final List<Map> _arrayChatMessage = [];@overridevoid initState() {// TODO: implement initStatesuper.initState();// for (int i = 13; i >= 0; i--) {//   //_arrayChatMessage.addAll(_cache);//   print("------------------i % 6 + 1:${i % 6 + 1}");//   _arrayChatMessage.add({//     'id': i,//     'type': i % 6 + 1,//     'content_1': '你吃饭了吗2${i}-${i % 6}',//     'content_2': {//       'picture_mini': {//         'url'://             'https://user-info-1302720239.cos.ap-nanjing.myqcloud.com/userIcon/user_icon_000100.jpg',//         'width': 450,//         'height': 200//       },//       'picture'://           'https://user-info-1302720239.cos.ap-nanjing.myqcloud.com/userIcon/user_icon_000100.jpg',//     },//     'content_3'://         'https://user-info-1302720239.cos.ap-nanjing.myqcloud.com/userIcon/user_icon_000100.jpg',//     'content_4': '',//     'content_5': '',//     'content_6': '',//     'times': 1000000 + i//   });// }_arrayChatMessage.add({'id': 99,'type': 1,'content_1': '你吃饭了吗? ','content_2': {'picture_mini': {'url':'https://img2.baidu.com/it/u=3202947311,1179654885&fm=253&fmt=auto&app=138&f=JPEG?w=800&h=500','width': 800,'height': 500},'picture':'https://user-info-1302720239.cos.ap-nanjing.myqcloud.com/userIcon/user_icon_000100.jpg',},'content_3':'https://user-info-1302720239.cos.ap-nanjing.myqcloud.com/userIcon/user_icon_000100.jpg','content_4': '','content_5': '','content_6': '','times': 1000000 + 9});_arrayChatMessage.add({'id': 100,'type': 1,'content_1': '我吃过了你呢? ','content_2': {'picture_mini': {'url':'https://img2.baidu.com/it/u=3202947311,1179654885&fm=253&fmt=auto&app=138&f=JPEG?w=800&h=500','width': 800,'height': 500},'picture':'https://user-info-1302720239.cos.ap-nanjing.myqcloud.com/userIcon/user_icon_000100.jpg',},'content_3':'https://user-info-1302720239.cos.ap-nanjing.myqcloud.com/userIcon/user_icon_000100.jpg','content_4': '','content_5': '','content_6': '','times': 1000000 + 9});_arrayChatMessage.add({'id': 100,'type': 2,'content_1': ' ','content_2': {'picture_mini': {'url':'https://img2.baidu.com/it/u=3202947311,1179654885&fm=253&fmt=auto&app=138&f=JPEG?w=800&h=500','width': 800,'height': 500},'picture':'https://user-info-1302720239.cos.ap-nanjing.myqcloud.com/userIcon/user_icon_000100.jpg',},'content_3':'https://user-info-1302720239.cos.ap-nanjing.myqcloud.com/userIcon/user_icon_000100.jpg','content_4': '','content_5': '','content_6': '','times': 1000000 + 9});_arrayChatMessage.add({'id': 100,'type': 2,'content_1': ' ','content_2': {'picture_mini': {'url':'https://lmg.jj20.com/up/allimg/1114/033021091503/210330091503-6-1200.jpg','width': 800,'height': 500},'picture':'https://user-info-1302720239.cos.ap-nanjing.myqcloud.com/userIcon/user_icon_000100.jpg',},'content_3':'https://user-info-1302720239.cos.ap-nanjing.myqcloud.com/userIcon/user_icon_000100.jpg','content_4': '','content_5': '','content_6': '','times': 1000000 + 9});_arrayChatMessage.add({'id': 100,'type': 2,'content_1': ' ','content_2': {'picture_mini': {'url':'https://lmg.jj20.com/up/allimg/1114/033021091503/210330091503-6-1200.jpg','width': 800,'height': 500},'picture':'https://user-info-1302720239.cos.ap-nanjing.myqcloud.com/userIcon/user_icon_000100.jpg',},'content_3':'https://user-info-1302720239.cos.ap-nanjing.myqcloud.com/userIcon/user_icon_000100.jpg','content_4': '','content_5': '','content_6': '','times': 1000000 + 9});_arrayChatMessage.add({'id': 100,'type': 2,'content_1': ' ','content_2': {'picture_mini': {'url':'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fc-ssl.duitang.com%2Fuploads%2Fblog%2F202107%2F16%2F20210716215819_76234.thumb.1000_0.png&refer=http%3A%2F%2Fc-ssl.duitang.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1679722694&t=6ddea52a86e658f1a73f6e0e3865bad6','width': 800,'height': 500},'picture':'https://user-info-1302720239.cos.ap-nanjing.myqcloud.com/userIcon/user_icon_000100.jpg',},'content_3':'https://user-info-1302720239.cos.ap-nanjing.myqcloud.com/userIcon/user_icon_000100.jpg','content_4': '','content_5': '','content_6': '','times': 1000000 + 9});_arrayChatMessage.add({'id': 100,'type': 2,'content_1': ' ','content_2': {'picture_mini': {'url':'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fc-ssl.duitang.com%2Fuploads%2Fblog%2F202107%2F16%2F20210716215819_76234.thumb.1000_0.png&refer=http%3A%2F%2Fc-ssl.duitang.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1679722694&t=6ddea52a86e658f1a73f6e0e3865bad6','width': 800,'height': 500},'picture':'https://user-info-1302720239.cos.ap-nanjing.myqcloud.com/userIcon/user_icon_000100.jpg',},'content_3':'https://user-info-1302720239.cos.ap-nanjing.myqcloud.com/userIcon/user_icon_000100.jpg','content_4': '','content_5': '','content_6': '','times': 1000000 + 9});_arrayChatMessage.add({'id': 100,'type': 2,'content_1': ' ','content_2': {'picture_mini': {'url': 'https://photo.tuchong.com/4274381/f/1139873881.jpg','width': 800,'height': 500},'picture':'https://user-info-1302720239.cos.ap-nanjing.myqcloud.com/userIcon/user_icon_000100.jpg',},'content_3':'https://user-info-1302720239.cos.ap-nanjing.myqcloud.com/userIcon/user_icon_000100.jpg','content_4': '','content_5': '','content_6': '','times': 1000000 + 9});_arrayChatMessage.add({'id': 100,'type': 2,'content_1': ' ','content_2': {'picture_mini': {'url': 'https://photo.tuchong.com/4274381/f/11398738812.jpg','width': 800,'height': 500},'picture':'https://user-info-1302720239.cos.ap-nanjing.myqcloud.com/userIcon/user_icon_000100.jpg',},'content_3':'https://user-info-1302720239.cos.ap-nanjing.myqcloud.com/userIcon/user_icon_000100.jpg','content_4': '','content_5': '','content_6': '','times': 1000000 + 9});//print('--datum:${widget.userInfoOther}');}@overrideWidget build(BuildContext context) {return Scaffold(resizeToAvoidBottomInset: false,appBar: AppBar(backgroundColor: AppColor.colorEDEDED,shadowColor: AppColor.colordddddd,elevation: 1.cale,leading: AppWidget.iconBack(() {AppNavigator().navigateBack();}),centerTitle: true,title: Text(widget.userInfoOther['name'],style: AppTextStyle.textStyle_34_000000,),actions: [Padding(padding: EdgeInsets.only(right: 24.cale),child: AppWidget.inkWellEffectNone(onTap: () {},child: Icon(AppIcon.dot3,size: 46.cale,color: Colors.black,),),)],),body: ChangeNotifierProvider<ProviderChatContent>(create: (BuildContext context) => ProviderChatContent(),child: Builder(builder: (BuildContext context) {return Column(children: [Expanded(child: AppWidget.inkWellEffectNone(onTap: () {FocusScope.of(context).requestFocus(FocusNode(),);context.read<ProviderChatContent>().updateContentShow(false);},child: ListView.builder(padding: EdgeInsets.symmetric(vertical: 30.cale),physics: const BouncingScrollPhysics(parent: AlwaysScrollableScrollPhysics(),),shrinkWrap: false,reverse: _arrayChatMessage.length > 7,itemCount: _arrayChatMessage.length,// itemExtent: 188.cale,itemBuilder: (BuildContext context, int index) {if (index % 2 != 0) {return ChatElementSelf(userInfo: widget.userInfoOther,chatMessage: _arrayChatMessage[index],);} else {return ChatElementOther(userInfo: widget.userInfoOther,chatMessage: _arrayChatMessage[index]);}},),),),Consumer(builder: (BuildContext context,ProviderChatContent providerChatContent, child) {return ChatBottom(providerChatContent: providerChatContent,);}),],);},),),);}@overridevoid dispose() {super.dispose();}
}

provider_chat_content.dart

import 'package:flutter/cupertino.dart';
import 'package:imflutter/wrap/extension/extension.dart';///用于 软键盘区/发送附件  域显示控制
class ProviderChatContent extends ChangeNotifier {bool _contentShow = false;double _keyboardHeight = 200;/// 是否显示 附件区域bool get contentShow => _contentShow;/// 键盘高度double get keyboardHeight => _keyboardHeight - 20.cale;///更新区域 展示void updateContentShow(bool isShow) {_contentShow = isShow;notifyListeners();}void updateKeyboardHeight(double height) {_keyboardHeight = height;notifyListeners();}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_75201.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Hbase资源隔离操作指南

1.检查集群的环境配置 1.1 HBase版本号确认> 5.11.0 引入rsgroup的Patch&#xff1a; [HBASE-6721] RegionServer Group based Assignment - ASF JIRA RegionServer Group based Assignment 社区支持版本&#xff1a;2.0.0 引入rsgroup的CDH版本 5.11.0 https://www.…

购买运动耳机应该考虑什么问题、运动达人必备的爆款运动耳机

喜欢运动的小伙伴都知道&#xff0c;运动和音乐是最配的&#xff0c;在运动中伴随着节奏感的音乐能够让自己更兴奋&#xff0c;锻炼的更加起劲儿。在运动耳机方面我也一直都有所研究&#xff0c;购买运动耳机最重要的就是要满足我们运动时候听音乐的需求&#xff0c;从佩戴舒适…

《C++ Primer Plus》(第6版)第5章编程练习

《C Primer Plus》&#xff08;第6版&#xff09;第5章编程练习《C Primer Plus》&#xff08;第6版&#xff09;第5章编程练习1. 计算闭区间内的整数和2. 重新编写程序清单5.43. 累加4. 投资价值5. 销售情况6. 销售情况27. 汽车8. 销售情况29. 销售情况210. 销售情况2《C Prim…

【技术美术图形部分】简述主流及新的抗锯齿技术

电脑的世界里没有曲线&#xff0c;都是三角面组成一个个模型的&#xff0c;因此一定会出现走样&#xff08;锯齿&#xff09;的情况&#xff0c;只是严重与否的问题&#xff0c;而AA也是实时渲染最难解决的问题之一。 Sampling&Artifacts Lecture 06 Rasterization 2 (An…

MAML算法详解(元学习)

文章目录回顾元学习MAML算法MAML和预训练模型的区别数学推导MAML实施细节总结回顾元学习 元学习的基本知识参考这篇博客元学习和机器学习的对比 MAML算法 学习初始化参数&#xff0c;所有任务的初始化的参数都是一样的 MAML和预训练模型的区别 MAML使用的是ϕ\phiϕ…

阶段十:总结专题(第六章:缓存篇)

阶段十&#xff1a;总结专题&#xff08;第六章&#xff1a;缓存篇&#xff09;Day-第六章&#xff1a;缓存篇1. Redis 数据类型**String****List****Hash****Sorted Set**2. keys 命令问题3. 过期 key 的删除策略4. Redis 持久化**AOF 持久化****AOF 重写****RDB 持久化****混…

Python 中 openpyxl 模块封装,读写 Excel 文件中自动化测试用例数据

只有测试数据和错误提示信息不同&#xff0c;其他代码都是一样的&#xff0c;不这样不易修改数据和维护&#xff0c;会有两点痛点 1.代码冗余极其严重, 程序可读性不佳 2.程序拓展性很差 往往我们在自动化测试汇总&#xff0c;会将数据放在 Excel 文件、CSV文件、数据库 Py…

Python-scatter散点图及颜色大全

# -*- coding: utf-8 -*- import numpy as np import matplotlib.pyplot as pltplt.rcParams[font.sans-serif][SimHei] plt.rcParams[axes.unicode_minus] False #matplotlib画图中中文显示会有问题&#xff0c;需要这两行设置默认字体plt.xlabel(X) plt.ylabel(Y) plt.xlim…

【IP技术】ipv4和ipv6是什么?

IPv4和IPv6是两种互联网协议&#xff0c;用于在互联网上标识和寻址设备。IPv4&#xff08;Internet Protocol version 4&#xff09;是互联网协议的第四个版本&#xff0c;是当前广泛使用的互联网协议。IPv4地址由32位二进制数构成&#xff0c;通常表示为4个十进制数&#xff0…

大数据技术之Hive(四)分区表和分桶表、文件格式和压缩

一、分区表和分桶表1.1 分区表partitionhive中的分区就是把一张大表的数据按照业务需要分散的存储到多个目录&#xff0c;每个目录就称为该表的一个分区。在查询时通过where子句中的表达式选择式选择查询所需要的分区&#xff0c;这样的查询效率辉提高很多。1.1.1 分区表基本语…

2023年蜂巢科技最新面试题

2023年蜂巢科技最新面试题 bio与nio的区别 bio同步阻塞io&#xff1a;在此种⽅式下&#xff0c;⽤户进程在发起⼀个IO操作以后&#xff0c;必须等待IO操作的完成&#xff0c;只有当真正完成了IO操作以后&#xff0c;⽤户进程才能运⾏。JAVA传统的IO模型属于此种⽅式&#xff0…

flink常用算子介绍

flink任务中【Transformation 数据转换】是对数据进行操作&#xff0c;有 Map、FlatMap、Filter、KeyBy 、Reduce 、Fold 、Aggregations、Window 、WindowAll 、Union 、Window join 、Split 、Select 、Project 等&#xff0c;通过对数据的操作&#xff0c;转换成想要的数据&…

HttpRunnerManager部署

基于HttpRunner的接口自动化测试平台: HttpRunner, djcelery and Django_. HttpRunner手册: http://cn.httprunner.org/git地址&#xff1a;httprunner/HttpRunnerManager: 基于 HttpRunner 的 Web 测试平台&#xff0c;已停止维护。 (github.com)部署机器&#xff1a;linux部署…

vue3+rust个人博客建站日记4-Vditor搞定MarkDown

即然是个人博客&#xff0c;那么绝对不能丢给自己一个大大的输入框敷衍了事。如果真是这样&#xff0c;现在就可以宣布项目到此结束了。如今没人享受用输入框写博客。作为一个有追求的程序员&#xff0c;作品就要紧跟潮流。 后来&#xff0c;Markdown 的崛起逐步改变了大家的排…

华为OD机试题,用 Java 解【火星文计算 2】问题

最近更新的博客 华为OD机试题,用 Java 解【停车场车辆统计】问题华为OD机试题,用 Java 解【字符串变换最小字符串】问题华为OD机试题,用 Java 解【计算最大乘积】问题华为OD机试题,用 Java 解【DNA 序列】问题华为OD机试 - 组成最大数(Java) | 机试题算法思路 【2023】使…

跑步戴哪种蓝牙耳机比较好,五款适合跑步的蓝牙耳机推荐

跑步当中佩戴的蓝牙耳机&#xff0c;佩戴舒适度以及牢固度是我们首要关注的&#xff0c;耳机的材质还有耳机的防水能力&#xff0c;都是十分需要注意的方面。那具体在挑选运动耳机当中需要如何选择呢&#xff1f;下面收集的一些在运动当中比较好用的运动蓝牙耳机分享给大家。1、…

华为OD机试题,用 Java 解【机器人走迷宫】问题

最近更新的博客 华为OD机试题,用 Java 解【停车场车辆统计】问题华为OD机试题,用 Java 解【字符串变换最小字符串】问题华为OD机试题,用 Java 解【计算最大乘积】问题华为OD机试题,用 Java 解【DNA 序列】问题华为OD机试 - 组成最大数(Java) | 机试题算法思路 【2023】使…

力扣每日一题(2023年2月)

2023年2月期每日一题第一天 &#xff08;2325. 解密消息&#xff09;第十六天&#xff08;2341. 数组能形成多少数对&#xff09;第十七天 &#xff08;1139. 最大的以 1 为边界的正方形&#xff09;第十八天 &#xff08;1237. 找出给定方程的正整数解&#xff09;第十九天 &a…

【再临数据结构】Day1. 稀疏数组

前言 这不单单是稀疏数组的开始&#xff0c;也是我重学数据结构的开始。因此&#xff0c;在开始说稀疏数组的具体内容之前&#xff0c;我想先说一下作为一个有着十余年“学龄”的学生&#xff0c;所一直沿用的一个学习方法&#xff1a;3W法。我认为&#xff0c;只有掌握了正确的…

Apache Hive入门

文章目录一、Apache Hive概述1.1、什么是Hive1.2、使用Hive原因1.3、Hive和Hadoop关系二、Hive功能思想2.1、映射信息记录2.2、SQL语法解析、编译三、Hive架构、组件3.1、Hive架构图3.2Hive组件四、Hive常用操作4.1、数据类型4.1.1、基本数据类型4.1.2、集合数据类型4.2、数据库…