• Flutter高仿微信-第44篇-群聊


    Flutter高仿微信系列共59篇,从Flutter客户端、Kotlin客户端、Web服务器、数据库表结构、Xmpp即时通讯服务器、视频通话服务器、腾讯云服务器全面讲解。

     详情请查看

    效果图:

    实现代码:

    group_chat_main.dart

    /**
     * Author : wangning
     * Email : maoning20080809@163.com
     * Date : 2022/11/6 19:42
     * Description : 群聊
     */
    
    class GroupChatMain extends StatefulWidget {
    
      String toGroupId;
      String account = SpUtils.getString(CommonUtils.LOGIN_ACCOUNT);
    
      GroupChatMain({required this.toGroupId});
    
      @override
      _GroupChatMainState createState() => _GroupChatMainState(toGroupId);
    }
    
    class _GroupChatMainState extends State with TickerProviderStateMixin {
    
      String _toGroupId;
      _GroupChatMainState(this._toGroupId);
    
      //我的账户
      UserBean? _meUserBean;
    
      GroupBean? _groupBean;
    
      List addTimeList = [];
      List items = [];
      ScrollController _controller = ScrollController();
      var chatEvent;
      var baseEvent;
      //每页13条
      static const PAGE_SIZE = 13;
      //当前页
      var PAGE_NUM = 1;
      //从那一条开始(为保证最新的先显示, 先查询最后的,并且不能用desc查询)
      var startNum = 0;
      //总共多少条
      var CHAT_TOTAL = 0;
    
      //群成员个数
      int? memberCount = 0;
    
      @override
      void initState() {
        super.initState();
        AppManager.getInstance().toGroupId = _toGroupId;
        _checkAvailable();
        _updateChatStatus();
    
        baseEvent = eventBus.on((baseBean) {
          //刷新群聊记录
          if(baseEvent != null && baseBean.type == BaseEvent.TYPE_REFRESH_GROUP){
            loadAllChat();
            loadGroupBean();
          }
        });
    
        chatEvent = eventBus.on((groupChatBean) {
          LogUtils.d('群聊发送消息接收:${groupChatBean.runtimeType}');
          setState(() {
            groupChatBean as GroupChatBean;
            items.add(groupChatBean);
            setState(() {
    
            });
          });
        });
    
        loadGroupBean();
        loadGroupUserCount();
        loadUserBean();
        loadAllChat();
    
        jumpToBottom(400);
        // 监听滚动事件
        _controller.addListener((){
          if(_controller.position.pixels>_controller.position.maxScrollExtent-40){
          }
        });
    
      }
    
      //加载群成员个数
      void loadGroupUserCount() async{
        memberCount = await GroupUserRepository.getInstance().findGroupUserCountByGroupId(widget.toGroupId);
        LogUtils.d("加载群成员个数 groupId = ${widget.toGroupId} ,  count = ${memberCount}");
        /*setState(() {
        });*/
      }
    
      @override
      void dispose() {
        super.dispose();
        eventBus.off(chatEvent);
        eventBus.off(baseEvent);
        AppManager.getInstance().toGroupId = "";
      }
    
      final controller = TextEditingController();
      FocusNode _chatContentFocus = FocusNode();
    
      @override
      Widget build(BuildContext context) {
        if(!isLoadMore){
          //每次发送消息滚动到底部0.1秒
          jumpToBottom(100);
        }
    
        return Scaffold(
          appBar: WnAppBar.getAppBar(context, Text("${_groupBean?.groupName}(${memberCount})"), addGroup : true, addGroupClick: (){
                Navigator.pushNamed(context, Routes.show_group_member, arguments: {
                  "groupId":widget.toGroupId  //参数map
                });
           }),
          bottomNavigationBar: Text(""),//占用底部位置
          body: GestureDetector(
            onTap: (){
              _processClickBlank();
            },
            child: Container(
              child: Column(
                children: [
                  Expanded(
                    child: RefreshIndicator(
                        displacement: 2,
                        onRefresh: _onRefresh,
                        child: ListView.builder(
                          controller: _controller,
                          itemBuilder: (BuildContext context, int index) {
                            return GroupChatContentView(items: items,account: widget.account, groupChatBean: items[index], index: index, meUserBean: _meUserBean,addTimeList: addTimeList,
                              otherAccount: items[index].account, deleteCallback: (data){
                                setState(() {
                                  items.remove(items[index]);
                                });
                              },clickVoiceCallback: (data){
                                //点击播放录音,暂停后再播放
                                for(int i = 0; i < items.length; i++){
                                  if(i == index){
                                    items[i].isPlayVoice = true;
                                  } else {
                                    items[i].isPlayVoice = false;
                                  }
                                }
                                setState(() {
    
                                });
                              }, refreshTransfer: (position){
                                LogUtils.d("回调刷新:${position}");
    
                              },);
                          },
                          itemCount: items.length,
    
                        )
                    ),
                  ),
                  Divider(height: 12.0, color: Color(0xFFF7F8F8),),
                  Container(
                    padding: EdgeInsets.only(top: 5.0, bottom: 5.0, right: 2.0, left: 2.0),
                    color: Color(0xFFF3F3F3),
                    width: double.infinity,
                    child: Row(
    
                      children: [
                        Container(
                          margin: EdgeInsets.symmetric(horizontal: 2.0),
                          child: IconButton(
                            //按下语音说活
                              icon: isPressVoice ? Image.asset("assets/chat/button_keyboard.png"):Image.asset("assets/chat/button_voice.png"),
                              onPressed: () =>{
                                _processPressVoice()
                              }
                          ), //触发发送消息事件执行的函数_handleSubmitted
                        ),
                        Expanded(
                          child: Stack(
                            children: [
                              Offstage(
                                offstage: !isPressVoice,
                                child: ChatVoiceView(
                                  refreshMediaCallback: (type, mediaURL, thumbnailFileName, second, messageId){
                                    _refreshMedia(type, mediaURL, thumbnailFileName, mediaSecond: second, messageId: messageId);
                                  },
                                  sendMedialCallback: (type, mediaURL, second, messageId){
                                    _sendMedia(type, mediaURL, mediaSecond: second, messageId: messageId);
                                  },
                                  stopPlayVoiceCallback: (){
                                    hidePlayVoiceList();
                                  },
                                ),
                              ),
                              Offstage(
                                offstage: isPressVoice,
                                child: Container(
                                  padding: EdgeInsets.only(top: 8.0, bottom: 8.0, left: 8.0),
                                  decoration: BoxDecoration(borderRadius: BorderRadius.all(Radius.circular(5.0),),color: Colors.white),
                                  child: TextField(
                                    controller: controller,
                                    focusNode: _chatContentFocus,
                                    decoration: InputDecoration.collapsed(hintText: null),
                                    autocorrect: true,
                                    //是否自动更正
                                    autofocus: false,
                                    maxLines: 5,
                                    minLines: 1,
                                    textAlign: TextAlign.start,
                                    style: TextStyle(color: Colors.black, fontSize: 20),
                                    cursorColor: Colors.green,
                                    onTap: (){
                                      //点击编辑框
                                      jumpToBottom(400);
                                      hideEmoji = true;
                                      hideAdd = true;
                                      setState(() {
                                      });
                                    },
                                    onChanged: (value){
                                      //录入文字
                                      setState(() {
                                        if(value.length>0){
                                          hideSend = false;
                                          hideAddIcon = true;
                                        } else {
                                          hideSend = true;
                                          hideAddIcon = false;
                                        }
                                      });
                                    },
                                    onSubmitted: _handleSubmitted,
                                    enabled: true, //是否禁用
                                  ),
                                ),
                              ),
                            ],
                          ),
    
                        ),
    
                        Container(
                          child: IconButton(
                              icon: Image.asset("assets/chat/button_emoji.png"),
                              onPressed: () => _processEmoji()),
                        ),
    
    
                        Offstage(
                          offstage: hideAddIcon,
                          child: Container(
                            //margin: EdgeInsets.only(right: 4.0),
                            child: IconButton(
                              //添加按钮
                                icon: Image.asset("assets/chat/button_add.png"),
                                onPressed: () => {
                                  _processAdd()
                                }
                            ),
                          ),
                        ),
    
                        Offstage(
                          offstage: hideSend,
                          child: Container(
                            margin: EdgeInsets.symmetric(horizontal: 4.0),
                            child: IconButton(
                              //发送按钮
                                icon: new Icon(Icons.send), //发送按钮图标
                                onPressed: () => _handleSubmitted(
                                    controller.text)), //触发发送消息事件执行的函数_handleSubmitted
                          ),
                        ),
                      ],
                    ),
                  ),
    
                  Offstage(
                    offstage: hideAdd,
                    child: ChatAddView(
                      viewType: CommonUtils.VIEW_TYPE_GROUP_CHAT,
                      toChatId: widget.toGroupId,
                      refreshMediaCallback: (type, mediaURL, thumbnailFileName, second, messageId){
                        _refreshMedia(type, mediaURL, thumbnailFileName, mediaSecond: second , messageId: messageId);
                      },
                      sendMedialCallback: (type, mediaURL, second, messageId){
                        _sendMedia(type, mediaURL, mediaSecond: second, messageId: messageId);
                      },
                      refreshRedpacketAndTransfer: (type, text){
    
                      },
                    ),
                  ),
    
                  Offstage(
                    offstage: hideEmoji,
                    child: getEmojiWidget(),
                  ),
    
                ],
              ),
            ),
          ),
        );
      }
    
      //进入聊天页面,把聊天状态更新为已读
      void _updateChatStatus() async{
        int newMessageCount = await ChatRepository.getInstance().getAllChatUnReadByAccount(_toGroupId)??0;
        if(newMessageCount >= 0){
          await ChatRepository.getInstance().updateChatReadByAccount(_toGroupId);
          Map result = HashMap();
          result["from_account"] = _toGroupId;
          eventBus.emit(BaseEvent(BaseEvent.TYPE_UPDATE_CHAT_STATUS, result: result));
        }
    
      }
    
      // 下拉刷新
      Future _onRefresh() async{
        // 持续两秒
        await Future.delayed(Duration(milliseconds:20),(){
          //LogUtils.d("下拉刷新--开始 ${startNum} , ${PAGE_SIZE} , ${CHAT_TOTAL}");
    
          if(startNum >= PAGE_SIZE){
            startNum = CHAT_TOTAL - PAGE_SIZE * PAGE_NUM;
            _loadMoreData(widget.account, widget.toGroupId, startNum, PAGE_SIZE);
          } else if(startNum > 0 && startNum < PAGE_SIZE){
            //不够1页数据,查询全部,然后就不能下一页
            _loadMoreData(widget.account, widget.toGroupId, 0, startNum);
            startNum = 0;
          }
    
        });
      }
    
      bool isLoadMore = false;
      //上拉加载更多数据
      void _loadMoreData(String fromAccount, String toAccount, int sNum , int pageSize){
    
      }
    
      //检查状态, 如果不可以,先登录
      void _checkAvailable() async{
        var isAvailable = await XmppManager.getInstance().isAvailable();
        if(!isAvailable){
          String account = SpUtils.getString(CommonUtils.LOGIN_ACCOUNT);
          String password = SpUtils.getString(CommonUtils.LOGIN_PASSWORD);
          XmppManager.getInstance().connect(account, password);
        }
      }
    
      void loadAllChat() async {
        CHAT_TOTAL = await GroupChatRepository.getInstance().findGroupChatCountByGroupId(widget.toGroupId)??0;
        startNum = CHAT_TOTAL - PAGE_SIZE * PAGE_NUM;
        GroupChatRepository.getInstance().findAllGroupChatByGroupIdPage(widget.toGroupId, startNum, CHAT_TOTAL).then((chatList) {
          if(startNum > 0){
            PAGE_NUM++;
          }
          setState(() {
            items = chatList??[];
            items.forEach((element) {
              LogUtils.d("群aa聊:${element.toJson()}");
            });
          });
        });
      }
    
      void loadUserBean() async {
        UserRepository.getInstance().findUserByAccount(widget.account).then((userBean) {
          //setState(() {
            _meUserBean = userBean!;
          //});
        });
      }
    
      //加载群信息
      void loadGroupBean() async {
        _groupBean = await GroupRepository.getInstance().findGroupByGroupId(widget.toGroupId);
        //setState(() {
        //});
      }
    
      _sendMessage(var message){
        int id = DateTime.now().millisecondsSinceEpoch;
        String toJid = "${widget.toGroupId}@conference.wangning";
        XmppManager.getInstance().sendGroupMessageWithType(toJid, message, "${id}", id);
    
        Map result = HashMap();
        eventBus.emit(BaseEvent(BaseEvent.TYPE_NEW_MESSAGE, result: result));
      }
    
      //默认滚动到底部
      void jumpToBottom(int milliseconds){
        //LogUtils.d("滚动到底部");
        //第一次进入,滚动到底部要0.4秒
        if (items.length > 0) {
          Timer(Duration(milliseconds: milliseconds),
                  () => _controller.jumpTo(_controller.position.maxScrollExtent));
        }
      }
    
      //隐藏播放列表,停止播放录音
      hidePlayVoiceList(){
        for(int i = 0; i < items.length;i++){
          items[i].isPlayVoice = false;
        }
        AudioPlayer.getInstance().stop();
        setState(() {
        });
      }
    
      //刷新多媒体(图片、语音、小视频) (先刷新本地,然后小视频压缩完成再慢慢发送)
      void _refreshMedia(int type, String mediaURL, String thumbnailFileName, {int mediaSecond=0, String messageId = "" }) async {
    
        bool isNetwork = await CommonNetwork.isNetwork();
        if(!isNetwork) {
          CommonUtils.showNetworkError(context);
          return;
        }
    
        String addTime = WnDateUtils.getCurrentTime();
    
        //先刷新本地聊天
        //ChatBean chatBean = ChatBean(fromAccount: widget.account, toAccount: widget.toGroupId,addTime:addTime,messageId: messageId,isRead: 1);
        GroupChatBean groupChatBean = GroupChatBean(account: widget.account, groupId: widget.toGroupId, addTime: addTime, messageId: messageId);
    
        groupChatBean.contentType = type;
        if(type == CommonUtils.CHAT_CONTENT_TYPE_VOICE){
          groupChatBean.localMediaUrl = mediaURL;
          groupChatBean.second = mediaSecond;
          //状态变更,向聊天记录中插入新记录
          setState(() {
            items.add(groupChatBean);
          });
          await GroupChatRepository.getInstance().insertGroupChat(groupChatBean);
        } else if(type == CommonUtils.CHAT_CONTENT_TYPE_IMG){
          groupChatBean.localMediaUrl = mediaURL;
          //状态变更,向聊天记录中插入新记录
          setState(() {
            items.add(groupChatBean);
          });
          await GroupChatRepository.getInstance().insertGroupChat(groupChatBean);
        } else if(type == CommonUtils.CHAT_CONTENT_TYPE_VIDEO){
          groupChatBean.localMediaUrl = mediaURL;
          groupChatBean.content = thumbnailFileName;
          groupChatBean.second = mediaSecond;
    
          GroupChatBean? localGroupChatBean = await GroupChatRepository.getInstance().findGroupChatByMessageId(messageId);
          //状态变更,向聊天记录中插入新记录
          if(localGroupChatBean == null){
            items.add(groupChatBean);
            GroupChatRepository.getInstance().insertGroupChat(groupChatBean);
          } else {
            groupChatBean.id = localGroupChatBean.id;
            GroupChatRepository.getInstance().updateGroupChat(groupChatBean);
            //如果已经存在,先删除在添加
            for(int i = 0; i < items.length; i++){
              GroupChatBean item = items[i];
              if(item.messageId == messageId){
                items.remove(item);
                break;
              }
            }
            items.add(groupChatBean);
          }
          setState(() {
          });
    
        }
    
        jumpToBottom(100);
      }
    
      //发送多媒体(图片、语音、小视频)
      void _sendMedia(int type, String mediaURL, {int mediaSecond = 0, String messageId = ""}) async {
    
        bool isNetwork = await CommonNetwork.isNetwork();
        if(!isNetwork) {
          return;
        }
    
        //上传文件
        GroupChatBean? serverChatBean;
        String message = "";
        String addTime = WnDateUtils.getCurrentTime();
        ChatSendBean chatSendBean = ChatSendBean();
        chatSendBean.fromAccount = SpUtils.getAccount();
        chatSendBean.contentType = type;
        chatSendBean.messageId = messageId;
        chatSendBean.addTime = addTime;
        if(type == CommonUtils.CHAT_CONTENT_TYPE_IMG){
          //图片
          serverChatBean = await UploadUtils.getInstance().uploadGroupChatImage(widget.account, widget.toGroupId, mediaURL, messageId, addTime);
    
        } else if(type == CommonUtils.CHAT_CONTENT_TYPE_VOICE){
          //语音
          serverChatBean = await UploadUtils.getInstance().uploadGroupChatVoice(widget.account, widget.toGroupId, mediaURL, messageId, addTime, mediaSecond);
          chatSendBean.second = mediaSecond;
        } else if(type == CommonUtils.CHAT_CONTENT_TYPE_VIDEO){
          //小视频
          serverChatBean = await UploadUtils.getInstance().uploadGroupChatVideo(widget.account, widget.toGroupId, mediaURL, messageId, addTime, mediaSecond);
          chatSendBean.second = mediaSecond;
        } else {
          return ;
        }
        chatSendBean.content = serverChatBean?.serverMediaUrl??"";
        GroupChatRepository.getInstance().updateGroupChatByMessageId(serverChatBean?.messageId??"", serverChatBean?.serverMediaUrl??"");
        message = jsonEncode(chatSendBean);
        _sendMessage(message);
      }
    
      //是否隐藏文件
      bool hideAdd = true;
      //是否隐藏emoji表情
      bool hideEmoji = true;
      //是否隐藏发送按钮
      bool hideSend = true;
      //是否隐藏添加按钮
      bool hideAddIcon = false;
      //是否按下语音说话
      bool isPressVoice = false;
    
      //点击空白地方,隐藏文件、emoji
      void _processClickBlank(){
        setState(() {
          hideAdd = true;
          hideEmoji = true;
          _chatContentFocus.unfocus();    // 失去焦点
        });
      }
    
      void _processPressVoice(){
        setState(() {
          isPressVoice = !isPressVoice;
          hideEmoji = true;
          hideAdd = true;
          _processFocus();
        });
      }
    
      void _processEmoji(){
        LogUtils.d("点击emoji");
        setState(() {
          hideEmoji = !hideEmoji;
          isPressVoice = false;
          hideAdd = true;
          _processFocus();
        });
      }
    
      void _processAdd(){
        setState(() {
          hideAdd = !hideAdd;
          isPressVoice = false;
          hideEmoji = true;
          _processFocus();
        });
      }
    
      void _processFocus(){
        if(!hideAdd || !hideEmoji || isPressVoice){
          _chatContentFocus.unfocus();    // 失去焦点
        } else {
          FocusScope.of(context).requestFocus(_chatContentFocus);     // 获取焦点
        }
      }
    
      emoticonClick(String name){
        //LogUtils.d("选择表情:" + name);
        controller.text = name;
      }
    
      ///选中表情
      _onEmojiSelected(Emoji emoji) {
        controller
          ..text += emoji.emoji
          ..selection = TextSelection.fromPosition(TextPosition(offset: controller.text.length));
        hideAddIcon = true;
        hideSend = false;
        setState(() {
        });
      }
    
      ///表情删除按钮
      _onBackspacePressed() {
        controller
          ..text = controller.text.characters.skipLast(1).toString()
          ..selection = TextSelection.fromPosition(
              TextPosition(offset: controller.text.length));
        if (controller.text.isNotEmpty) {
          setState(() {
          });
        }
      }
    
      //定义发送文本事件的处理函数
      void _handleSubmitted(String text) async {
        if (text.length > 0) {
    
          bool isNetwork = await CommonNetwork.isNetwork();
          if(!isNetwork) {
            CommonUtils.showNetworkError(context);
            return;
          }
    
          int contentType = CommonUtils.CHAT_CONTENT_TYPE_TEXT;
          String addTime = WnDateUtils.getCurrentTime();
          String messageId = UUID.getUUID();
          ChatSendBean chatSendBean = ChatSendBean();
          chatSendBean.contentType = contentType;
          chatSendBean.content = text;
          chatSendBean.addTime = addTime;
          chatSendBean.second = 0;
          chatSendBean.messageId = messageId;
          chatSendBean.fromAccount = SpUtils.getAccount();
          String message = jsonEncode(chatSendBean);
    
    
          controller.clear(); //清空输入框
          GroupChatBean groupChatBean = GroupChatBean(account: widget.account, groupId: widget.toGroupId, content: text, contentType: contentType, addTime: addTime, messageId: messageId, localMediaUrl: "", serverMediaUrl: "", second: 0);
          LogUtils.d("插入数据:${groupChatBean.toJson()}");
          //状态变更,向聊天记录中插入新记录
          setState(() {
            hideAddIcon = false;
            hideSend = true;
            items.add(groupChatBean);
          });
          await GroupChatRepository.getInstance().insertGroupChat(groupChatBean);
    
          _sendMessage(message);
    
          jumpToBottom(100);
        }
      }
    
      Widget getEmojiWidget(){
    
        return SizedBox(
          height: 200.0,
          width: 1000.0,
          child: EmojiPicker(
              onEmojiSelected: (Category category, Emoji emoji) {
                _onEmojiSelected(emoji);
              },
              onBackspacePressed: _onBackspacePressed,
              config: const Config(
                  columns: 7,
                  emojiSizeMax: 25.0,
                  verticalSpacing: 0,
                  horizontalSpacing: 0,
                  initCategory: Category.RECENT,
                  bgColor: Color(0xFFF2F2F2),
                  indicatorColor: Color(0xff65DAC5),
                  iconColor: Colors.orange,
                  iconColorSelected: Color(0xff65DAC5),
                  progressIndicatorColor: Color(0xff65DAC5),
                  backspaceColor: Color(0xff65DAC5),
                  showRecentsTab: true,
                  recentsLimit: 28,
                  categoryIcons: CategoryIcons(),
                  buttonMode: ButtonMode.MATERIAL)),
        );
      }
    
    
    }

    group_chat_content_view.dart

    /**
     * Author : wangning
     * Email : maoning20080809@163.com
     * Date : 2022/11/6 19:46
     * Description : 群聊
     */
    class GroupChatContentView extends StatefulWidget {
    
      final List items;
      final GroupChatBean groupChatBean;
      final int index;
      final String? otherAccount;
      final UserBean? meUserBean;
      final String account;
      final deleteCallback;
      final List? addTimeList;
      //点击语音播放回调
      final clickVoiceCallback;
    
      //点击领取转账,刷新页面
      final refreshTransfer;
    
      GroupChatContentView({required this.items,  required this.account, required this.groupChatBean, required this.index,
        required this.meUserBean, required this.otherAccount, this.addTimeList, required this.deleteCallback, required this.clickVoiceCallback, required this.refreshTransfer});
    
      @override
      State createState() => _GroupChatContentViewState();
    
    }
    
    
    class _GroupChatContentViewState extends State {
    
      UserBean? otherUserBean;
    
      @override
      void initState() {
        super.initState();
        _loadOtherUserBean();
      }
    
      void _loadOtherUserBean() async {
        otherUserBean = await UserRepository.getInstance().findUserByAccount(widget.otherAccount??"");
        setState(() {
    
        });
      }
    
      void goNewFriends(String account) async{
        UserBean? userBean = await UserRepository.getInstance().findUserByAccount(account);
        if(userBean != null){
          Navigator.push(context,MaterialPageRoute(builder: (context)=>AddFriends(userBean: userBean!,)));
        } else {
          userBean = await UserRepository.getInstance().getUserServer(account);
          Navigator.push(context,MaterialPageRoute(builder: (context)=>AddFriends(userBean: userBean!,)));
        }
      }
    
      @override
      Widget build(BuildContext context) {
    
        String addTimeResult = _getAddTime("${widget.groupChatBean.addTime}");
        bool isExistTime = isExistAddTime(addTimeResult);
        if(!isExistTime){
          widget.addTimeList?.add(addTimeResult);
        }
        //如果是最后一个,清除标志
        if(widget.index == widget.items.length -1){
          widget.addTimeList?.clear();
        }
        return Column(
          children: [
            Offstage(
              offstage: isExistTime,
              child: Container(
                margin: EdgeInsets.only(top: 12),
                child: Text("${addTimeResult}"),
              ),
            ),
    
            Container(
              child: widget.account == widget.groupChatBean.account
                  ? fromAccountWidget()
                  : toAccountWidget(),
            )
          ],
        );
      }
    
      //小视频缩略图
      Widget getCommonThumbnail(int second){
        return CommonThumbnailWidget(
            padding: EdgeInsets.only(
                top: 0.0,
                right: (widget.account == widget.groupChatBean.account ? 0.0 : 5.0),
                left: (widget.account == widget.groupChatBean.account ? 2.0 : 0.0)),
            image: widget.groupChatBean.content??"",
            second: second,
            onPressed: () {
              Navigator.push(context, MaterialPageRoute(builder: (context) => VideoPlayLocalPreview(widget.groupChatBean.localMediaUrl!)));
            });
      }
    
      //显示我的
      Widget fromAccountWidget(){
        return Container(
          margin: EdgeInsets.only(top: 8.0, left: 68.0, right: 8),
          padding: EdgeInsets.all(2.0),
          child: Row(
            children: [
              Expanded(
                child: GestureDetector(
                  onLongPress: (){
                    _showDeleteDialog(widget.groupChatBean);
                  },
                  onTap: () {
                  },
                  child: Stack(
    
                    alignment: AlignmentDirectional.bottomEnd,
                    children: [
                      Offstage(
                        offstage: !(widget.groupChatBean.contentType == CommonUtils.CHAT_CONTENT_TYPE_TEXT),
                        child: Column(
                          // Column被Expanded包裹起来,使其内部文本可自动换行
                          crossAxisAlignment: CrossAxisAlignment.end,
                          children: [
                            Container(
                              padding: EdgeInsets.symmetric(vertical: 8.0, horizontal: 10.0),
                              decoration: BoxDecoration(borderRadius: BorderRadius.all(Radius.circular(5.0),),color: Color(0xFF9EEA6A),),
                              child: Text(
                                widget.groupChatBean.content??"",
                                textAlign: TextAlign.left,
                                style: TextStyle(color: Colors.black, fontSize: 20.0),
                              ),
                            )
                          ],
                        ),
                      ),
                      Offstage(
                        offstage: !(widget.groupChatBean.contentType == CommonUtils.CHAT_CONTENT_TYPE_VOICE),
                        child: InkWell(
                            onTap: () {
                              widget.clickVoiceCallback(true);
                              setState(() {
                                widget.groupChatBean.isPlayVoice = true;
                              });
                              //点击语音
                              AudioPlayer.getInstance().playLocal(widget.groupChatBean.localMediaUrl??"", callback: (data){
                                //录音回调
                                setState(() {
                                  widget.groupChatBean.isPlayVoice = false;
                                });
                              });
                            },
                            child : Container(
                              width: 120,
                              height: 40,
                              padding: EdgeInsets.symmetric(vertical: 4.0, horizontal: 2.0),
                              decoration: BoxDecoration(borderRadius: BorderRadius.all(Radius.circular(1.0),),color: Color(0xFF9EEA6A),),
                              child: Row(
                                crossAxisAlignment: CrossAxisAlignment.center,
                                mainAxisAlignment: MainAxisAlignment.center,
                                children: [
                                  Text("${widget.groupChatBean.second}''"),
                                  SizedBox(width: 4,),
                                  widget.groupChatBean.isPlayVoice?Image.asset("assets/chat/wn_chat_me_animator.gif", height: 24,):Image.asset("assets/chat/wn_chat_me_volume_3.png", height: 24,),
                                ],
                              ),
                            )
                        ),
                      ),
                      Offstage(
                        offstage: !(widget.groupChatBean.contentType == CommonUtils.CHAT_CONTENT_TYPE_IMG),
                        child: CommonUtils.showGroupChatImage(widget.groupChatBean.serverMediaUrl??"", widget.groupChatBean.localMediaUrl??"", width:100, height:200, angle:1, onPressed: (data){
                          Navigator.push(context,MaterialPageRoute(builder: (context)=>CommonImagePreview(fileName: data)));
                        }),
                      ),
                      widget.groupChatBean.contentType == CommonUtils.CHAT_CONTENT_TYPE_VIDEO?getCommonThumbnail(widget.groupChatBean.second??0):SizedBox(),
                      
                    ],
                  ),
                ),
              ),
              //userImage
              Container(
                padding: EdgeInsets.only(left: 6, right: 6),
                child: GestureDetector(
                  onTap: (){
                    //Navigator.push(context,MaterialPageRoute(builder: (context)=>ContactsDetails(toChatId: widget.chatBean.fromAccount??"")));
                  },
                  child: CommonAvatarView.showBaseImage(widget.meUserBean?.avatar??"", 38, 38),
                ),
              ),
    
            ],
          ),
        );
      }
    
      //显示好友
      Widget toAccountWidget(){
        return Container(
          margin: EdgeInsets.only(top: 8.0, right: 68.0),
          padding: EdgeInsets.all(2.0),
          child: Row(
            //crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              //userImage,
              Container(
                margin: EdgeInsets.only(left: 6, right: 6),
                child: GestureDetector(
                  onTap : (){
                    Navigator.push(context,MaterialPageRoute(builder: (context)=>ContactsDetails(toChatId: otherUserBean?.account??"")));
                  },
                  child: CommonAvatarView.showBaseImage(otherUserBean?.avatar??"", 38, 38),
                ),
              ),
              Expanded(
                child: GestureDetector(
    
                    onLongPress: (){
                      _showDeleteDialog(widget.groupChatBean);
                    },
                    onTap: () {
                    },
    
                    child: Stack(
                      alignment: AlignmentDirectional.centerStart,
                      children: [
                        Offstage(
                          offstage: !(widget.groupChatBean.contentType == CommonUtils.CHAT_CONTENT_TYPE_TEXT),
                          child: Column(
                            crossAxisAlignment: CrossAxisAlignment.start,
                            children: [
                              Container(
                                padding: EdgeInsets.symmetric(vertical: 8.0, horizontal: 10.0),
                                decoration: BoxDecoration(borderRadius: BorderRadius.all(Radius.circular(5.0),),color: Color(0xFFEDEDED)),
                                child: Text(
                                  widget.groupChatBean.content??"",
                                  textAlign: TextAlign.left,
                                  style: TextStyle(color: Colors.black, fontSize: 20.0),
                                ),
                              )
                            ],
                          ),
                        ),
                        Offstage(
                          offstage: !(widget.groupChatBean.contentType == CommonUtils.CHAT_CONTENT_TYPE_VOICE),
                          child: InkWell(
                              onTap: () {
                                setState(() {
                                  widget.groupChatBean.isPlayVoice = true;
                                });
                                LogUtils.d("点击语音");
                                AudioPlayer.getInstance().playLocal(widget.groupChatBean.localMediaUrl??"", callback: (data){
                                  LogUtils.d("录音回调:${data}");
                                  setState(() {
                                    widget.groupChatBean.isPlayVoice = false;
                                  });
                                });
                              },
                              child : Container(
                                width: 120,
                                height: 40,
                                padding: EdgeInsets.symmetric(vertical: 4.0, horizontal: 2.0),
                                decoration: BoxDecoration(borderRadius: BorderRadius.all(Radius.circular(5.0),),color: Color(0xFFEDEDED)),
                                child: Row(
                                  crossAxisAlignment: CrossAxisAlignment.center,
                                  mainAxisAlignment: MainAxisAlignment.center,
                                  children: [
                                    widget.groupChatBean.isPlayVoice?Image.asset("assets/chat/wn_chat_other_animator.gif", height: 34,):Image.asset("assets/chat/wn_chat_other_volume_3.png",  height: 34,),
                                    SizedBox(width: 4,),
                                    Text("${widget.groupChatBean.second}''"),
                                  ],
                                ),
    
                              )
                          ),
                        ),
                        Offstage(
                          offstage: !(widget.groupChatBean.contentType == CommonUtils.CHAT_CONTENT_TYPE_IMG),
                          child: CommonUtils.showGroupChatImage(widget.groupChatBean.serverMediaUrl??"", widget.groupChatBean.localMediaUrl??"",  width:100, height:200, angle:1, onPressed: (data){
                            Navigator.push(context,MaterialPageRoute(builder: (context)=>CommonImagePreview(fileName: data)));
                          }),
                        ),
    
                        widget.groupChatBean.contentType == CommonUtils.CHAT_CONTENT_TYPE_VIDEO?getCommonThumbnail(widget.groupChatBean.second??0):SizedBox(),
                      ],
                    )
                ),
              ),
              /**/
            ],
          ),
        );
      }
    
      bool isExistAddTime(String addTimeResult){
        return widget.addTimeList?.contains(addTimeResult)??false;
      }
    
      String _getAddTime(String addTime){
        return WnTimeUtils.timeUtils(startTime:  addTime);
      }
    
      //删除对话框
      Future _showDeleteDialog(GroupChatBean groupChatBean) async {
        return showDialog(
            context: context,
            barrierDismissible: false,
            builder: (BuildContext context) {
              return AlertDialog(
                title: Text('确定要删除该消息吗?', style: new TextStyle(fontSize: 17.0)),
                actions: [
                  MaterialButton(
                    child: Text('取消'),
                    onPressed: (){
                      LogUtils.d("确定取消");
                      Navigator.of(context).pop();
                    },
                  ),
                  MaterialButton(
                    child: Text('确定'),
                    onPressed: (){
                      LogUtils.d("确定删除");
                      Navigator.pop(context);
                      _deleteChatBean(groupChatBean);
                    },
                  )
                ],
              );
            }
        );
      }
    
      //删除消息
      _deleteChatBean(GroupChatBean groupChatBean) async{
        int id = groupChatBean.id??0;
        await ChatRepository.getInstance().deleteChatById(id);
        widget.deleteCallback(true);
      }
    
    }

  • 相关阅读:
    Ubuntu快速安装MSF命令
    Flash驱动控制--芯片擦除(SPI协议)
    Synchronized同步锁
    养老院IPTV数字电视系统方案-养老公寓康养社区IPTV电视系统建设指南
    电脑中vcruntime140.dll丢失的四种修复方法,一键修复dll修复方法
    zernike相衬显微镜、图像矩、zernike多项式和像差
    react-demo项目:纯零搭建react项目(不用create-react-app脚手架)
    把 Maven 提交到项目?Maven Wrapper的使用与好处
    【TWS API 问题2】如何用盈透证券的TWS API持续获取5分钟K线的问题?
    YOLOv2-yolo9000-batter,faster,stronger 论文精度
  • 原文地址:https://blog.csdn.net/maoning20080808/article/details/128036412