高仿微信聊天输入框,效果图如下(目前都是静态展示,服务还没开始开发):
大家如果观察仔细的话 应该会发现,他输入框下面的高度 刚好就是 软键盘的高度;所以在这里就需要监听软键盘的高度。还要配置
- resizeToAvoidBottomInset: false,
- ? ?return Scaffold(
- ? ? ? resizeToAvoidBottomInset: false,
- ? ? ? appBar: AppBar(
(因为严格限制 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'},
- ];
-
- @override
- void initState() {
- // TODO: implement initState
- super.initState();
- WidgetsBinding.instance.addObserver(this);
- _controller.addListener(() {
- setState(() {});
- });
- _focusNode.addListener(() {
- if (_focusNode.hasFocus) {
- widget.providerChatContent.updateContentShow(true);
- }
- });
- }
-
- @override
- Widget 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(),
- ),
- )
- ],
- ),
- );
- }
-
- ///应用尺寸改变时回调,例如旋转 键盘
- @override
- void didChangeMetrics() {
- // TODO: implement didChangeMetrics
- super.didChangeMetrics();
- if (mounted) {
- // 键盘高度
- final double viewInsetsBottom = EdgeInsets.fromWindowPadding(
- WidgetsBinding.instance.window.viewInsets,
- WidgetsBinding.instance.window.devicePixelRatio)
- .bottom;
- if (viewInsetsBottom > 0) {
- widget.providerChatContent.updateKeyboardHeight(viewInsetsBottom);
- }
- }
- }
-
- @override
- void 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);
-
- @override
- State<ChatElementOther> createState() => _ChatElementOtherState();
- }
-
- class _ChatElementOtherState extends State<ChatElementOther> {
- @override
- Widget 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 {
- @override
- void 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;
- }
-
- @override
- bool shouldRepaint(covariant CustomPainter oldDelegate) {
- // TODO: implement shouldRepaint
- return 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);
-
- @override
- State<ChatElementSelf> createState() => _ChatElementSelfState();
- }
-
- class _ChatElementSelfState extends State<ChatElementSelf> {
- @override
- Widget 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 {
- @override
- void 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;
- }
-
- @override
- bool shouldRepaint(covariant CustomPainter oldDelegate) {
- // TODO: implement shouldRepaint
- return 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);
-
- @override
- Widget 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);
-
- @override
- State<PageChatPerson> createState() => _PageChatPersonState();
- }
-
- class _PageChatPersonState extends State<PageChatPerson> {
- /// 1 文本
- /// 2 图片
- /// 3 语音
- /// 4 视频
- /// 5 提示消息
- /// 6 提示消息
- final List<Map> _arrayChatMessage = [];
-
- @override
- void initState() {
- // TODO: implement initState
- super.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}');
- }
-
- @override
- Widget 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,
- );
- }),
- ],
- );
- },
- ),
- ),
- );
- }
-
- @override
- void 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();
- }
- }
到此这篇关于flutter 微信聊天输入框的文章就介绍到这了,更多相关flutter 微信聊天输入框内容请搜索w3xue以前的文章或继续浏览下面的相关文章希望大家以后多多支持w3xue!