Flutter高仿微信-第38篇-单聊-转账

news2025/8/3 22:02:03

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

 详情请查看

效果图:

详情请参考 Flutter高仿微信-第29篇-单聊 , 这里只是提取小视频的部分代码。

实现代码:

//我的转账
Widget meTransferWidget(){
  return GestureDetector(
    onTap: (){
      //点击转账
      Navigator.push(context, MaterialPageRoute(builder: (context) => TransferDetails(toUser: widget.otherUserBean?.account??"", balance: double.parse(widget.chatBean?.content??""), messageId: widget.chatBean?.messageId??"")));
    },
    child: Container(
      child: Stack(
        children: [
          meRedpacketBackground(),

          Positioned(
            left: 20, top: 20,
            child:CommonUtils.getBaseIconPng("wc_chat_transfer_icon", width: 40, height: 40),
          ),

          Positioned(
            left: 70, top: 14,
            child: Text("¥${double.parse(widget.chatBean.content??'0').toStringAsFixed(2)}", style: TextStyle(fontSize: 18, color: Colors.white, fontWeight: FontWeight.bold),),
          ),

          Positioned(
            left: 70, top: 40,
            child: Text("你发起了一笔转账", style: TextStyle(fontSize: 12, color: Colors.white, fontWeight: FontWeight.bold),),
          ),

          Positioned(
            left: 70, top: 54,
            child: Container(
              margin: EdgeInsets.only(top:10),
              width: 120,
              height: 1,
              color: Colors.white,
            ),
          ),

          Positioned(
            left: 20, bottom: 14,
            child:Text("私人转账", style: TextStyle(fontSize: 12, color: Colors.white38),),
          ),

        ],
      ),
    ),
  );
}

//朋友的转账
Widget toTransferWidget(){
  return GestureDetector(
    onTap: (){
      _processTransferDetails();
    },
    child: Opacity(
      opacity: widget.chatBean.isClick == 1 ? 0.6 :1,
      child: Container(
        child: Stack(
          children: [
            toRedpacketBackground(),

            Positioned(
              left: 42, top: 20,
              child:CommonUtils.getBaseIconPng("wc_chat_transfer_icon", width: 40, height: 40),
            ),

            Positioned(
              left: 98, top: 14,
              child: Text("¥${double.parse(widget.chatBean.content??'0').toStringAsFixed(2)}", style: TextStyle(fontSize: 18, color: Colors.white, fontWeight: FontWeight.bold),),
            ),

            Positioned(
              left: 98, top: 40,
              child: Text(widget.chatBean.isClick == 1?'已收款':'请收款', style: TextStyle(fontSize: 12, color: Colors.white, fontWeight: FontWeight.bold),),
            ),

            Positioned(
              left: 98, top: 54,
              child: Container(
                margin: EdgeInsets.only(top:10),
                width: 120,
                height: 1,
                color: Colors.white,
              ),
            ),

            Positioned(
              left: 38, bottom: 14,
              child:Text("私人转账", style: TextStyle(fontSize: 12, color: Colors.white38),),
            ),

          ],
        ),
      ),
    ),
  );
}

/**
 * Author : wangning
 * Email : maoning20080809@163.com
 * Date : 2022/11/4 16:37
 * Description : 转账详情
 */

class TransferDetails extends StatefulWidget {

  double balance;
  String messageId;
  String toUser;
  TransferDetails({required this.toUser, required this.balance, required this.messageId});

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

}

class _TransferDetailsState extends State<TransferDetails>{

  //用户信息
  UserBean? _userBean;
  ChatBean? _chatBean;
  String account = SpUtils.getAccount();
  //是否隐藏底部按钮
  bool isHideReceiveButton = true;

  //显示icon图标
  String iconPath = "wc_transfer_time";
  //收款名称提示
  String nameTip = "";

  //收款成功返回的金额
  double resultBalance = 0;

  @override
  void initState() {
    super.initState();
    _init();
  }

