Flutter高仿微信-第50篇-群聊-查看群成员

news2025/2/27 14:02:34

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

 详情请查看

效果图:

实现代码:

import 'package:flutter/material.dart';
import 'package:wnchat2/bean/groupchat/group_bean.dart';
import 'package:wnchat2/bean/groupchat/group_user_bean.dart';
import 'package:wnchat2/common/common_utils.dart';
import 'package:wnchat2/common/sp_utils.dart';
import 'package:wnchat2/common/wn_app_bar.dart';
import 'package:wnchat2/event/base_event.dart';
import 'package:wnchat2/groupchat/group_update_name.dart';
import 'package:wnchat2/main/contacts_details_page.dart';
import 'package:wnchat2/repository/group_chat_repository.dart';
import 'package:wnchat2/repository/group_repository.dart';
import 'package:wnchat2/repository/user_repository.dart';
import 'package:wnchat2/routers/routers.dart';
import 'package:wnchat2/utils/loading_dialog_utils.dart';

import '../bean/user/userbean.dart';
import '../common/event_bus_utils.dart';
import '../manager/app_manager.dart';
import '../repository/group_user_repository.dart';
import '../utils/log_utils.dart';
import 'show_group_member_item.dart';

/**
 * Author : wangning
 * Email : maoning20080809@163.com
 * Date : 2022/11/6 19:46
 * Description : 显示群成员
 */

class ShowGroupMember extends StatefulWidget{

  String groupId;

  ShowGroupMember({required this.groupId});

  @override
  State<StatefulWidget> createState() => _ShowGroupMemberState();

}

class _ShowGroupMemberState extends State<ShowGroupMember>{

  GroupBean? _groupBean;
  List<GroupUserBean> _groupUserList = [];
  bool isLoading = false;
  String account = SpUtils.getString(CommonUtils.LOGIN_ACCOUNT);

  //每个个数宽度
  double itemWidth = 44;
  //显示个数
  int gridCount = 5;

  @override
  void initState() {
    super.initState();
    LogUtils.d("show_group_member 跳转的群id:${widget.groupId}");

    _getData();
  }

  _getData() async {
    _groupBean = await GroupRepository.getInstance().findGroupByGroupId(widget.groupId);
    _groupUserList = await GroupUserRepository.getInstance().findAllGroupUserByGroupId(widget.groupId)??[];
    itemWidth = AppManager.getInstance().getWidth(context) / gridCount;

    //如果群成员不是好友,先下载群成员个人信息到本地数据库
    for(int i = 0; i < _groupUserList.length; i++){
      GroupUserBean groupUserBean = _groupUserList[i];
       UserBean? localUserBean = await UserRepository.getInstance().findUserByAccount(groupUserBean.account??"");
        LogUtils.d("成员列表:${groupUserBean.toJson()} ");
       if(localUserBean == null){
         UserBean userBean = await UserRepository.getInstance().getUserServer(groupUserBean.account??"");
         UserRepository.getInstance().insertUserLocal(userBean);
       }
    }

    setState(() {
      //尾部+号
      _groupUserList?.add(GroupUserBean());
    });
  }

  //修改群名
  void _updateGroupName(){
    bool isOwner = false;
    for(int i = 0; i< _groupUserList.length; i++){
      GroupUserBean groupUserBean = _groupUserList[i];
      LogUtils.d("是否账号:${account}, ${groupUserBean.toJson()}");
      if(account == groupUserBean.account &&
          (groupUserBean.accountType == GroupUserBean.ACCOUNT_TYPE_OWNER||
              groupUserBean.accountType == GroupUserBean.ACCOUNT_TYPE_ADMIN)){
        LogUtils.d("选择的账号:${account}, ${groupUserBean.toJson()}");
        isOwner = true;
        break;
      }
    }
    LogUtils.d("是否成员:${isOwner}");
    if(isOwner){
      Navigator.push(context, MaterialPageRoute(builder: (context) => GroupUpdateName(groupId: widget.groupId)));
    } else {
      LoadingDialogUtils.showTipDialog(context, msg : "当前群聊仅群主/群管理员可以修改群聊名称");
    }

  }

  //删除并退出对话框
  void _deleteAndExistDialog(){
    LoadingDialogUtils.showBaseDialog(context, msg: "确定要删除并退出吗?", clickConfirm: (){
      _deleteAndExist();
    }, clickCancel: (){
    });
  }

