|
|
@@ -1,24 +1,766 @@
|
|
|
-
|
|
|
import 'dart:ui';
|
|
|
|
|
|
import 'package:clean/base/base_view.dart';
|
|
|
import 'package:clean/module/home/home_controller.dart';
|
|
|
+import 'package:clean/resource/assets.gen.dart';
|
|
|
+import 'package:clean/resource/string.gen.dart';
|
|
|
+import 'package:get/get.dart';
|
|
|
import 'package:flutter/Material.dart';
|
|
|
+import 'package:flutter_screenutil/flutter_screenutil.dart';
|
|
|
+import 'package:syncfusion_flutter_charts/charts.dart';
|
|
|
|
|
|
class HomePage extends BaseView<HomeController> {
|
|
|
-
|
|
|
const HomePage({super.key});
|
|
|
|
|
|
@override
|
|
|
- Color backgroundColor() {
|
|
|
- return Colors.white;
|
|
|
+ backgroundColor() {
|
|
|
+ return Color(0xFF05050D);
|
|
|
+ }
|
|
|
+
|
|
|
+ @override
|
|
|
+ viewHeight() {
|
|
|
+ return double.infinity;
|
|
|
}
|
|
|
|
|
|
@override
|
|
|
Widget buildBody(BuildContext context) {
|
|
|
// TODO: implement buildBody
|
|
|
+ return Stack(
|
|
|
+ children: [
|
|
|
+ SafeArea(
|
|
|
+ child: SingleChildScrollView(
|
|
|
+ child: Column(
|
|
|
+ children: [
|
|
|
+ titleCard(),
|
|
|
+ storageCard(),
|
|
|
+ similarCard(),
|
|
|
+ quickPhotoCard(),
|
|
|
+ peopleCard(),
|
|
|
+ locationsCard(),
|
|
|
+ screenshotsAndBlurryCard(),
|
|
|
+ SizedBox(height: 40.h),
|
|
|
+ ],
|
|
|
+ )),
|
|
|
+ ),
|
|
|
+ IgnorePointer(
|
|
|
+ child: Assets.images.bgHome.image(
|
|
|
+ width: 360.w,
|
|
|
+ height: 234.h,
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ ],
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ Widget titleCard() {
|
|
|
+ return Padding(
|
|
|
+ padding: EdgeInsets.only(top: 29.h, left: 16.w, right: 16.w),
|
|
|
+ child: Row(
|
|
|
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
|
+ children: [
|
|
|
+ Text(
|
|
|
+ StringName.cleanPro,
|
|
|
+ style: TextStyle(
|
|
|
+ color: Colors.white,
|
|
|
+ fontSize: 24.sp,
|
|
|
+ fontWeight: FontWeight.w900,
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ GestureDetector(
|
|
|
+ onTap: () {
|
|
|
+ print("home vip");
|
|
|
+ controller.usedSpace.value = controller.usedSpace.value + 60;
|
|
|
+ controller.freeSpace.value = controller.freeSpace.value - 60;
|
|
|
+ },
|
|
|
+ child: Assets.images.iconHomeTitleVip
|
|
|
+ .image(width: 60.8.w, height: 20.h),
|
|
|
+ ),
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ Widget storageCard() {
|
|
|
+ return Container(
|
|
|
+ margin: EdgeInsets.only(top: 20.h),
|
|
|
+ padding: EdgeInsets.symmetric(horizontal: 16.w),
|
|
|
+ width: 328.w,
|
|
|
+ height: 146.h,
|
|
|
+ decoration: ShapeDecoration(
|
|
|
+ color: Colors.white.withValues(alpha: 0.10000000149011612),
|
|
|
+ shape: RoundedRectangleBorder(
|
|
|
+ borderRadius: BorderRadius.circular(14.r),
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ child: Row(
|
|
|
+ children: [
|
|
|
+ circularChartCard(),
|
|
|
+ SizedBox(
|
|
|
+ width: 14.w,
|
|
|
+ ),
|
|
|
+ storageInfoCard(),
|
|
|
+ ],
|
|
|
+ ));
|
|
|
+ }
|
|
|
+
|
|
|
+ Widget circularChartCard() {
|
|
|
+ return SizedBox(
|
|
|
+ width: 120.00.w,
|
|
|
+ child: Obx(() {
|
|
|
+ return SfCircularChart(
|
|
|
+ series: <CircularSeries>[
|
|
|
+ DoughnutSeries<PieData, String>(
|
|
|
+ dataSource: [
|
|
|
+ PieData('photo Space', controller.photoSpacePercentage,
|
|
|
+ Colors.blue),
|
|
|
+ PieData(
|
|
|
+ 'Used Space',
|
|
|
+ controller.usedSpacePercentage -
|
|
|
+ controller.photoSpacePercentage,
|
|
|
+ Colors.red),
|
|
|
+ PieData(
|
|
|
+ 'Unused Space',
|
|
|
+ controller.freeSpacePercentage,
|
|
|
+ Colors.white.withValues(alpha: 0.10000000149011612),
|
|
|
+ ),
|
|
|
+ ],
|
|
|
+ xValueMapper: (PieData data, _) => data.label,
|
|
|
+ yValueMapper: (PieData data, _) => data.value,
|
|
|
+ pointColorMapper: (PieData data, _) => data.color,
|
|
|
+ cornerStyle: CornerStyle.bothCurve,
|
|
|
+ radius: '100%',
|
|
|
+ // 设置饼图的半径
|
|
|
+ innerRadius: '80%',
|
|
|
+ // 设置饼图的内半径
|
|
|
+ startAngle: 0,
|
|
|
+ // 设置开始角度
|
|
|
+ endAngle: 360, // 设置结束角度
|
|
|
+ ),
|
|
|
+ ],
|
|
|
+ annotations: <CircularChartAnnotation>[
|
|
|
+ CircularChartAnnotation(
|
|
|
+ widget: Container(
|
|
|
+ child: Column(
|
|
|
+ mainAxisSize: MainAxisSize.min,
|
|
|
+ crossAxisAlignment: CrossAxisAlignment.center,
|
|
|
+ children: [
|
|
|
+ Row(
|
|
|
+ mainAxisAlignment: MainAxisAlignment.center,
|
|
|
+ crossAxisAlignment: CrossAxisAlignment.end,
|
|
|
+ children: [
|
|
|
+ Obx(() {
|
|
|
+ return Text(
|
|
|
+ controller.usedSpacePercentage.toStringAsFixed(0),
|
|
|
+ textAlign: TextAlign.end,
|
|
|
+ style: TextStyle(
|
|
|
+ color: Colors.white
|
|
|
+ .withValues(alpha: 0.8999999761581421),
|
|
|
+ fontSize: 30.sp,
|
|
|
+ height: 1,
|
|
|
+ fontWeight: FontWeight.w400,
|
|
|
+ ),
|
|
|
+ );
|
|
|
+ }),
|
|
|
+ Text(
|
|
|
+ '%',
|
|
|
+ textAlign: TextAlign.end,
|
|
|
+ style: TextStyle(
|
|
|
+ color: Colors.white
|
|
|
+ .withValues(alpha: 0.8999999761581421),
|
|
|
+ fontSize: 14.87.r,
|
|
|
+ fontWeight: FontWeight.w500,
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ Text(
|
|
|
+ 'used',
|
|
|
+ textAlign: TextAlign.center,
|
|
|
+ style: TextStyle(
|
|
|
+ color: Colors.white.withValues(
|
|
|
+ alpha: 0.6000000238418579),
|
|
|
+ fontSize: 14.87.r,
|
|
|
+ height: 1,
|
|
|
+ fontWeight: FontWeight.w500,
|
|
|
+ ),
|
|
|
+ )
|
|
|
+ ],
|
|
|
+ )),
|
|
|
+ horizontalAlignment: ChartAlignment.center,
|
|
|
+ verticalAlignment: ChartAlignment.center,
|
|
|
+ radius: '0%',
|
|
|
+ ),
|
|
|
+ ],
|
|
|
+ );
|
|
|
+ }),
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ Widget storageInfoCard() {
|
|
|
+ return Column(
|
|
|
+ crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
+ children: [
|
|
|
+ SizedBox(
|
|
|
+ height: 24.h,
|
|
|
+ ),
|
|
|
+ Text(
|
|
|
+ 'Storage Used',
|
|
|
+ style: TextStyle(
|
|
|
+ color: Colors.white,
|
|
|
+ fontSize: 16.sp,
|
|
|
+ fontWeight: FontWeight.w500,
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ Row(
|
|
|
+ children: [
|
|
|
+ Obx(() {
|
|
|
+ return Text.rich(
|
|
|
+ TextSpan(
|
|
|
+ children: [
|
|
|
+ TextSpan(
|
|
|
+ text: controller.usedSpace.toStringAsFixed(1),
|
|
|
+ style: TextStyle(
|
|
|
+ color: Color(0xFFFC4C4F),
|
|
|
+ fontSize: 13.sp,
|
|
|
+ fontWeight: FontWeight.w400,
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ TextSpan(
|
|
|
+ text: 'GB',
|
|
|
+ style: TextStyle(
|
|
|
+ color: Color(0xFFFC4C4F),
|
|
|
+ fontSize: 13.sp,
|
|
|
+ fontWeight: FontWeight.w500,
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ textAlign: TextAlign.center,
|
|
|
+ );
|
|
|
+ }),
|
|
|
+ Text(
|
|
|
+ ' / ',
|
|
|
+ style: TextStyle(
|
|
|
+ color: Colors.white.withValues(alpha: 0.6000000238418579),
|
|
|
+ fontSize: 13.sp,
|
|
|
+ fontWeight: FontWeight.w500,
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ Obx(() {
|
|
|
+ return Text.rich(
|
|
|
+ TextSpan(
|
|
|
+ children: [
|
|
|
+ TextSpan(
|
|
|
+ text: controller.totalSpace.toStringAsFixed(1),
|
|
|
+ style: TextStyle(
|
|
|
+ color:
|
|
|
+ Colors.white.withValues(alpha: 0.6000000238418579),
|
|
|
+ fontSize: 13.sp,
|
|
|
+ fontWeight: FontWeight.w400,
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ TextSpan(
|
|
|
+ text: 'GB',
|
|
|
+ style: TextStyle(
|
|
|
+ color:
|
|
|
+ Colors.white.withValues(alpha: 0.6000000238418579),
|
|
|
+ fontSize: 13.sp,
|
|
|
+ fontWeight: FontWeight.w500,
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ textAlign: TextAlign.center,
|
|
|
+ );
|
|
|
+ }),
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ SizedBox(
|
|
|
+ height: 10.h,
|
|
|
+ ),
|
|
|
+ Row(
|
|
|
+ crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
+ children: [
|
|
|
+ Container(
|
|
|
+ margin: EdgeInsets.only(top: 7.h),
|
|
|
+ width: 6.w,
|
|
|
+ height: 6.h,
|
|
|
+ decoration: ShapeDecoration(
|
|
|
+ color: Color(0xFF0279FB),
|
|
|
+ shape: OvalBorder(),
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ SizedBox(
|
|
|
+ width: 3.5.w,
|
|
|
+ ),
|
|
|
+ Column(
|
|
|
+ crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
+ children: [
|
|
|
+ Text(
|
|
|
+ 'Photos',
|
|
|
+ textAlign: TextAlign.start,
|
|
|
+ style: TextStyle(
|
|
|
+ color: Colors.white,
|
|
|
+ fontSize: 14.sp,
|
|
|
+ fontWeight: FontWeight.w500,
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ Obx(() {
|
|
|
+ return Text(
|
|
|
+ '${controller.photoSpace.toStringAsFixed(1)} GB',
|
|
|
+ textAlign: TextAlign.start,
|
|
|
+ style: TextStyle(
|
|
|
+ color: Colors.white.withValues(alpha: 0.6499999761581421),
|
|
|
+ fontSize: 13.sp,
|
|
|
+ fontWeight: FontWeight.w400,
|
|
|
+ ),
|
|
|
+ );
|
|
|
+ }),
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ SizedBox(
|
|
|
+ width: 10.w,
|
|
|
+ ),
|
|
|
+ Container(
|
|
|
+ margin: EdgeInsets.only(top: 7.h),
|
|
|
+ width: 6.w,
|
|
|
+ height: 6.h,
|
|
|
+ decoration: ShapeDecoration(
|
|
|
+ color: Color(0xFFEE4933),
|
|
|
+ shape: OvalBorder(),
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ SizedBox(
|
|
|
+ width: 3.5.w,
|
|
|
+ ),
|
|
|
+ Column(
|
|
|
+ crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
+ children: [
|
|
|
+ Text(
|
|
|
+ 'iphone',
|
|
|
+ textAlign: TextAlign.start,
|
|
|
+ style: TextStyle(
|
|
|
+ color: Colors.white,
|
|
|
+ fontSize: 14.sp,
|
|
|
+ fontWeight: FontWeight.w500,
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ Obx(() {
|
|
|
+ return Text(
|
|
|
+ '${controller.usedSpace.toStringAsFixed(1)} GB',
|
|
|
+ textAlign: TextAlign.start,
|
|
|
+ style: TextStyle(
|
|
|
+ color: Colors.white.withValues(alpha: 0.6499999761581421),
|
|
|
+ fontSize: 13.sp,
|
|
|
+ fontWeight: FontWeight.w400,
|
|
|
+ ),
|
|
|
+ );
|
|
|
+ }),
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ ],
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ Widget similarCard() {
|
|
|
+ return Container(
|
|
|
+ width: 328.w,
|
|
|
+ height: 155.h,
|
|
|
+ margin: EdgeInsets.only(top: 20.h),
|
|
|
+ padding: EdgeInsets.symmetric(horizontal: 16.w),
|
|
|
+ decoration: ShapeDecoration(
|
|
|
+ color: Colors.white.withValues(alpha: 0.11999999731779099),
|
|
|
+ shape: RoundedRectangleBorder(
|
|
|
+ borderRadius: BorderRadius.circular(16.r),
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ child: Column(
|
|
|
+ crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
+ children: [
|
|
|
+ SizedBox(height: 12.h),
|
|
|
+ Row(
|
|
|
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
|
+ children: [
|
|
|
+ Column(
|
|
|
+ crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
+ children: [
|
|
|
+ Text(
|
|
|
+ 'Similar',
|
|
|
+ style: TextStyle(
|
|
|
+ color: Colors.white,
|
|
|
+ fontSize: 16.sp,
|
|
|
+ fontWeight: FontWeight.w700,
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ Text.rich(
|
|
|
+ TextSpan(
|
|
|
+ children: [
|
|
|
+ TextSpan(
|
|
|
+ text: '800',
|
|
|
+ style: TextStyle(
|
|
|
+ color: Colors.white,
|
|
|
+ fontSize: 12.sp,
|
|
|
+ fontWeight: FontWeight.w400,
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ TextSpan(
|
|
|
+ text: ' duplicate photos detected',
|
|
|
+ style: TextStyle(
|
|
|
+ color: Colors.white
|
|
|
+ .withValues(alpha: 0.800000011920929),
|
|
|
+ fontSize: 12.sp,
|
|
|
+ fontWeight: FontWeight.w400,
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ CleanUpButton(
|
|
|
+ label: 'Clean up',
|
|
|
+ size: '0 GB',
|
|
|
+ onTap: () {
|
|
|
+ controller.similarCleanClick();
|
|
|
+ },
|
|
|
+ ),
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ // SizedBox(height: 19.h),
|
|
|
+ Spacer(),
|
|
|
+ Obx(() {
|
|
|
+ return Row(
|
|
|
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
|
+ children: List.generate(4, (index) {
|
|
|
+ return ImageContainer(
|
|
|
+ imagePath: controller.similarImages[index], // 可以传入不同的路径
|
|
|
+ size: 70.w,
|
|
|
+ );
|
|
|
+ }),
|
|
|
+ );
|
|
|
+ }),
|
|
|
+ Spacer(),
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ Widget quickPhotoCard() {
|
|
|
+ return Container(
|
|
|
+ padding: EdgeInsets.symmetric(horizontal: 16.w),
|
|
|
+ margin: EdgeInsets.only(top: 30.h),
|
|
|
+ alignment: Alignment.centerLeft,
|
|
|
+ child: Text(
|
|
|
+ 'Quick Photo Clean',
|
|
|
+ style: TextStyle(
|
|
|
+ color: Colors.white,
|
|
|
+ fontSize: 18.sp,
|
|
|
+ fontWeight: FontWeight.w700,
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ Widget peopleCard() {
|
|
|
+ return Container(
|
|
|
+ margin: EdgeInsets.only(top: 12.h),
|
|
|
+ width: 328.w,
|
|
|
+ height: 205.h,
|
|
|
+ decoration: ShapeDecoration(
|
|
|
+ color: Colors.white.withValues(alpha: 0.12),
|
|
|
+ shape: RoundedRectangleBorder(
|
|
|
+ borderRadius: BorderRadius.circular(14.sp),
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ child: Stack(
|
|
|
+ children: [
|
|
|
+ Column(
|
|
|
+ crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
+ children: [
|
|
|
+ Spacer(),
|
|
|
+ Padding(
|
|
|
+ padding: EdgeInsets.only(left: 14.0.w),
|
|
|
+ child: Text(
|
|
|
+ 'People',
|
|
|
+ style: TextStyle(
|
|
|
+ color: Colors.white,
|
|
|
+ fontSize: 16.sp,
|
|
|
+ fontWeight: FontWeight.w700,
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ Spacer(),
|
|
|
+ Row(
|
|
|
+ mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
|
|
+ children: List.generate(2, (index) {
|
|
|
+ return ImageContainer(
|
|
|
+ imagePath: 'iconHomeNoPhoto',
|
|
|
+ size: 146.w,
|
|
|
+ );
|
|
|
+ }),
|
|
|
+ ),
|
|
|
+ Spacer(),
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ Positioned(
|
|
|
+ bottom: 20.h,
|
|
|
+ right: 20.w,
|
|
|
+ child: CleanUpButton(
|
|
|
+ label: 'Clean up',
|
|
|
+ size: '0 GB',
|
|
|
+ onTap: () {
|
|
|
+ controller.peopleCleanClick();
|
|
|
+ },
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ Widget locationsCard() {
|
|
|
+ return Container(
|
|
|
+ padding: EdgeInsets.symmetric(horizontal: 12.w),
|
|
|
+ margin: EdgeInsets.only(top: 14.h),
|
|
|
+ width: 328.w,
|
|
|
+ height: 230.h,
|
|
|
+ decoration: ShapeDecoration(
|
|
|
+ color: Colors.white.withValues(alpha: 0.12),
|
|
|
+ shape: RoundedRectangleBorder(
|
|
|
+ borderRadius: BorderRadius.circular(14.sp),
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ child: Stack(
|
|
|
+ children: [
|
|
|
+ Column(
|
|
|
+ crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
+ children: [
|
|
|
+ Spacer(),
|
|
|
+ Text(
|
|
|
+ 'Locations',
|
|
|
+ style: TextStyle(
|
|
|
+ color: Colors.white,
|
|
|
+ fontSize: 16.sp,
|
|
|
+ fontWeight: FontWeight.w700,
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ Spacer(),
|
|
|
+ Container(
|
|
|
+ width: 304.w,
|
|
|
+ height: 171.h,
|
|
|
+ decoration: ShapeDecoration(
|
|
|
+ color: Color(0xFF272C33),
|
|
|
+ shape: RoundedRectangleBorder(
|
|
|
+ borderRadius: BorderRadius.circular(12.r),
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ child: Center(
|
|
|
+ child: Assets.images.iconHomeNoPhoto.image(
|
|
|
+ width: 60.w,
|
|
|
+ height: 60.h,
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ Spacer(),
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ Positioned(
|
|
|
+ bottom: 20.h,
|
|
|
+ right: 8.w,
|
|
|
+ child: CleanUpButton(
|
|
|
+ label: 'Clean up',
|
|
|
+ size: '0 GB',
|
|
|
+ onTap: () {
|
|
|
+ controller.locationCleanClick();
|
|
|
+ },
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ Widget screenshotsAndBlurryCard() {
|
|
|
return Container(
|
|
|
- color: Colors.black,
|
|
|
+ padding: EdgeInsets.symmetric(horizontal: 16.w),
|
|
|
+ margin: EdgeInsets.only(top: 14.h),
|
|
|
+ child: Row(
|
|
|
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
|
+ children: [
|
|
|
+ _buildCard('Screenshots', 'Clean up', '0 GB', onTap: () {
|
|
|
+ controller.screenshotCleanClick();
|
|
|
+ }),
|
|
|
+ _buildCard('Blurry', 'Clean up', '0 GB', onTap: () {
|
|
|
+ controller.blurryCleanClick();
|
|
|
+ }),
|
|
|
+ ],
|
|
|
+ ),
|
|
|
);
|
|
|
}
|
|
|
-}
|
|
|
+
|
|
|
+ Widget _buildCard(String title, String buttonLabel, String size,
|
|
|
+ {required Function() onTap}) {
|
|
|
+ return Stack(
|
|
|
+ children: [
|
|
|
+ Container(
|
|
|
+ width: 160.w,
|
|
|
+ height: 189.h,
|
|
|
+ decoration: ShapeDecoration(
|
|
|
+ color: Colors.white.withValues(alpha: 0.12),
|
|
|
+ shape: RoundedRectangleBorder(
|
|
|
+ borderRadius: BorderRadius.circular(14.r),
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ child: Column(
|
|
|
+ crossAxisAlignment: CrossAxisAlignment.center,
|
|
|
+ children: [
|
|
|
+ Spacer(),
|
|
|
+ Container(
|
|
|
+ alignment: Alignment.centerLeft,
|
|
|
+ padding: EdgeInsets.only(left: 9.w),
|
|
|
+ child: Text(
|
|
|
+ title,
|
|
|
+ style: TextStyle(
|
|
|
+ color: Colors.white,
|
|
|
+ fontSize: 16.sp,
|
|
|
+ fontWeight: FontWeight.w700,
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ Spacer(),
|
|
|
+ Container(
|
|
|
+ width: 144.w,
|
|
|
+ height: 142.h,
|
|
|
+ decoration: ShapeDecoration(
|
|
|
+ color: Color(0xFF272C33),
|
|
|
+ shape: RoundedRectangleBorder(
|
|
|
+ borderRadius: BorderRadius.circular(12.r),
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ child: Center(
|
|
|
+ child: Assets.images.iconHomeNoPhoto.image(
|
|
|
+ width: 60.w,
|
|
|
+ height: 60.h,
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ Spacer(),
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ Positioned(
|
|
|
+ bottom: 16.h,
|
|
|
+ right: 16.w,
|
|
|
+ child: CleanUpButton(
|
|
|
+ label: buttonLabel,
|
|
|
+ size: size,
|
|
|
+ onTap: onTap,
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ ],
|
|
|
+ );
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+class CleanUpButton extends StatelessWidget {
|
|
|
+ final String label;
|
|
|
+ final String size;
|
|
|
+ final Function() onTap;
|
|
|
+
|
|
|
+ const CleanUpButton({
|
|
|
+ super.key,
|
|
|
+ required this.label,
|
|
|
+ required this.size,
|
|
|
+ required this.onTap,
|
|
|
+ });
|
|
|
+
|
|
|
+ @override
|
|
|
+ Widget build(BuildContext context) {
|
|
|
+ return Container(
|
|
|
+ width: 94.w,
|
|
|
+ height: 44.h,
|
|
|
+ decoration: ShapeDecoration(
|
|
|
+ color: Color(0xFF0279FB),
|
|
|
+ shape: RoundedRectangleBorder(
|
|
|
+ borderRadius: BorderRadius.circular(10.r),
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ child: GestureDetector(
|
|
|
+ onTap: onTap,
|
|
|
+ child: Row(
|
|
|
+ mainAxisAlignment: MainAxisAlignment.spaceAround,
|
|
|
+ children: [
|
|
|
+ Column(
|
|
|
+ crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
+ children: [
|
|
|
+ Spacer(),
|
|
|
+ Text(
|
|
|
+ label,
|
|
|
+ style: TextStyle(
|
|
|
+ color: Colors.white,
|
|
|
+ fontSize: 12.sp,
|
|
|
+ fontWeight: FontWeight.w400,
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ Text(
|
|
|
+ size,
|
|
|
+ style: TextStyle(
|
|
|
+ color: Colors.white,
|
|
|
+ fontSize: 16.sp,
|
|
|
+ height: 1,
|
|
|
+ fontWeight: FontWeight.w700,
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ Spacer(),
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ Assets.images.iconHomeRightArrow.image(
|
|
|
+ width: 6.52.w,
|
|
|
+ height: 6.52.h,
|
|
|
+ ),
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ ));
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+class ImageContainer extends StatelessWidget {
|
|
|
+ final String imagePath;
|
|
|
+ final double size;
|
|
|
+
|
|
|
+ const ImageContainer({
|
|
|
+ super.key,
|
|
|
+ required this.imagePath,
|
|
|
+ required this.size,
|
|
|
+ });
|
|
|
+
|
|
|
+ @override
|
|
|
+ Widget build(BuildContext context) {
|
|
|
+ return Container(
|
|
|
+ width: size,
|
|
|
+ height: size,
|
|
|
+ decoration: ShapeDecoration(
|
|
|
+ color: Color(0xFF272C33),
|
|
|
+ shape: RoundedRectangleBorder(
|
|
|
+ borderRadius: BorderRadius.circular(12.r),
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ child: Center(
|
|
|
+ child: Assets.images.iconHomeNoPhoto.image(
|
|
|
+ width: size * 0.45, // 图片的大小相对容器
|
|
|
+ height: size * 0.45,
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ );
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+class PieData {
|
|
|
+ final String label;
|
|
|
+ final double value;
|
|
|
+ final Color color;
|
|
|
+
|
|
|
+ PieData(this.label, this.value, this.color);
|
|
|
+}
|