文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

flutter微信聊天输入框功能如何实现

2023-07-05 07:59

关注

这篇文章主要讲解了“flutter微信聊天输入框功能如何实现”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“flutter微信聊天输入框功能如何实现”吧!

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

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

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

这里以 单聊为例:

遇到有个问题就是输入框行数的限制:这里这只 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: "输入错误",),

代码结构如下:

flutter微信聊天输入框功能如何实现

--- 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微信聊天输入框功能如何实现这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是编程网,小编将为大家推送更多相关知识点的文章,欢迎关注!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     807人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     351人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     314人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     433人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     221人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