  //删除并退出
  void _deleteAndExist() async {
    LoadingDialogUtils.showLoadingContentDialog(context);

    String account = SpUtils.getAccount();
    List<String> members = [account];
    GroupUserBean? groupUserBean =  await GroupUserRepository.getInstance().findGroupUserByAccountAndGroupId(account, widget.groupId);
    //清空群聊信息
    await GroupChatRepository.getInstance().deleteAllGroupChatByGroupId(widget.groupId);
    //删除群聊用户
    await GroupUserRepository.getInstance().deleteGroupUserByGroupId(account, widget.groupId);

    await GroupUserRepository.getInstance().deleteGroupUserByGroupIdAndAccountServer(account, widget.groupId);

    
    LoadingDialogUtils.dimissLoadingDialog(context);

    Navigator.popUntil(context, (route) {return route.isFirst;});
  }

  //清空聊天记录对话框
  void _cleanGroupChatDialog(){
    LoadingDialogUtils.showBaseDialog(context, msg: "确定要清空聊天记录吗?", clickConfirm: (){
      _cleanGroupChat();
    }, clickCancel: (){
    });
  }

  //清空聊天记录
  void _cleanGroupChat(){
    GroupChatRepository.getInstance().deleteAllGroupChatByGroupId(widget.groupId);
    //刷新聊天页面
    eventBus.emit(BaseEvent(BaseEvent.TYPE_REFRESH_GROUP, result: HashMap<String, Object>()));
    Navigator.pop(context);
  }

  @override
  Widget build(BuildContext context) {

    return Scaffold(
      appBar: WnAppBar.getAppBar(context, Text("聊天信息(${_groupUserList.length -1 })")),

      body: Column(
        children: [
          SizedBox(height: 10,),
          getImageGridView(),
          lineWidget(),
          updateGroupName(),
          lineWidget(),
          SizedBox(height: 50,),
          cleanGroupChat(),
          lineWidget(),
          deleteAndExist(),
          lineWidget(),
          SizedBox(height: 10,),
        ],
      ),
    );
  }

  //显示图片九宫格
  Widget getImageGridView(){
    return Expanded(
        child:GridView.builder(
          gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: gridCount,childAspectRatio: 1,),
          itemCount: _groupUserList.length,
          itemBuilder: (context, index){
            return InkWell(
              onTap: (){
                Navigator.push(context,MaterialPageRoute(builder: (context)=>ContactsDetails(toChatId: _groupUserList[index].account??"")));
              },
              child: Container(
                alignment: Alignment.center,
                margin: EdgeInsets.only(left: 3, top: 6, right: 3, bottom: 6),
                child: showAvatarWidget(index),
              ),
            );
          },
        )
    );
  }

  //修改群名称
  Widget updateGroupName() {
    return Row(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        Expanded(
          child: InkWell(
            onTap: (){
              _updateGroupName();
            },
            child: Container(
              color: Colors.grey.shade300,
              child: Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: <Widget>[
                  Container(
                    margin: EdgeInsets.only(bottom: 15.0, top: 15, left: 12),
                    child: Text("群聊名称",style: TextStyle(fontSize: 22, color: Colors.black, fontWeight: FontWeight.bold),),
                  ),
                  Expanded(child: Text("")),
                  Container(
                    margin: EdgeInsets.only(bottom: 15.0, top: 15, right: 8),
                    child: Text("${_groupBean?.groupName}",style: TextStyle(fontSize: 22, color: Colors.grey.shade800),),
                  ),
                  Container(
                    margin: EdgeInsets.only(top:15, bottom: 15.0, right: 10.0),
                    child: Icon(Icons.chevron_right,color: Colors.grey,),
                  ),
                ],
              ),
            ),
          ),
        ),
      ],
    );
  }


  //清空聊天记录
  Widget cleanGroupChat(){
    return InkWell(
      onTap: (){
        _cleanGroupChatDialog();
      },
      child: Container(
        width: double.infinity,
        alignment: Alignment.center,
        margin: const EdgeInsets.only(top: 12, bottom: 12),
        child: const Text("清空聊天记录", style: TextStyle(fontSize: 20, color: Colors.red, fontWeight: FontWeight.bold),),
      ),
    );
  }

  //删除并退出
  Widget deleteAndExist(){
    return InkWell(
      onTap: (){
        _deleteAndExistDialog();
      },
      child: Container(
        width: double.infinity,
        alignment: Alignment.center,
        margin: EdgeInsets.only(top: 12, bottom: 12),
        child: const Text("删除并退出", style: TextStyle(fontSize: 20, color: Colors.red, fontWeight: FontWeight.bold),),
      ),
    );
  }

  Widget lineWidget() {
    return Container(
      width: double.infinity,
      height: 0.5,
      color: Colors.grey.shade300,
    );
  }

  //显示头像,最后一个显示加号图标
  Widget showAvatarWidget(int index){
    if(index == _groupUserList.length -1){
      //加号
      return InkWell(
        onTap: (){
          Navigator.pushNamed(context, Routes.add_group_member, arguments: {
            "groupId":widget.groupId  //参数map
          });
        },
        child: CommonUtils.getBaseIconPng("wc_group_chat_add"),
      );
    } else {
      GroupUserBean groupUserBean = _groupUserList[index];
      return ShowGroupMemberItem(groupUserBean: groupUserBean);
    }

  }


}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Node.js 入门教程 7 从命令行运行 Node.js 脚本 8 如何退出 Node.js 程序