  void _init() async {
    _userBean = await UserRepository.getInstance().findUserByAccount(widget.toUser);
    _chatBean = await ChatRepository.getInstance().findChatByMessageId(widget.messageId);
    if(account == widget.toUser){
      if(_chatBean?.isClick == 1){
        //已收款
        iconPath = "wc_transfer_time_complete";
        nameTip = "已收款";
        isHideReceiveButton = true;
      } else {
        //待你收款
        nameTip = "待你收款";
        iconPath = "wc_transfer_time";
        isHideReceiveButton = false;
      }
    } else {
      iconPath = "wc_transfer_time";
      nameTip = "待${_userBean?.nickName??''}收款";
      isHideReceiveButton = true;
    }
    setState(() {
    });
  }

  //处理收款
  void _processReceive(double balance) async {

    //判断网络
    bool isNetwork = await CommonNetwork.isNetwork();
    if(!isNetwork) {
      CommonUtils.showNetworkError(context);
      return;
    }

    //判断金额
    if(!CommonUtils.judgeBalance(context, "${balance}")){
      return;
    }

    LoadingDialogUtils.showLoadingDialog(context, msg: "正在加载...");

    int operator = CommonUtils.USER_OPERATOR_PLUS;
    BaseResult baseResult = await UserRepository.getInstance().updateBalanceServer(account, operator, balance);

    LoadingDialogUtils.dimissLoadingDialog(context);

    if(baseResult.isSuccess!){
      resultBalance = double.parse(baseResult.data.toString());
      UserRepository.getInstance().updateBalance(account, resultBalance);
      ChatRepository.getInstance().updateChatRedPacketStatus(widget.messageId, 1);
      _init();
    } else {
      Navigator.pop(context);
    }

  }

  @override
  Widget build(BuildContext context) {

    return WillPopScope(
        child: Scaffold(
          appBar: WnAppBar.getAppBar(context, const Text("转账"), type:WnAppBar.TYPE_TRANSFER , clickBack: (){

            Navigator.pop(context, resultBalance);
          }),

          body: Container(
            child: Column(
              children: [
                iconWidget(),
                nameWidget(),
                balanceWidget(),
                lineWidget(),
                timeWidget(),
                const Expanded(child: Text("")),
                receiveWidget(),
              ],
            ),
          ),
        ),
        onWillPop: () async {
          Navigator.pop(context, resultBalance);
          return false;
        }
    );
  }

  Widget iconWidget(){
    return Container(
      margin: EdgeInsets.only(top: 50),
      child: CommonUtils.getBaseIconPng(iconPath, width: 60, height: 60),
    );
  }

  Widget nameWidget(){
    return Container(
      margin: EdgeInsets.only(top: 20,),
      child: Text(nameTip, style: TextStyle(fontSize: 20),),
    );
  }

  Widget balanceWidget(){
    return Container(
      margin: EdgeInsets.only(top: 20),
      child: Text("¥${widget.balance}", style: TextStyle(fontSize: 30, fontWeight: FontWeight.bold),),
    );
  }

  //横线
  Widget lineWidget(){
    return Container(
      width: double.infinity,
      height: 0.5,
      margin: EdgeInsets.only(left:12, top: 30, right: 12),
      color: Colors.grey.shade600,
    );
  }

  //转账时间
  Widget timeWidget(){
    String addTime = _chatBean?.addTime??"";
    return Container(
      margin: EdgeInsets.only(left:12, top: 20, right: 12),
      child: Row(
        children: [
          Text("转账时间"),
          Expanded(child: Text("")),
          Text(addTime),
        ],
      ),
    );
  }

  //收款按钮
  Widget receiveWidget(){
    return Offstage(
      offstage: isHideReceiveButton,
      child: Container(
        margin: EdgeInsets.only(bottom: 30),
        child: ElevatedButton(
            style: ButtonStyle(
              backgroundColor: MaterialStateProperty.all(Color(0xff05C160)),
              shape: MaterialStateProperty.all(
                  RoundedRectangleBorder(borderRadius: BorderRadius.circular(30))
              ),
            ),
            onPressed: (){
              _processReceive(widget.balance);
            },
            child: Container(
              decoration: BoxDecoration(
                borderRadius: BorderRadius.all(Radius.circular(30)),
              ),
              alignment: AlignmentDirectional.center,

              width: 200,
              height: 60,
              child: Text("收款", style: TextStyle(fontSize: 22, color: Colors.white),),
            )
        ),
      ),
    );
  }

}

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

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

