Flutter for OpenHarmony移动数据使用监管助手App实战 - 套餐管理实现
套餐管理页面的核心是数据展示,把DataPlan模型设计好,UI层就很简单了。环形进度条直观展示使用进度,详情卡片提供更多数据,提醒卡片根据状态给出提示。支持多套餐管理添加套餐编辑功能支持套餐到期提醒添加流量预测功能欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net。
套餐管理是流量监控App的核心功能之一,用户在这里设置自己的流量套餐信息,App才能准确计算剩余流量和使用进度。这个页面需要展示套餐使用情况,并提供编辑套餐的入口。
页面结构规划
套餐管理页面分为几个部分:
- 套餐进度卡片:大号环形进度条展示使用百分比
- 详情信息卡片:剩余流量、剩余天数、日均可用
- 提醒状态卡片:根据使用情况显示正常或警告
空状态处理
如果用户还没设置套餐,需要显示引导界面:
Widget _buildNoPlan() {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.sim_card_outlined, size: 80.sp, color: AppTheme.textSecondary),
Center让内容居中显示。
Column垂直排列图标和文字。
sim_card_outlined图标表示套餐。
SizedBox(height: 16.h),
Text('暂无套餐', style: TextStyle(fontSize: 16.sp, color: AppTheme.textSecondary)),
SizedBox(height: 16.h),
ElevatedButton(onPressed: () {}, child: const Text('添加套餐')),
间距16.h后显示提示文字。
ElevatedButton引导用户添加套餐。
简洁的空状态引导用户操作。
],
),
);
}
闭合Column和Center完成空状态。
空状态页面简洁明了。
一个图标、一句提示、一个按钮。
套餐进度卡片
用大号环形进度条作为页面的视觉中心:
Widget _buildPlanCard() {
final plan = controller.plan.value!;
return Container(
padding: EdgeInsets.all(20.w),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(16.r),
),
获取当前套餐数据。
Container作为进度卡片的容器。
白色背景与页面灰色背景对比。
child: Column(
children: [
CircularPercentIndicator(
radius: 80.r,
lineWidth: 12.w,
percent: plan.usagePercentage / 100,
Column垂直排列进度条和信息。
CircularPercentIndicator是环形进度条组件。
radius设置进度条半径。
center: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'${plan.usagePercentage.toStringAsFixed(0)}%',
style: TextStyle(fontSize: 24.sp, fontWeight: FontWeight.bold),
),
center放置进度条中间的内容。
显示使用百分比,不保留小数。
24.sp大字号突出显示。
Text('已使用', style: TextStyle(fontSize: 12.sp, color: AppTheme.textSecondary)),
],
),
progressColor: plan.isOverThreshold ? AppTheme.warningColor : AppTheme.primaryColor,
backgroundColor: Colors.grey.shade200,
),
"已使用"标签用12.sp小字号。
超过阈值时进度条变成警告色。
灰色背景作为进度条底色。
SizedBox(height: 20.h),
Text(plan.name, style: TextStyle(fontSize: 18.sp, fontWeight: FontWeight.w600)),
SizedBox(height: 8.h),
Text(
'${plan.formattedUsed} / ${plan.formattedTotal}',
style: TextStyle(fontSize: 14.sp, color: AppTheme.textSecondary),
),
间距20.h后显示套餐名称。
18.sp字号,w600加粗突出名称。
显示已用/总量的格式化字符串。
],
),
);
}
闭合Column和Container完成进度卡片。
环形进度条是页面的视觉焦点。
整体设计直观清晰。
详情信息卡片
展示更多套餐相关的数据:
Widget _buildDetailsCard() {
final plan = controller.plan.value!;
return Container(
padding: EdgeInsets.all(16.w),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(12.r),
),
获取当前套餐数据。
Container作为详情卡片的容器。
白色背景与页面灰色背景对比。
child: Column(
children: [
_buildDetailRow('剩余流量', plan.formattedRemaining),
const Divider(),
_buildDetailRow('剩余天数', '${plan.daysRemaining} 天'),
Column垂直排列各详情项。
_buildDetailRow构建单行详情。
Divider分隔各行。
const Divider(),
_buildDetailRow(
'日均可用',
'${(plan.remainingData / plan.daysRemaining / (1024 * 1024)).toStringAsFixed(0)} MB',
),
],
),
);
}
日均可用=剩余流量/剩余天数。
转换为MB单位显示。
帮助用户控制每日流量使用。
详情行组件
单行详情的显示:
Widget _buildDetailRow(String label, String value) {
return Padding(
padding: EdgeInsets.symmetric(vertical: 8.h),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
Padding添加垂直内边距。
Row两端对齐标签和数值。
spaceBetween让两端对齐。
children: [
Text(label, style: TextStyle(fontSize: 14.sp, color: AppTheme.textSecondary)),
Text(value, style: TextStyle(fontSize: 14.sp, fontWeight: FontWeight.w600)),
],
),
);
}
标签用次要颜色作为说明。
数值用w600加粗突出显示。
整体设计简洁直观。
提醒状态卡片
根据套餐使用情况显示不同的提示:
Widget _buildAlertCard() {
final plan = controller.plan.value!;
return Container(
padding: EdgeInsets.all(16.w),
decoration: BoxDecoration(
获取当前套餐数据。
Container作为提醒卡片的容器。
16.w内边距让内容不贴边。
color: plan.isOverThreshold
? AppTheme.warningColor.withOpacity(0.1)
: AppTheme.wifiColor.withOpacity(0.1),
borderRadius: BorderRadius.circular(12.r),
),
超过阈值用警告色浅色背景。
正常状态用绿色浅色背景。
12.r圆角保持视觉一致。
child: Row(
children: [
Icon(
plan.isOverThreshold ? Icons.warning_outlined : Icons.check_circle_outline,
color: plan.isOverThreshold ? AppTheme.warningColor : AppTheme.wifiColor,
size: 24.sp,
),
Row横向排列图标和文字。
超过阈值显示警告图标。
正常状态显示勾选图标。
SizedBox(width: 12.w),
Expanded(
child: Text(
plan.isOverThreshold
? '流量使用已超过${plan.alertThreshold}%,请注意控制'
: '流量使用正常',
间距12.w让图标和文字不挤。
Expanded让文字占据剩余空间。
根据状态显示不同提示文字。
style: TextStyle(
fontSize: 13.sp,
color: plan.isOverThreshold ? AppTheme.warningColor : AppTheme.wifiColor,
),
),
),
],
),
);
}
文字颜色与图标颜色一致。
13.sp字号适合提示信息。
整体设计让用户一眼看出状态。
DataPlan数据模型
套餐数据的模型定义:
class DataPlan {
final String id;
final String name;
final int totalData;
final int usedData;
final DateTime startDate;
id是套餐的唯一标识。
name是套餐名称。
totalData和usedData是总流量和已用流量。
final DateTime endDate;
final int alertThreshold;
final bool isActive;
int get remainingData => totalData - usedData;
startDate和endDate是套餐有效期。
alertThreshold是提醒阈值百分比。
remainingData计算剩余流量。
double get usagePercentage => totalData > 0 ? (usedData / totalData) * 100 : 0;
int get daysRemaining => endDate.difference(DateTime.now()).inDays;
bool get isOverThreshold => usagePercentage >= alertThreshold;
usagePercentage计算使用百分比。
daysRemaining计算剩余天数。
isOverThreshold判断是否超过阈值。
String get formattedTotal => _formatBytes(totalData);
String get formattedUsed => _formatBytes(usedData);
String get formattedRemaining => _formatBytes(remainingData);
}
格式化方法将字节数转为可读字符串。
formattedTotal、formattedUsed、formattedRemaining。
计算属性让数据访问更方便。
Controller层实现
控制器管理套餐相关的状态:
class DataPlanController extends GetxController {
final plan = Rx<DataPlan?>(null);
final isEditing = false.obs;
void onInit() {
plan存储当前套餐,可为null。
isEditing控制编辑状态。
onInit在控制器初始化时调用。
super.onInit();
loadPlan();
}
void loadPlan() {
plan.value = DataPlan(
id: '1',
name: '月度套餐',
loadPlan加载套餐数据。
创建DataPlan对象。
模拟数据用于演示。
totalData: 1024 * 1024 * 1024 * 10,
usedData: 1024 * 1024 * 1024 * 6,
startDate: DateTime.now().subtract(const Duration(days: 15)),
endDate: DateTime.now().add(const Duration(days: 15)),
alertThreshold: 80,
总流量10GB,已用6GB。
套餐从15天前开始,还有15天结束。
alertThreshold设为80%。
);
}
}
闭合loadPlan方法和控制器类。
实际项目中从本地存储加载数据。
套餐数据应该持久化保存。
写在最后
套餐管理页面的核心是数据展示,把DataPlan模型设计好,UI层就很简单了。环形进度条直观展示使用进度,详情卡片提供更多数据,提醒卡片根据状态给出提示。
可以继续优化的方向:
- 支持多套餐管理
- 添加套餐编辑功能
- 支持套餐到期提醒
- 添加流量预测功能
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net
更多推荐


所有评论(0)