Node.js 入门教程 Node.js官方入门教程 Node.js中文网 本文仅用于学习记录&#xff0c;不存在任何商业用途&#xff0c;如侵删 文章目录Node.js 入门教程7 从命令行运行 Node.js 脚本8 如何退出 Node.js 程序7 从命令行运行 Node.js 脚本 运行 Node.js 程序的常用方法是&#…

【点云处理】点云法向量估计及其加速(5)

在上一篇文章【点云处理】点云法向量估计及其加速(4)中我们尝试对pcl自带的KDTree的k近邻搜索过程使用OpenMP加速&#xff0c;效果比较明显&#xff0c;有将近1倍的提速。在这篇文章中我们暂时放弃pcl自带的KDTree&#xff0c;转而使用另一大杀器nanflann库提供的KDTree。nanof…

玩链子游戏

一 游戏描述 有一条链子&#xff0c;上面有 n 颗钻石&#xff0c;钻石编号为 1&#xff5e;n 。可以对该链子执行两种操作&#xff1a; ① CUT a b c &#xff08;区间切割操作&#xff09; 切下从第 a 颗钻石到第 b 颗钻石的链子&#xff0c;把它插在剩余链子的第 c 颗钻石…

【食品加工技术】第五章 烘烤食品加工技术 笔记

【食品加工技术】第五章 烘烤食品加工技术 笔记5.1 焙烤食品概述烘烤食品的分类按发酵和膨化程度分类安装生产工艺分类烘烤食品的原料面粉糖蛋品乳及乳制品膨松剂烘烤设备常用设备恒温设备常用工具5.2 面包加工工艺和关键技术面包的分类面包的发酵原理面包的工艺流程一次发酵二…

uboot引导应用程序

uboot默认是支持执行应用程序的&#xff0c;就像引导内核一样&#xff0c;我们也可以自己写一个应用程序&#xff0c;让uboot启动时引导。 在uboot examples/standalone 目录下&#xff0c;有hello_world.c文件&#xff0c;编译uboot的时候&#xff0c;会自动编译hello_world.…

详解 InnoDB Cluster 主机名问题

详解 InnoDB Cluster 主机名问题 文章目录详解 InnoDB Cluster 主机名问题导言测试过程结论导言 因在写 【InnoDB Cluster】修改已有集群实例名称及成员实例选项 时发现主机名这块有一些问题&#xff0c;在其中进行了部分测试&#xff0c;但为使其内容精简&#xff0c;故将此部…

程序员必知的三款在线绘图工具

文章目录2.draw.io3.Lucidchart4.PrcessOn5.小结正所谓“一图胜千言”&#xff0c;无论是商务办公、PPT 演示、学习总结、技术交流、项目开发&#xff0c;我们常常都需要制作一些图表、流程图、架构图来更直观地呈现内容以及归类整理知识点。 今天就来说下程序员们常用的三款在…

【矩阵论】正规方程——生成子空间

5.1 子空间 5.1.1. 定义 设 W⊂CnW\subset C^nW⊂Cn &#xff0c;即子空间对线性组合封闭 若(1)对∀α,β∈W&#xff0c;有αβ∈W(对加法封闭)(2)对∀α∈W,∀k∈C&#xff0c;有kα∈W(对数乘封闭)\begin{aligned} 若 &(1)对\forall \alpha,\beta\in W&#xff0c;有\…

秋招失利,拿到这份“Java 高分指南(25 专题)”,金三银四翻盘有望

面试造火箭&#xff0c;工作拧螺丝&#xff01;金九银十灰溜溜地落榜&#xff0c;备受打击。正当准备明年金三银四之际&#xff0c;意外喜提朋友赠送的这“Java 高分指南&#xff08;25 专题&#xff09;”&#xff1a;Elasticsearch、微服务、Linux、JavaOOP、集合/泛型、Mysq…