相关文章

【C++】Cmake使用教程(看这一篇就够了)

文章目录引言一 环境搭建二 简单入门2.1 项目结构2.2 示例源码2.3 运行查看三 编译多个源文件3.1 在同一个目录下有多个源文件3.1.1 简单版本3.1.1.1 项目结构3.1.1.2 示例代码3.1.1.3 运行查看3.1.2 进阶版本3.1.2.1 项目结构3.1.2.2 示例源码3.1.2.3 运行查看3.2 在不同目录下…

热门编程语言那么多,该选择哪个

编程语言那么多&#xff0c;该怎么选呢&#xff1f;无论是对找工作、还是打算转行新领域的同学们&#xff0c;起初都会有这样的困扰。这时候了解清楚编程语言的种类&#xff0c;到底该选哪个方向&#xff1f;将来能从事哪些岗位的工作&#xff1f;就比较重要了。与其盲目随从他…

CAS号:376364-38-4,rCRAMP (rat)

rCRAMP (rat) 是一种大鼠组织蛋白酶相关的抗菌肽&#xff0c;有助于大鼠脑肽/蛋白质提取物的抗菌活性。rCRAMP (rat) 是大鼠中枢神经系统先天免疫系统的关键参与者。rCRAMP (rat) is the rat cathelin-related antimicrobial peptide. rCRAMP (rat) contributes to the antibac…

计算机网络协议------从入门到深化

计算机网络通信 什么是通信协议 简单来说&#xff0c;通信协议就是计算机之间通过网络实现通信时事先达成 的一种“约定”&#xff1b;这种“约定”使那些由不同厂商的设备&#xff0c;不同CPU及不 同操作系统组成的计算机之间&#xff0c;只要遵循相同的协议就可以实现通 信。…

数据治理容易走进哪些误区?

在业界&#xff0c;大家都为如何做好数据治理而感到困惑。数据治理工作一定要先摸清楚数据的家底&#xff0c;规划好路线图&#xff0c;再进行决策。不然很容易走进误区中&#xff0c;无法自拔。下面总结了数据治理的7个常见误区&#xff0c;并给出一定建议&#xff0c;希望给予…

ERD Online 4.0.3_fix 元数据在线建模(免费、私有部署)

❝ 修复数据源导入的元数据&#xff0c;在没有中文注释修改的时候&#xff0c;导致表消失修复页面刷新导致404修改是否在关系图中显示的提示一键部署增加两种部署方式&#xff1a;IPPORT、DOMAIN增加手动部署方式、极大程度的实现部署定制化❞以 「root」 用户登录 Linux 主机执…

面试:dumpsys meminfo 内存信息含义

查看内存信息&#xff1a; adb shell dumpsys meminfo dumpsys meminfo显示的信息如图所示&#xff1a; 这里仅介绍我们需要重点关注的字段&#xff1a; Dalvik Heap&#xff1a;虚拟机占用的内存&#xff0c;可以理解为Java层占用的内存。Native Heap&#xff1a;Native层占…

python 循环引用的解决方法

目录 1、问题描述 2、原因 3、示例 4、解决办法 1、问题描述 编写python代码&#xff0c;运行中出现了&#xff1a;‘most likely due to a circular import ’ 这样的报错。 2、原因 循环引用问题&#xff0c;即A引用了B&#xff0c;B又引用了A&#xff0c;造成循环引用…

ctp交易接口股票怎么查询历史数据?

针对于ctp交易接口股票历史数据的查询&#xff0c;其基本原理就是利用api接口开发子系统最终就是开发完成并暴露一个标准的HTTPAPI接口&#xff0c;并将接口注册和接入到API网关。API设计和开发的核心思想仍然应该是基于领域对象建模驱动&#xff0c;通过领域对象建模很好的实现…

激光数据去畸变

