开源鸿蒙跨平台Flutter开发:计算器合集应用
文章摘要: 开源鸿蒙跨平台社区推出了一款多功能计算器合集应用,集成房贷计算、个税计算、单位转换和健康指数等实用工具。该应用采用Flutter框架开发,支持鸿蒙OS、iOS和Android平台,界面简洁直观,提供详细计算结果和可视化图表。核心功能包括等额本息/本金房贷计算、个人所得税计算、多种单位换算以及BMI等健康指标计算。技术栈包含Dart语言、Provider状态管理和Material Des
欢迎加入开源鸿蒙跨平台社区:
https://openharmonycrossplatform.csdn.net
一、项目概述
运行效果图




1.1 应用简介
计算器合集是一款功能丰富的计算工具应用,集成了房贷计算、个税计算、单位转换、健康指数计算等多种实用计算器,一个应用解决各种计算需求。应用以专业的蓝色为主色调,象征精确与可靠,涵盖房贷计算、个税计算、单位转换、健康计算四大模块。
用户可以轻松计算房贷还款、个人所得税、单位转换、健康指数等,应用提供详细的计算结果和可视化图表,帮助用户做出更明智的决策。界面简洁直观,操作便捷,适合各种场景使用。
1.2 核心功能
| 功能模块 | 功能描述 | 实现方式 |
|---|---|---|
| 房贷计算 | 等额本息、等额本金计算 | 数学公式 |
| 个税计算 | 个人所得税计算 | 税率表 |
| 单位转换 | 长度、重量、面积等转换 | 单位换算 |
| 健康计算 | BMI、体脂率、基础代谢率 | 健康公式 |
| 货币转换 | 汇率换算 | 实时汇率 |
| 日期计算 | 日期间隔、年龄计算 | 日期处理 |
1.3 计算器类型定义
| 序号 | 计算器名称 | Emoji | 功能描述 |
|---|---|---|---|
| 1 | 房贷计算器 | 🏠 | 计算房贷还款金额 |
| 2 | 个税计算器 | 💼 | 计算个人所得税 |
| 3 | 单位转换 | 🔄 | 各种单位换算 |
| 4 | 健康计算 | 🏥 | 健康指数计算 |
| 5 | 货币转换 | 💱 | 货币汇率换算 |
| 6 | 日期计算 | 📅 | 日期相关计算 |
1.4 房贷计算类型
| 序号 | 还款方式 | 描述 | 特点 |
|---|---|---|---|
| 1 | 等额本息 | 每月还款额固定 | 前期利息多,本金少 |
| 2 | 等额本金 | 每月本金固定 | 总利息较少,前期还款压力大 |
1.5 单位转换类别
| 序号 | 类别名称 | 单位示例 |
|---|---|---|
| 1 | 长度 | 米、千米、英尺、英寸 |
| 2 | 重量 | 千克、克、磅、盎司 |
| 3 | 面积 | 平方米、公顷、亩、平方英尺 |
| 4 | 体积 | 升、毫升、立方英尺、加仑 |
| 5 | 温度 | 摄氏度、华氏度、开尔文 |
| 6 | 时间 | 秒、分钟、小时、天 |
1.6 健康计算指标
| 序号 | 指标名称 | 计算方法 | 用途 |
|---|---|---|---|
| 1 | BMI | 体重(kg)/身高(m)² | 体重指数 |
| 2 | 体脂率 | 基于性别、年龄、BMI计算 | 体脂肪比例 |
| 3 | 基础代谢率 | 基于性别、年龄、体重、身高 | 基础能耗 |
| 4 | 理想体重 | 基于身高计算 | 健康体重范围 |
1.7 技术栈
| 技术领域 | 技术选型 | 版本要求 |
|---|---|---|
| 开发框架 | Flutter | >= 3.0.0 |
| 编程语言 | Dart | >= 2.17.0 |
| 状态管理 | Provider | >= 6.0.0 |
| 图表库 | charts_flutter | >= 0.12.0 |
| 数据持久化 | shared_preferences | >= 2.0.0 |
| 设计规范 | Material Design 3 | - |
| 目标平台 | 鸿蒙OS / iOS / Android | API 21+ |
1.8 项目结构
lib/
└── main_calculator_collection.dart
├── CalculatorCollectionApp # 应用入口
├── CalculatorType # 计算器类型枚举
├── LoanCalculator # 房贷计算器
├── TaxCalculator # 个税计算器
├── UnitConverter # 单位转换
├── HealthCalculator # 健康计算器
├── CurrencyConverter # 货币转换
├── DateCalculator # 日期计算
├── CalculatorHomePage # 主页面(底部导航)
├── _buildLoanPage # 房贷页面
├── _buildTaxPage # 个税页面
├── _buildUnitPage # 单位转换页面
├── _buildHealthPage # 健康页面
├── ResultDisplayWidget # 结果显示组件
└── ChartDisplayWidget # 图表显示组件
二、系统架构
2.1 整体架构图
2.2 类图设计
2.3 页面导航流程
2.4 计算流程
三、核心模块设计
3.1 数据模型设计
3.1.1 计算器类型枚举 (CalculatorType)
enum CalculatorType {
loan(
label: '房贷计算',
emoji: '🏠',
description: '计算房贷还款金额',
color: Color(0xFF2196F3),
),
tax(
label: '个税计算',
emoji: '💼',
description: '计算个人所得税',
color: Color(0xFF4CAF50),
),
unit(
label: '单位转换',
emoji: '🔄',
description: '各种单位换算',
color: Color(0xFFFF9800),
),
health(
label: '健康计算',
emoji: '🏥',
description: '健康指数计算',
color: Color(0xFFF44336),
),
currency(
label: '货币转换',
emoji: '💱',
description: '货币汇率换算',
color: Color(0xFF9C27B0),
),
date(
label: '日期计算',
emoji: '📅',
description: '日期相关计算',
color: Color(0xFF607D8B),
);
final String label;
final String emoji;
final String description;
final Color color;
}
3.1.2 房贷计算模型 (LoanCalculator)
class LoanCalculator {
final double principal; // 贷款本金
final double annualRate; // 年利率
final int loanTerm; // 贷款期限(年)
final LoanType loanType; // 还款方式
LoanCalculator({
required this.principal,
required this.annualRate,
required this.loanTerm,
required this.loanType,
});
double get monthlyRate => annualRate / 12 / 100;
int get totalMonths => loanTerm * 12;
double calculateMonthlyPayment() {
if (loanType == LoanType.equalPayment) {
return _calculateEqualPayment();
} else {
return _calculateEqualPrincipal();
}
}
double _calculateEqualPayment() {
final rate = monthlyRate;
final months = totalMonths;
if (rate == 0) return principal / months;
final payment = principal * rate * pow(1 + rate, months) /
(pow(1 + rate, months) - 1);
return payment;
}
double _calculateEqualPrincipal() {
final principalPayment = principal / totalMonths;
return principalPayment + principal * monthlyRate;
}
double calculateTotalPayment() {
if (loanType == LoanType.equalPayment) {
return calculateMonthlyPayment() * totalMonths;
} else {
final principalPayment = principal / totalMonths;
double totalInterest = 0;
double remainingPrincipal = principal;
for (int i = 0; i < totalMonths; i++) {
totalInterest += remainingPrincipal * monthlyRate;
remainingPrincipal -= principalPayment;
}
return principal + totalInterest;
}
}
double calculateTotalInterest() {
return calculateTotalPayment() - principal;
}
}
enum LoanType {
equalPayment(label: '等额本息'),
equalPrincipal(label: '等额本金');
final String label;
const LoanType({required this.label});
}
3.1.3 个税计算模型 (TaxCalculator)
class TaxCalculator {
final double income; // 收入
final double deductions; // 扣除项目
final double specialDeductions; // 专项扣除
final double otherDeductions; // 其他扣除
TaxCalculator({
required this.income,
required this.deductions,
this.specialDeductions = 0,
this.otherDeductions = 0,
});
double get taxableIncome {
final monthlyIncome = income / 12;
final monthlyDeductions = deductions / 12;
final monthlySpecialDeductions = specialDeductions / 12;
final monthlyOtherDeductions = otherDeductions / 12;
final monthlyTaxable = monthlyIncome - 5000 - monthlyDeductions -
monthlySpecialDeductions - monthlyOtherDeductions;
return max(0, monthlyTaxable * 12);
}
double calculateTax() {
final taxable = taxableIncome;
if (taxable <= 36000) {
return taxable * 0.03;
} else if (taxable <= 144000) {
return 36000 * 0.03 + (taxable - 36000) * 0.1;
} else if (taxable <= 300000) {
return 36000 * 0.03 + 108000 * 0.1 + (taxable - 144000) * 0.2;
} else if (taxable <= 420000) {
return 36000 * 0.03 + 108000 * 0.1 + 156000 * 0.2 + (taxable - 300000) * 0.25;
} else if (taxable <= 660000) {
return 36000 * 0.03 + 108000 * 0.1 + 156000 * 0.2 + 120000 * 0.25 + (taxable - 420000) * 0.3;
} else if (taxable <= 960000) {
return 36000 * 0.03 + 108000 * 0.1 + 156000 * 0.2 + 120000 * 0.25 + 240000 * 0.3 + (taxable - 660000) * 0.35;
} else {
return 36000 * 0.03 + 108000 * 0.1 + 156000 * 0.2 + 120000 * 0.25 + 240000 * 0.3 + 300000 * 0.35 + (taxable - 960000) * 0.45;
}
}
double calculateAfterTaxIncome() {
return income - calculateTax();
}
}
3.1.4 单位转换模型 (UnitConverter)
class UnitConverter {
final String category;
final double value;
final String fromUnit;
final String toUnit;
UnitConverter({
required this.category,
required this.value,
required this.fromUnit,
required this.toUnit,
});
double convert() {
switch (category) {
case '长度':
return _convertLength();
case '重量':
return _convertWeight();
case '面积':
return _convertArea();
case '体积':
return _convertVolume();
case '温度':
return _convertTemperature();
case '时间':
return _convertTime();
default:
return value;
}
}
double _convertLength() {
final meters = _lengthToMeters(value, fromUnit);
return _metersToLength(meters, toUnit);
}
double _lengthToMeters(double value, String unit) {
switch (unit) {
case '米': return value;
case '千米': return value * 1000;
case '厘米': return value / 100;
case '毫米': return value / 1000;
case '英尺': return value * 0.3048;
case '英寸': return value * 0.0254;
default: return value;
}
}
double _metersToLength(double meters, String unit) {
switch (unit) {
case '米': return meters;
case '千米': return meters / 1000;
case '厘米': return meters * 100;
case '毫米': return meters * 1000;
case '英尺': return meters / 0.3048;
case '英寸': return meters / 0.0254;
default: return meters;
}
}
// 其他单位转换方法...
}
3.1.5 健康计算模型 (HealthCalculator)
class HealthCalculator {
final double weight; // 体重(kg)
final double height; // 身高(m)
final int age; // 年龄
final String gender; // 性别
HealthCalculator({
required this.weight,
required this.height,
required this.age,
required this.gender,
});
double calculateBMI() {
return weight / (height * height);
}
String getBMICategory() {
final bmi = calculateBMI();
if (bmi < 18.5) return '体重过轻';
if (bmi < 24) return '正常范围';
if (bmi < 28) return '超重';
return '肥胖';
}
double calculateBodyFat() {
final bmi = calculateBMI();
if (gender == '男') {
return 1.20 * bmi + 0.23 * age - 16.2;
} else {
return 1.20 * bmi + 0.23 * age - 5.4;
}
}
double calculateBMR() {
if (gender == '男') {
return 88.362 + (13.397 * weight) + (4.799 * height * 100) - (5.677 * age);
} else {
return 447.593 + (9.247 * weight) + (3.098 * height * 100) - (4.330 * age);
}
}
(double, double) getIdealWeight() {
final idealLow = 18.5 * height * height;
final idealHigh = 24 * height * height;
return (idealLow, idealHigh);
}
}
3.2 页面结构设计
3.2.1 主页面布局
3.2.2 房贷计算页面
3.2.3 个税计算页面
3.2.4 单位转换页面
3.2.5 健康计算页面
3.3 计算引擎设计
3.4 结果展示设计
四、UI设计规范
4.1 配色方案
应用以专业的蓝色为主色调,象征精确与可靠:
| 颜色类型 | 色值 | 用途 |
|---|---|---|
| 主色 | #2196F3 (Blue) | 导航、主题元素 |
| 辅助色 | #64B5F6 | 房贷页面 |
| 第三色 | #81C784 | 个税页面 |
| 强调色 | #FFB74D | 单位转换页面 |
| 健康色 | #EF9A9A | 健康页面 |
| 背景色 | #FAFAFA | 页面背景 |
| 卡片背景 | #FFFFFF | 功能卡片 |
| 结果背景 | #E3F2FD | 结果展示区域 |
4.2 计算器类型颜色
| 计算器 | 色值 | 视觉效果 |
|---|---|---|
| 房贷计算 | #2196F3 | 专业蓝色 |
| 个税计算 | #4CAF50 | 健康绿色 |
| 单位转换 | #FF9800 | 活力橙色 |
| 健康计算 | #F44336 | 健康红色 |
| 货币转换 | #9C27B0 | 优雅紫色 |
| 日期计算 | #607D8B | 中性灰色 |
4.3 字体规范
| 元素 | 字号 | 字重 | 颜色 |
|---|---|---|---|
| 页面标题 | 24px | Bold | 主色 |
| 计算结果 | 20px | Bold | #000000 |
| 输入标签 | 16px | Medium | #666666 |
| 结果说明 | 14px | Regular | #999999 |
| 按钮文本 | 16px | Medium | #FFFFFF |
4.4 组件规范
4.4.1 房贷计算界面
┌─────────────────────────────────────┐
│ 房贷计算 │
│ │
│ 贷款金额: [1000000]元 │
│ 年利率: [4.9]% │
│ 贷款期限: [30]年 │
│ │
│ 还款方式: │
│ [等额本息] [等额本金] │
│ │
│ [计算] │
│ │
│ 每月还款: ¥5307.27 │
│ 总还款: ¥1,910,617.12 │
│ 总利息: ¥910,617.12 │
└─────────────────────────────────────┘
4.4.2 个税计算界面
┌─────────────────────────────────────┐
│ 个税计算 │
│ │
│ 年收入: [120000]元 │
│ 基本扣除: [60000]元 │
│ 专项扣除: [24000]元 │
│ 其他扣除: [0]元 │
│ │
│ [计算] │
│ │
│ 应纳税所得额: ¥36,000 │
│ 应纳税额: ¥1,080 │
│ 税后收入: ¥118,920 │
│ 税率: 3% │
└─────────────────────────────────────┘
4.4.3 单位转换界面
┌─────────────────────────────────────┐
│ 单位转换 │
│ │
│ 选择类别: [长度 ▼] │
│ 输入数值: [1] │
│ 从单位: [米 ▼] │
│ 到单位: [千米 ▼] │
│ │
│ [转换] │
│ │
│ 转换结果: 0.001 千米 │
│ 公式: 1米 = 0.001千米 │
└─────────────────────────────────────┘
4.4.4 健康计算界面
┌─────────────────────────────────────┐
│ 健康计算 │
│ │
│ 体重: [70]kg │
│ 身高: [1.75]m │
│ 年龄: [30]岁 │
│ 性别: [男 ▼] │
│ │
│ 计算指标: │
│ [BMI] [体脂率] [基础代谢率] [理想体重] │
│ │
│ [计算] │
│ │
│ BMI: 22.86 (正常范围) │
│ 健康建议: 体重在正常范围内,保持健康生活方式 │
└─────────────────────────────────────┘
五、核心功能实现
5.1 房贷计算实现
class LoanCalculator {
final double principal;
final double annualRate;
final int loanTerm;
final LoanType loanType;
LoanCalculator({
required this.principal,
required this.annualRate,
required this.loanTerm,
required this.loanType,
});
double get monthlyRate => annualRate / 12 / 100;
int get totalMonths => loanTerm * 12;
double calculateMonthlyPayment() {
if (loanType == LoanType.equalPayment) {
return _calculateEqualPayment();
} else {
return _calculateEqualPrincipal();
}
}
double _calculateEqualPayment() {
final rate = monthlyRate;
final months = totalMonths;
if (rate == 0) return principal / months;
final payment = principal * rate * pow(1 + rate, months) /
(pow(1 + rate, months) - 1);
return payment;
}
double _calculateEqualPrincipal() {
final principalPayment = principal / totalMonths;
return principalPayment + principal * monthlyRate;
}
double calculateTotalPayment() {
if (loanType == LoanType.equalPayment) {
return calculateMonthlyPayment() * totalMonths;
} else {
final principalPayment = principal / totalMonths;
double totalInterest = 0;
double remainingPrincipal = principal;
for (int i = 0; i < totalMonths; i++) {
totalInterest += remainingPrincipal * monthlyRate;
remainingPrincipal -= principalPayment;
}
return principal + totalInterest;
}
}
double calculateTotalInterest() {
return calculateTotalPayment() - principal;
}
List<Map<String, dynamic>> getPaymentSchedule() {
final schedule = <Map<String, dynamic>>[];
final principalPayment = principal / totalMonths;
double remainingPrincipal = principal;
for (int month = 1; month <= totalMonths; month++) {
final interestPayment = remainingPrincipal * monthlyRate;
final totalPayment = loanType == LoanType.equalPayment
? calculateMonthlyPayment()
: principalPayment + interestPayment;
schedule.add({
'month': month,
'payment': totalPayment,
'principal': loanType == LoanType.equalPayment
? totalPayment - interestPayment
: principalPayment,
'interest': interestPayment,
'remaining': remainingPrincipal - (loanType == LoanType.equalPayment
? totalPayment - interestPayment
: principalPayment),
});
remainingPrincipal -= loanType == LoanType.equalPayment
? totalPayment - interestPayment
: principalPayment;
}
return schedule;
}
}
5.2 个税计算实现
class TaxCalculator {
final double income;
final double deductions;
final double specialDeductions;
final double otherDeductions;
TaxCalculator({
required this.income,
required this.deductions,
this.specialDeductions = 0,
this.otherDeductions = 0,
});
double get taxableIncome {
final monthlyIncome = income / 12;
final monthlyDeductions = deductions / 12;
final monthlySpecialDeductions = specialDeductions / 12;
final monthlyOtherDeductions = otherDeductions / 12;
final monthlyTaxable = monthlyIncome - 5000 - monthlyDeductions -
monthlySpecialDeductions - monthlyOtherDeductions;
return max(0, monthlyTaxable * 12);
}
double calculateTax() {
final taxable = taxableIncome;
if (taxable <= 36000) {
return taxable * 0.03;
} else if (taxable <= 144000) {
return 36000 * 0.03 + (taxable - 36000) * 0.1;
} else if (taxable <= 300000) {
return 36000 * 0.03 + 108000 * 0.1 + (taxable - 144000) * 0.2;
} else if (taxable <= 420000) {
return 36000 * 0.03 + 108000 * 0.1 + 156000 * 0.2 + (taxable - 300000) * 0.25;
} else if (taxable <= 660000) {
return 36000 * 0.03 + 108000 * 0.1 + 156000 * 0.2 + 120000 * 0.25 + (taxable - 420000) * 0.3;
} else if (taxable <= 960000) {
return 36000 * 0.03 + 108000 * 0.1 + 156000 * 0.2 + 120000 * 0.25 + 240000 * 0.3 + (taxable - 660000) * 0.35;
} else {
return 36000 * 0.03 + 108000 * 0.1 + 156000 * 0.2 + 120000 * 0.25 + 240000 * 0.3 + 300000 * 0.35 + (taxable - 960000) * 0.45;
}
}
double calculateAfterTaxIncome() {
return income - calculateTax();
}
String getTaxBracket() {
final taxable = taxableIncome;
if (taxable <= 36000) return '3% 税率';
if (taxable <= 144000) return '10% 税率';
if (taxable <= 300000) return '20% 税率';
if (taxable <= 420000) return '25% 税率';
if (taxable <= 660000) return '30% 税率';
if (taxable <= 960000) return '35% 税率';
return '45% 税率';
}
}
5.3 单位转换实现
class UnitConverter {
final String category;
final double value;
final String fromUnit;
final String toUnit;
UnitConverter({
required this.category,
required this.value,
required this.fromUnit,
required this.toUnit,
});
double convert() {
switch (category) {
case '长度':
return _convertLength();
case '重量':
return _convertWeight();
case '面积':
return _convertArea();
case '体积':
return _convertVolume();
case '温度':
return _convertTemperature();
case '时间':
return _convertTime();
default:
return value;
}
}
double _convertLength() {
final meters = _lengthToMeters(value, fromUnit);
return _metersToLength(meters, toUnit);
}
double _lengthToMeters(double value, String unit) {
switch (unit) {
case '米': return value;
case '千米': return value * 1000;
case '厘米': return value / 100;
case '毫米': return value / 1000;
case '英尺': return value * 0.3048;
case '英寸': return value * 0.0254;
default: return value;
}
}
double _metersToLength(double meters, String unit) {
switch (unit) {
case '米': return meters;
case '千米': return meters / 1000;
case '厘米': return meters * 100;
case '毫米': return meters * 1000;
case '英尺': return meters / 0.3048;
case '英寸': return meters / 0.0254;
default: return meters;
}
}
double _convertWeight() {
final kilograms = _weightToKilograms(value, fromUnit);
return _kilogramsToWeight(kilograms, toUnit);
}
double _weightToKilograms(double value, String unit) {
switch (unit) {
case '千克': return value;
case '克': return value / 1000;
case '吨': return value * 1000;
case '磅': return value * 0.453592;
case '盎司': return value * 0.0283495;
default: return value;
}
}
double _kilogramsToWeight(double kilograms, String unit) {
switch (unit) {
case '千克': return kilograms;
case '克': return kilograms * 1000;
case '吨': return kilograms / 1000;
case '磅': return kilograms / 0.453592;
case '盎司': return kilograms / 0.0283495;
default: return kilograms;
}
}
double _convertTemperature() {
if (fromUnit == toUnit) return value;
double celsius;
if (fromUnit == '摄氏度') {
celsius = value;
} else if (fromUnit == '华氏度') {
celsius = (value - 32) * 5 / 9;
} else { // 开尔文
celsius = value - 273.15;
}
if (toUnit == '摄氏度') {
return celsius;
} else if (toUnit == '华氏度') {
return celsius * 9 / 5 + 32;
} else { // 开尔文
return celsius + 273.15;
}
}
// 其他单位转换方法...
}
5.4 健康计算实现
class HealthCalculator {
final double weight;
final double height;
final int age;
final String gender;
HealthCalculator({
required this.weight,
required this.height,
required this.age,
required this.gender,
});
double calculateBMI() {
return weight / (height * height);
}
String getBMICategory() {
final bmi = calculateBMI();
if (bmi < 18.5) return '体重过轻';
if (bmi < 24) return '正常范围';
if (bmi < 28) return '超重';
return '肥胖';
}
double calculateBodyFat() {
final bmi = calculateBMI();
if (gender == '男') {
return 1.20 * bmi + 0.23 * age - 16.2;
} else {
return 1.20 * bmi + 0.23 * age - 5.4;
}
}
String getBodyFatCategory() {
final bodyFat = calculateBodyFat();
if (gender == '男') {
if (bodyFat < 10) return '过低';
if (bodyFat < 20) return '正常';
if (bodyFat < 25) return '超重';
return '肥胖';
} else {
if (bodyFat < 18) return '过低';
if (bodyFat < 28) return '正常';
if (bodyFat < 33) return '超重';
return '肥胖';
}
}
double calculateBMR() {
if (gender == '男') {
return 88.362 + (13.397 * weight) + (4.799 * height * 100) - (5.677 * age);
} else {
return 447.593 + (9.247 * weight) + (3.098 * height * 100) - (4.330 * age);
}
}
(double, double) getIdealWeight() {
final idealLow = 18.5 * height * height;
final idealHigh = 24 * height * height;
return (idealLow, idealHigh);
}
String getHealthAdvice() {
final bmi = calculateBMI();
if (bmi < 18.5) {
return '体重过轻,建议适当增加营养摄入,保持健康饮食。';
} else if (bmi < 24) {
return '体重在正常范围内,保持健康生活方式和均衡饮食。';
} else if (bmi < 28) {
return '超重,建议适当控制饮食,增加运动量。';
} else {
return '肥胖,建议咨询医生,制定科学的减重计划。';
}
}
}
5.5 结果展示实现
class ResultDisplayWidget extends StatelessWidget {
final String title;
final double value;
final String unit;
final String description;
final Color color;
const ResultDisplayWidget({
super.key,
required this.title,
required this.value,
required this.unit,
required this.description,
required this.color,
});
Widget build(BuildContext context) {
return Container(
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: color.withOpacity(0.1),
borderRadius: BorderRadius.circular(12),
border: Border.all(color: color),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
title,
style: Theme.of(context).textTheme.titleMedium?.copyWith(
color: color,
),
),
const SizedBox(height: 8),
Text(
'${value.toStringAsFixed(2)} $unit',
style: Theme.of(context).textTheme.headlineSmall?.copyWith(
color: color,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 8),
Text(
description,
style: Theme.of(context).textTheme.bodySmall,
),
],
),
);
}
}
class ChartDisplayWidget extends StatelessWidget {
final List<Map<String, dynamic>> data;
final String xLabel;
final String yLabel;
final Color color;
const ChartDisplayWidget({
super.key,
required this.data,
required this.xLabel,
required this.yLabel,
required this.color,
});
Widget build(BuildContext context) {
return Container(
height: 200,
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(12),
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.1),
spreadRadius: 1,
blurRadius: 5,
offset: const Offset(0, 2),
),
],
),
child: LineChart(
LineChartData(
lineBarsData: [
LineChartBarData(
spots: data.asMap().entries.map((entry) {
return FlSpot(entry.key.toDouble(), entry.value['value'] as double);
}).toList(),
color: color,
barWidth: 2,
isCurved: true,
dotData: FlDotData(show: false),
),
],
gridData: FlGridData(show: true),
titlesData: FlTitlesData(
bottomTitles: AxisTitles(
sideTitles: SideTitles(
showTitles: true,
getTitlesWidget: (value, meta) {
final index = value.toInt();
if (index >= 0 && index < data.length) {
return Text(data[index]['label'] as String);
}
return const Text('');
},
),
),
),
),
),
);
}
}
六、交互设计
6.1 房贷计算流程
6.2 个税计算流程
6.3 单位转换流程
6.4 健康计算流程
七、扩展功能规划
7.1 后续版本规划
7.2 功能扩展建议
7.2.1 高级计算功能
高级功能:
- 复利计算器
- 投资回报率计算
- 贷款比较工具
- 税务筹划工具
7.2.2 数据管理
数据功能:
- 计算历史记录
- 数据导出导入
- 云同步备份
- 多设备同步
7.2.3 用户体验
体验功能:
- 深色模式
- 自定义主题
- 手势操作
- 语音输入
八、注意事项
8.1 开发注意事项
-
精度问题:浮点数计算需注意精度误差
-
输入验证:用户输入需进行合理验证
-
性能优化:复杂计算需考虑性能影响
-
用户体验:操作流程需简洁直观
-
数据安全:敏感数据需保护
8.2 常见问题
| 问题 | 原因 | 解决方案 |
|---|---|---|
| 计算结果不准确 | 浮点数精度 | 使用decimal类型或合理舍入 |
| 输入错误 | 缺少验证 | 添加输入验证和提示 |
| 界面卡顿 | 复杂计算 | 异步计算或优化算法 |
| 内存占用高 | 数据量大 | 合理管理内存和缓存 |
| 兼容性问题 | 平台差异 | 测试不同平台兼容性 |
8.3 使用技巧
🧮 计算器合集使用技巧 🧮
房贷计算技巧
- 对比等额本息和等额本金的差异
- 调整贷款期限查看总利息变化
- 使用还款明细了解资金流向
- 保存计算结果方便对比
个税计算技巧
- 合理规划专项扣除
- 了解不同收入水平的税率
- 预测年度税务支出
- 优化税务筹划
单位转换技巧
- 常用单位快速转换
- 批量转换多个数值
- 记忆常用转换关系
- 自定义常用单位
健康计算技巧
- 定期检测健康指标
- 结合运动和饮食调整
- 了解健康标准范围
- 制定健康改善计划
九、运行说明
9.1 环境要求
| 环境 | 版本要求 |
|---|---|
| Flutter SDK | >= 3.0.0 |
| Dart SDK | >= 2.17.0 |
| 存储空间 | 建议50MB以上 |
| 鸿蒙OS | API 21+ |
9.2 运行命令
# 查看可用设备
flutter devices
# 运行到iOS设备
flutter run -t lib/main_calculator_collection.dart
# 运行到Android设备
flutter run -t lib/main_calculator_collection.dart
# 运行到Web服务器
flutter run -d web-server -t lib/main_calculator_collection.dart --web-port 8144
# 运行到鸿蒙设备
flutter run -d 127.0.0.1:5555 lib/main_calculator_collection.dart
# 代码分析
flutter analyze lib/main_calculator_collection.dart
十、总结
计算器合集应用通过房贷计算、个税计算、单位转换、健康计算四大模块,为用户提供了一个功能全面的计算工具平台。应用集成了多种实用计算器,涵盖日常生活和工作中的各种计算需求,帮助用户快速获取准确的计算结果。
核心功能涵盖房贷计算、个税计算、单位转换、健康计算四大模块。房贷计算支持等额本息和等额本金两种还款方式;个税计算基于最新税率表,支持多种扣除项目;单位转换支持长度、重量、面积、体积、温度、时间等多种单位;健康计算支持BMI、体脂率、基础代谢率、理想体重等多种健康指标。
应用采用 Material Design 3 设计规范,以专业的蓝色为主色调,象征精确与可靠。通过本应用,希望能够帮助用户解决各种计算需求,做出更明智的决策,提高生活和工作效率。
计算器合集——一个应用解决各种计算需求
更多推荐


所有评论(0)