Flutter高仿微信-第57篇-添加好友

Flutter高仿微信系列共59篇&#xff0c;从Flutter客户端、Kotlin客户端、Web服务器、数据库表结构、Xmpp即时通讯服务器、视频通话服务器、腾讯云服务器全面讲解。 详情请查看 效果图&#xff1a; 实现代码&#xff1a; /*** Author : wangning* Email : maoning20080809163.c…

ThreadLocal

文章目录一、ThreadLocal是什么二、ThreadLocal作用三、ThreadLocal的设计结构早期:现在:四、ThreadLocal核心方法1. set方法2. get方法3. remove方法五、ThreadLocal内存泄漏六、使用场景七、参考资料前言&#xff1a; 再写博客时&#xff0c;遇到了如何处理保存用户的信息时出…

基于共享储能电站的工业用户 日前优化经济调度matlab程序(yalmip+cplex)(yalmip+gurobi)

基于共享储能电站的工业用户 日前优化经济调度matlab程序&#xff08;yalmipcplex&#xff09;&#xff08;yalmipgurobi&#xff09; 参考文献&#xff1a;基于共享储能电站的工业用户 日前优化经济调度 摘要: 文章提出一种基于共享储能电站的工业用户日前优化经济调度方法。…

nginx反向代理,负载均衡配置

文章目录一.nginx代理简介二.nginx配置简介三.nginx作为反向代理的配置四.nginx作为负载均衡的配置五.使用nginx代理的坑一.nginx代理简介 其实nginx作为代理有两种 正向代理: 隐藏客户端的信息;如科学上网 反向代理: 隐藏服务端的信息;如负载均衡 二.nginx配置…

11.26

目录 一.做题出错 1. 2.数组长度的一半 3.选择题 二.优先级队列(堆) 1.二叉树的顺序存储 1.1 存储方式 1.2下标关系 2.堆(heap) 2.1概念 2.2 操作-向下调整 三 建堆 四.优先级队列 1 概念 2 内部原理 3.操作-入队 offer() 4.操作-出队 五.计算糖果 一.做题出错…

docker如何下载国外镜像

目录背景解决方案1、创建阿里云镜像仓库2、使用https://labs.play-with-docker.com下载镜像3、将镜像上传到阿里云镜像仓库4、从阿里云镜像仓库中拉取镜像到我们linux系统中5、改变我们linux系统中拉取的镜像名称背景 今天在安装grafana和prometheus&#xff0c;但是在下载下面…

Java数据结构

目录 1、栈 2、队列 3、数组 4、链表 5、树 7、平衡二叉树 8、红黑树 1、栈 特点&#xff1a;先进后出&#xff0c;后进先出 数据进入栈模型的过程称为:压/进栈 数据离开栈模型的过程称为:弹/出栈 2、队列 特点&#xff1a;先进先出&#xff0c;后进后出 数据从后…

MyBatis-Plus中的更新操作(通过id更新和条件更新)

目录 前言 一、通过id更新 二、条件更新 2.1 使用QueryWrapper进行条件更新 2.2 使用UpdateWrapper进行条件更新 总结 前言 本文学习MP中的更新操作方法&#xff0c;带大家一起查看源码&#xff0c;了解更新操作的方法。学会熟练地去运用更新方法解决自己在项目中的问题…

Linus 文件处理(三)

目录 一、前言 二、扫描目录 1、opendir 2、readdir 3、telldir 4、seekdir 5、 closedir 6、A Directory-Scanning Program 三、Errors 1、strerror 2、perror 一、前言 本文将简单介绍Linux文件和目录&#xff0c;以及如何操作它们&#xff08;如何创建文件、打开…

独家 | 使用python马尔科夫链方法建模星巴克等待时长

作者&#xff1a;Piero Paialunga翻译&#xff1a;陈超校对&#xff1a;和中华本文约4200字&#xff0c;建议阅读11分钟本文使用马尔科夫链的方法对星巴克购买咖啡的等待时长进行建模。以下内容关于如何使用马尔科夫链计算你在星巴克咖啡的等待时长。图片来自Unplash&#xff0…

Spring - ApplicationContextInitializer 扩展接口

文章目录Preorg.springframework.context.ApplicationContextInitializer扩展点扩展接口扩展生效方式方式一 &#xff1a; Spring SPI扩展方式二 &#xff1a; 配置文件方式三 &#xff1a;启动类手工add测试结果Pre Spring Boot - 扩展接口一览 org.springframework.context.…