机器人在使用激光雷达时必然会遇到的一个问题就是激光雷达数据去畸变。为什么会产生畸变呢&#xff0c;这是因为激光雷达产生激光数据时如果机器人在运动&#xff0c;那么就会产生运动畸变。 在ros下使用激光雷达时&#xff0c;激光数据是相对于激光本体坐标系的。画个图看下会…

【无人机】基于SDRE对NPS II无人机进行点对点(调节)控制(Matlab代码实现)

&#x1f468;‍&#x1f393;个人主页&#xff1a;研学社的博客 &#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜…

iwebsec靶场 SQL注入漏洞通关笔记1- 数字型注入

目录 文章目录 前言 第01关 数字型注入 1.源码分析 2. sqlmap渗透 总结 前言 iwebsec靶场的SQL注入关卡共13关SQL注入漏洞&#xff0c;覆盖了数字型注入、字符型注入、报错型盲注、布尔型盲注、时间型盲注以及各种过滤绕过的注入&#xff0c;外加上二次注入&#xff0c;…

Recommendation Fairness: From Static to Dynamic 阅读笔记

论文链接https://arxiv.org/abs/2109.03150v1 Section 1 引言 越来越多的推荐系统开始将推荐建模为一个马尔可夫决策过程&#xff0c;并使用强化学习来解决这个问题。从而推荐系统场景下的公平性研究便面临着一个从静态评价与一次性干预static evaluation and one-shot interv…

CSS3 动画

变形 transform 在CSS3中&#xff0c;动画效果包括3个部分&#xff1a;变形&#xff08;transform&#xff09;、过渡&#xff08;transition&#xff09;、动画&#xff08;animation&#xff09; translate()平移 transform: translateX(x);    /*沿x轴方向平移*/ tran…

(十)死信队列

死信队列1、概念2、死信产生的原因3、代码实现3.1. 流程图3.2. 消息TTL 过期3.3. 队列达到最大长度3.4. 消息被拒1、概念 某些时候由于特定的原因导致 queue 中的某些消息无法被消费&#xff0c;这样的消息如果没有 后续的处理&#xff0c;就变成了死信&#xff0c;有死信自然就…

(九)RabbitMQ交换机(Exchange)

交换机Exchange1、交换机1.1. Exchanges 概念1.2. Exchanges 的类型1.3. 无名exchange&#xff08;默认交换机&#xff09;2、临时队列3、绑定&#xff08;bindings&#xff09;4、Fanout&#xff08;发布/订阅&#xff09;5、Direct exchange、6、Topics在这里插入图片描述1、…

学生HTML个人网页作业作品 基于HTML+CSS+JavaScript明星个人主页(15页)

&#x1f389;精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业…

0105 蓝桥杯真题08

/* * 中国古代文献中&#xff0c;曾记载过“大衍数列”, 主要用于解释中国传统文化中的太极衍生原理。 * 它的前几项是&#xff1a;0、2、4、8、12、18、24、32、40、50 ... * 其规律是&#xff1a;对偶数项&#xff0c;是序号平方再除2&#xff0c;奇数项&#xff0c;是序号…

【RT-Thread Studio更新】英飞凌 PSOC62-IFX-PROTO-KIT 开发环境搭建指南

本文将介绍在 RT-Thread Studio 上如何基于 PSOC62-IFX-PROTO-KIT 开发板搭建开发环境进行开发、烧录、调试功能。开发环境搭建步骤1、PSOC62-IFX-PROTO-KIT 开发板资源包安装打开Studio&#xff0c;点击工具栏上的SDK管理器在Board_Support_Packages 找到 Infineon 下的 PSOC6…

TOWER 成就徽章 NFT 系列介绍——TOWER 生态系统的第一个灵魂通证(SBT)

2022 年 7 月&#xff0c;团队推出了成就徽章 NFT 系列&#xff0c;记录每个成员在 TOWER 生态系统中的努力。这是第一个不可转让的灵魂 NFT 系列&#xff08;SBT&#xff09;&#xff0c;代表了每个玩家的独特身份。 关于灵魂通证&#xff08;SBT&#xff09; 以太坊联合创始人…