返回顶部
首页 > 资讯 > 精选 >flutter微信聊天输入框功能如何实现
  • 514
分享到

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

2023-07-05 07:07:21 514人浏览 安东尼
摘要

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

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

--结束END--

本文标题: flutter微信聊天输入框功能如何实现

本文链接: https://lsjlt.com/news/350543.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • flutter微信聊天输入框功能如何实现
    这篇文章主要讲解了“flutter微信聊天输入框功能如何实现”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“flutter微信聊天输入框功能如何实现”吧!高仿微信聊天输入框,效果图如下(目前都...
    99+
    2023-07-05
  • flutter微信聊天输入框功能实现
    目录chat_bottom.dartchat_element_other.dart chat_element_self.dart  chat_input...
    99+
    2023-03-02
    flutter 微信聊天输入框 flutter 聊天输入框 flutter 输入框
  • Android 使用<layer-list>实现微信聊天输入框功能
     LayerDrawable <layer-list> 标签可是设置LayerDrawable,一种有层次的Drawable叠加效果,<layer-list> 可以包含多个 <item>...
    99+
    2023-05-31
    android layer list
  • HTML5如何实现微信聊天、微信聊天表情编辑器功能
    这篇文章主要为大家展示了“HTML5如何实现微信聊天、微信聊天表情编辑器功能”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“HTML5如何实现微信聊天、微信聊天表...
    99+
    2024-04-02
  • 微信小程序实现聊天室功能
    本文通过实例为大家分享了微信小程序实现聊天室的具体代码,供大家参考,具体内容如下 1.实现效果展示 2.room.wxml <view class="container"...
    99+
    2024-04-02
  • 【微信开发】微信小程序实现实时聊天功能
    最近在做一个项目,需要运用到实时聊天功能,分享一下。      分为: 界面如何布局以及细节; 如何实现实时更新; 全部代码展示;         一、界面如何布局以及细节:         1.说到底,聊天界面就是循环一个数组,每一行...
    99+
    2023-09-02
    微信小程序 小程序
  • Unity实现微信聊天框界面
    本文实例为大家分享了Unity实现微信聊天框界面的具体代码,供大家参考,具体内容如下 【原理】 一个聊天界面主要由三个部分组成:内容区、可见区、滑动条 可见区在内容区上边,内容区会随...
    99+
    2024-04-02
  • java仿QQ微信聊天室功能的实现
    话不多说,先上图                      &...
    99+
    2024-04-02
  • 如何用PHP实现微信小程序的实时聊天功能?
    如何用PHP实现微信小程序的实时聊天功能?随着移动互联网的发展,微信小程序成为了很多开发者的首选平台。而实时聊天功能作为一种关键的社交功能,很多用户都希望在自己的小程序中实现。本文将介绍如何使用PHP来实现微信小程序的实时聊天功能,并提供具...
    99+
    2023-10-27
    PHP 微信小程序 实时聊天
  • uni-app小程序实现微信在线聊天功能(私聊/群聊)
    目录聊天信息列表的渲染聊天信息发送的相关问题实现一对一聊天关于websocket建立连接存储连接的用户发送聊天信息 首页新消息提示实现群聊加入房间发送群消息之前学习使用un...
    99+
    2023-02-18
    uni-app小程序微信聊天 uni-app微信小程序聊天
  • 如何利用HTML5+css3+jquery+weui实现仿微信聊天界面功能
    这篇文章主要介绍如何利用HTML5+css3+jquery+weui实现仿微信聊天界面功能,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!最新因项目需要,就利用HTML5+css3+jquery+weui做了一个仿微信...
    99+
    2023-06-09
  • Flutter实现微信朋友圈功能
    本文实例为大家分享了Flutter实现微信朋友圈功能的具体代码,供大家参考,具体内容如下 今天给大家实现一下微信朋友圈的效果,下面是效果图 下面还是老样子,还是以代码的方式进行讲解...
    99+
    2024-04-02
  • 微信小程序如何实现input输入框
    小编给大家分享一下微信小程序如何实现input输入框,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!微信小程序 checkbox 实现效果图:微信小程序输入框input属性名类型默认值说明v...
    99+
    2024-04-02
  • Redis如何实现聊天室功能?
    今天小编就为大家带来一篇介绍Redis实现聊天室功能的文章。小编觉得挺实用的,为此分享给大家做个参考。一起跟随小编过来看看吧。首先,来介绍下关于pub/sub的几个命令。发布消息publish channe...
    99+
    2024-04-02
  • php如何实现聊天室功能
    本篇内容主要讲解“php如何实现聊天室功能”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“php如何实现聊天室功能”吧!php实现聊天室功能的方法:首先创建前端代码;然后在PHP后端文件中通过创建...
    99+
    2023-06-20
  • Unity如何实现聊天室功能
    这篇文章给大家分享的是有关Unity如何实现聊天室功能的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。聊天室服务器服务器需要有以下几个步骤确定Socket协议类型(采用TCP协议或者UDP协议)2、绑定服务器的IP...
    99+
    2023-06-08
  • HTML5如何实现微信聊天界面、微信朋友圈
    这篇文章主要介绍HTML5如何实现微信聊天界面、微信朋友圈,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!html代码片段:<!--BEGIN 打赏--> <...
    99+
    2024-04-02
  • Flutter如何支持放大镜的输入框功能
    这篇文章将为大家详细讲解有关Flutter如何支持放大镜的输入框功能,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。功能需求最近需求开发中遇到一个Flutter开发问题,为了优化用户输入体验。产品同学希望能...
    99+
    2023-06-29
  • C++如何实现TCP聊天室功能
    小编给大家分享一下C++如何实现TCP聊天室功能,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!具体内容如下TCPServer.cpp:// TCPSer...
    99+
    2023-06-20
  • 微信小程序中如何实现聊天室
    小编给大家分享一下微信小程序中如何实现聊天室,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!微信小程序中如何实现聊天室utils文...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作