Flutter笔记电商中文货币显示插件 Money Display
1. 概述与入门
Money Display就是一款用于中文货币显示的插件。在Money Display中你可以定制每一个中文货币构成部分的样式、符号:
项目
项目主页(pub.dev):https://pub.dev/packages/money_display
仓库地址(Github):https://github.com/jacklee1995/flutter_money_display/blob/master/README.md
仓库地址(国内):http://thispage.tech:9680/jclee1995/flutter_money_display/-/blob/master/README_CN.md
概述
在电商项目中,经常需要显示货币比如:
实战中的电商应用货币显示有一些繁琐,比如需要在数字中插入逗号分隔符、需要判断金额数量级,为大的数量级添加单位(比如超过10000时添加万字),处理超出最大金额显示,考虑数位的保留,处理小数点后多余的0,等等。
我为此做了一个小模块,用于自动处理这些问题,没有特殊需求的情况下,可以仅仅传入一个double数,就像这样:
ChineseMoneyDisplayWidget(99.89)
这将替代你自己实现这些繁琐的数字和字符串处理。如果有需要,你可以通过考虑传入不同参数以指定更多的样式。
安装方式
可以直接通过Flutter的pub工具安装:
flutter pub add money_display
这将向你的包的 pubspec.yaml 文件中添加一行(并运行一个隐式的flutter pub get):
dependencies: money_display: ^1.0.0+1
2. 工作方式
本模块提供了一个 ChineseMoneyDisplayWidget
组件旨在将货币金额显示为中国货币格式,例如 “¥123,456.78”,并提供了一些自定义选项来满足不同的需求。
以下是本模块显示货币的大概逻辑:
- 构造函数参数:
ChineseMoneyDisplayWidget
构造函数接受多个参数,包括货币金额(price
)以及用于自定义显示的各种选项,如整数位字体大小、小数位字体大小、最大数字、溢出符号等。 - 格式化价格:
_formatPrice
方法负责将传入的price
格式化为富文本(TextSpan
)。首先,它将价格转换为字符串并使用正则表达式分离整数部分和小数部分。 - 处理大数值:如果价格大于等于
maxNum
,则显示overflowSymbol
,通常是表示无限大的符号。如果价格小于maxNum
,则继续处理。 - 处理大于一万的价格:如果价格大于一万,整数部分会被分隔成整数部分和小数部分(如果有的话)。如果没有小数部分,直接添加 “万” 符号。如果有小数部分,将整数部分和小数部分一同显示,整数部分后跟 “万” 符号。
- 处理大于一千的价格:如果价格大于一千,整数部分会被格式化,千位之间会添加逗号分隔符。处理方式与上述类似,根据是否有小数部分,显示整数部分、小数部分和 “万” 符号。
- 处理小于一千的价格:对于小于一千的价格,整数部分不添加逗号分隔符,而是根据是否有小数部分来显示整数部分、小数部分和 “万” 符号。
- 处理小数位:如果价格有小数部分,它将被显示,小数部分会根据
smallFontsize
和decimalDigitColor
进行样式设置。 - 整合文本:所有这些文本片段都会被整合到一个
TextSpan
中,以便一起显示。 - 构建富文本:在
build
方法中,富文本的一部分是currencySymbol
,它位于货币符号的前面。然后,_formatPrice
返回的富文本部分在RichText
组件中显示。整个组件就是在屏幕上显示这个富文本。
通过这种逻辑,ChineseMoneyDisplayWidget
组件能够将输入的价格以中国货币格式显示出来,并根据所提供的参数进行自定义样式。这使得开发人员能够轻松地将其集成到Flutter应用中以满足不同的货币显示需求。
3. 一个示例
import 'package:flutter/material.dart'; import 'package:money_display/money_display.dart'; void main() { runApp(const MoneyDisplayExample()); } class MoneyDisplayExample extends StatelessWidget { const MoneyDisplayExample({super.key}); @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar( title: const Text('Money Display 示例'), ), body: const Center( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ ChineseMoneyDisplayWidget(0.9), ChineseMoneyDisplayWidget(0.17), ChineseMoneyDisplayWidget(0.1796), ChineseMoneyDisplayWidget(6), ChineseMoneyDisplayWidget(6.1), ChineseMoneyDisplayWidget(9.16), ChineseMoneyDisplayWidget(9.1671), ChineseMoneyDisplayWidget(10), ChineseMoneyDisplayWidget(10.7), ChineseMoneyDisplayWidget(10.71), ChineseMoneyDisplayWidget(999), ChineseMoneyDisplayWidget(999.7), ChineseMoneyDisplayWidget(999.99), ChineseMoneyDisplayWidget(1000), ChineseMoneyDisplayWidget(1995.0), ChineseMoneyDisplayWidget(1995.07), ChineseMoneyDisplayWidget(6666.66), ChineseMoneyDisplayWidget(9999), ChineseMoneyDisplayWidget(99999), ChineseMoneyDisplayWidget(999999), ChineseMoneyDisplayWidget(996786), ChineseMoneyDisplayWidget(9999999), // maxNum 默认值为10000 ChineseMoneyDisplayWidget( 9999999, maxNum: 10000001, ), ChineseMoneyDisplayWidget( 9999999.97, maxNum: 10000001, integerColor: Colors.blue, integerFontsize: 25, decimalFontsize: 21, currencySymbolColor: Colors.pink, tenThousandSymbol: 'w', tenThousandSymbolColor: Colors.limeAccent, ), ], ), ), ), ); } }
效果如下:
4. 接口
/// 创建一个新的[ChineseMoneyDisplayWidget]实例 /// /// [price]是要显示的价格,[integerFontsize]和[decimalFontsize]分别表示整数位和小数位的字体大小 /// /// [maxNum]是一个可选参数,表示允许的最大数字,超过此数字将显示[overflowSymbol] /// /// [overflowSymbol]是一个可选参数,用于表示超过最大数字时显示的符号,默认为"-" /// /// [tenThousandSymbol]是一个可选参数,用于分隔万位的文本,默认为"万" /// /// [currencySymbol]是一个可选参数,表示货币符号,默认为"¥" /// /// [tenThousandSymbolColor]、[currencySymbolColor]、[overflowSymbolColor]是可选参数, /// 分别表示万字单位符号、货币符号和溢出符号的颜色,默认为红色 const ChineseMoneyDisplayWidget( this.price, { super.key, this.integerFontsize = 18, this.decimalFontsize = 15, this.tenThousandSymbolSize = 15, this.currencySymbolFontsize = 15, this.maxNum = 1000000, this.overflowSymbol = '-', this.tenThousandSymbol = '万', this.currencySymbol = '¥', this.tenThousandSymbolColor = Colors.red, this.integerColor = Colors.red, this.decimalDigitColor = Colors.red, this.currencySymbolColor = Colors.red, this.overflowSymbolColor = Colors.red, this.integerFontWeight = FontWeight.normal, this.decimalFontWeight = FontWeight.normal, this.tenThousandSymbolWeight = FontWeight.normal, this.currencyFontWeight = FontWeight.normal, });