home_view.dart 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836
  1. import 'dart:io';
  2. import 'package:clean/base/base_view.dart';
  3. import 'package:clean/module/home/home_controller.dart';
  4. import 'package:clean/module/image_picker/image_picker_util.dart';
  5. import 'package:clean/resource/assets.gen.dart';
  6. import 'package:clean/resource/string.gen.dart';
  7. import 'package:clean/utils/image_util.dart';
  8. import 'package:get/get.dart';
  9. import 'package:flutter/Material.dart';
  10. import 'package:flutter_screenutil/flutter_screenutil.dart';
  11. import 'package:syncfusion_flutter_charts/charts.dart';
  12. import 'package:wechat_assets_picker/wechat_assets_picker.dart';
  13. class HomePage extends BaseView<HomeController> {
  14. const HomePage({super.key});
  15. @override
  16. backgroundColor() {
  17. return Color(0xFF05050D);
  18. }
  19. @override
  20. viewHeight() {
  21. return double.infinity;
  22. }
  23. @override
  24. Widget buildBody(BuildContext context) {
  25. // TODO: implement buildBody
  26. return Stack(
  27. children: [
  28. SafeArea(
  29. child: SingleChildScrollView(
  30. child: Column(
  31. children: [
  32. titleCard(),
  33. storageCard(),
  34. similarCard(),
  35. quickPhotoCard(),
  36. peopleCard(),
  37. locationsCard(),
  38. screenshotsAndBlurryCard(),
  39. SizedBox(height: 40.h),
  40. ],
  41. )),
  42. ),
  43. IgnorePointer(
  44. child: Assets.images.bgHome.image(
  45. width: 360.w,
  46. height: 234.h,
  47. ),
  48. ),
  49. ],
  50. );
  51. }
  52. Widget titleCard() {
  53. return Padding(
  54. padding: EdgeInsets.only(top: 0.h, left: 16.w, right: 16.w),
  55. child: Row(
  56. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  57. children: [
  58. Text(
  59. StringName.cleanPro,
  60. style: TextStyle(
  61. color: Colors.white,
  62. fontSize: 24.sp,
  63. fontWeight: FontWeight.w900,
  64. ),
  65. ),
  66. GestureDetector(
  67. onTap: () {
  68. print("home vip");
  69. controller.usedSpace.value = controller.usedSpace.value + 60;
  70. controller.freeSpace.value = controller.freeSpace.value - 60;
  71. },
  72. child: Assets.images.iconHomeTitleVip
  73. .image(width: 60.8.w, height: 20.h),
  74. ),
  75. ],
  76. ),
  77. );
  78. }
  79. Widget storageCard() {
  80. return Container(
  81. margin: EdgeInsets.only(top: 20.h),
  82. padding: EdgeInsets.symmetric(horizontal: 16.w),
  83. width: 328.w,
  84. height: 146.h,
  85. decoration: ShapeDecoration(
  86. color: Colors.white.withValues(alpha: 0.10),
  87. shape: RoundedRectangleBorder(
  88. borderRadius: BorderRadius.circular(14.r),
  89. ),
  90. ),
  91. child: Row(
  92. children: [
  93. circularChartCard(),
  94. SizedBox(
  95. width: 14.w,
  96. ),
  97. storageInfoCard(),
  98. ],
  99. ));
  100. }
  101. Widget circularChartCard() {
  102. return SizedBox(
  103. width: 120.00.w,
  104. child: Obx(() {
  105. return SfCircularChart(
  106. series: <CircularSeries>[
  107. DoughnutSeries<PieData, String>(
  108. dataSource: [
  109. PieData('photo Space', controller.photoSpacePercentage,
  110. Colors.blue),
  111. PieData(
  112. 'Used Space',
  113. controller.usedSpacePercentage -
  114. controller.photoSpacePercentage,
  115. Colors.red),
  116. PieData(
  117. 'Unused Space',
  118. controller.freeSpacePercentage,
  119. Colors.white.withValues(alpha: 0.10000000149011612),
  120. ),
  121. ],
  122. xValueMapper: (PieData data, _) => data.label,
  123. yValueMapper: (PieData data, _) => data.value,
  124. pointColorMapper: (PieData data, _) => data.color,
  125. cornerStyle: CornerStyle.bothCurve,
  126. radius: '100%',
  127. // 设置饼图的半径
  128. innerRadius: '80%',
  129. // 设置饼图的内半径
  130. startAngle: 0,
  131. // 设置开始角度
  132. endAngle: 360, // 设置结束角度
  133. ),
  134. ],
  135. annotations: <CircularChartAnnotation>[
  136. CircularChartAnnotation(
  137. widget: Container(
  138. child: Column(
  139. mainAxisSize: MainAxisSize.min,
  140. crossAxisAlignment: CrossAxisAlignment.center,
  141. children: [
  142. Row(
  143. mainAxisAlignment: MainAxisAlignment.center,
  144. crossAxisAlignment: CrossAxisAlignment.end,
  145. children: [
  146. Obx(() {
  147. return Text(
  148. controller.usedSpacePercentage.toStringAsFixed(0),
  149. textAlign: TextAlign.end,
  150. style: TextStyle(
  151. color: Colors.white
  152. .withValues(alpha: 0.8999999761581421),
  153. fontSize: 30.sp,
  154. height: 1,
  155. fontWeight: FontWeight.w400,
  156. ),
  157. );
  158. }),
  159. Text(
  160. '%',
  161. textAlign: TextAlign.end,
  162. style: TextStyle(
  163. color: Colors.white
  164. .withValues(alpha: 0.8999999761581421),
  165. fontSize: 14.87.r,
  166. fontWeight: FontWeight.w500,
  167. ),
  168. ),
  169. ],
  170. ),
  171. Text(
  172. 'used',
  173. textAlign: TextAlign.center,
  174. style: TextStyle(
  175. color: Colors.white.withValues(
  176. alpha: 0.6000000238418579),
  177. fontSize: 14.87.r,
  178. height: 1,
  179. fontWeight: FontWeight.w500,
  180. ),
  181. )
  182. ],
  183. )),
  184. horizontalAlignment: ChartAlignment.center,
  185. verticalAlignment: ChartAlignment.center,
  186. radius: '0%',
  187. ),
  188. ],
  189. );
  190. }),
  191. );
  192. }
  193. Widget storageInfoCard() {
  194. return Column(
  195. crossAxisAlignment: CrossAxisAlignment.start,
  196. children: [
  197. SizedBox(
  198. height: 24.h,
  199. ),
  200. Text(
  201. 'Storage Used',
  202. style: TextStyle(
  203. color: Colors.white,
  204. fontSize: 16.sp,
  205. fontWeight: FontWeight.w500,
  206. ),
  207. ),
  208. Row(
  209. children: [
  210. Obx(() {
  211. return Text.rich(
  212. TextSpan(
  213. children: [
  214. TextSpan(
  215. text: controller.usedSpace.toStringAsFixed(1),
  216. style: TextStyle(
  217. color: Color(0xFFFC4C4F),
  218. fontSize: 13.sp,
  219. fontWeight: FontWeight.w400,
  220. ),
  221. ),
  222. TextSpan(
  223. text: 'GB',
  224. style: TextStyle(
  225. color: Color(0xFFFC4C4F),
  226. fontSize: 13.sp,
  227. fontWeight: FontWeight.w500,
  228. ),
  229. ),
  230. ],
  231. ),
  232. textAlign: TextAlign.center,
  233. );
  234. }),
  235. Text(
  236. ' / ',
  237. style: TextStyle(
  238. color: Colors.white.withValues(alpha: 0.6000000238418579),
  239. fontSize: 13.sp,
  240. fontWeight: FontWeight.w500,
  241. ),
  242. ),
  243. Obx(() {
  244. return Text.rich(
  245. TextSpan(
  246. children: [
  247. TextSpan(
  248. text: controller.totalSpace.toStringAsFixed(1),
  249. style: TextStyle(
  250. color:
  251. Colors.white.withValues(alpha: 0.6000000238418579),
  252. fontSize: 13.sp,
  253. fontWeight: FontWeight.w400,
  254. ),
  255. ),
  256. TextSpan(
  257. text: 'GB',
  258. style: TextStyle(
  259. color:
  260. Colors.white.withValues(alpha: 0.6000000238418579),
  261. fontSize: 13.sp,
  262. fontWeight: FontWeight.w500,
  263. ),
  264. ),
  265. ],
  266. ),
  267. textAlign: TextAlign.center,
  268. );
  269. }),
  270. ],
  271. ),
  272. SizedBox(
  273. height: 10.h,
  274. ),
  275. Row(
  276. crossAxisAlignment: CrossAxisAlignment.start,
  277. children: [
  278. Container(
  279. margin: EdgeInsets.only(top: 7.h),
  280. width: 6.w,
  281. height: 6.h,
  282. decoration: ShapeDecoration(
  283. color: Color(0xFF0279FB),
  284. shape: OvalBorder(),
  285. ),
  286. ),
  287. SizedBox(
  288. width: 3.5.w,
  289. ),
  290. Column(
  291. crossAxisAlignment: CrossAxisAlignment.start,
  292. children: [
  293. Text(
  294. 'Photos',
  295. textAlign: TextAlign.start,
  296. style: TextStyle(
  297. color: Colors.white,
  298. fontSize: 14.sp,
  299. fontWeight: FontWeight.w500,
  300. ),
  301. ),
  302. Obx(() {
  303. return Text(
  304. '${controller.photoSpace.toStringAsFixed(1)} GB',
  305. textAlign: TextAlign.start,
  306. style: TextStyle(
  307. color: Colors.white.withValues(alpha: 0.6499999761581421),
  308. fontSize: 13.sp,
  309. fontWeight: FontWeight.w400,
  310. ),
  311. );
  312. }),
  313. ],
  314. ),
  315. SizedBox(
  316. width: 10.w,
  317. ),
  318. Container(
  319. margin: EdgeInsets.only(top: 7.h),
  320. width: 6.w,
  321. height: 6.h,
  322. decoration: ShapeDecoration(
  323. color: Color(0xFFEE4933),
  324. shape: OvalBorder(),
  325. ),
  326. ),
  327. SizedBox(
  328. width: 3.5.w,
  329. ),
  330. Column(
  331. crossAxisAlignment: CrossAxisAlignment.start,
  332. children: [
  333. Text(
  334. 'iphone',
  335. textAlign: TextAlign.start,
  336. style: TextStyle(
  337. color: Colors.white,
  338. fontSize: 14.sp,
  339. fontWeight: FontWeight.w500,
  340. ),
  341. ),
  342. Obx(() {
  343. return Text(
  344. '${controller.usedSpace.toStringAsFixed(1)} GB',
  345. textAlign: TextAlign.start,
  346. style: TextStyle(
  347. color: Colors.white.withValues(alpha: 0.6499999761581421),
  348. fontSize: 13.sp,
  349. fontWeight: FontWeight.w400,
  350. ),
  351. );
  352. }),
  353. ],
  354. ),
  355. ],
  356. ),
  357. ],
  358. );
  359. }
  360. Widget similarCard() {
  361. return Container(
  362. width: 328.w,
  363. height: 155.h,
  364. margin: EdgeInsets.only(top: 20.h),
  365. padding: EdgeInsets.symmetric(horizontal: 16.w),
  366. decoration: ShapeDecoration(
  367. color: Colors.white.withValues(alpha: 0.12),
  368. shape: RoundedRectangleBorder(
  369. borderRadius: BorderRadius.circular(16.r),
  370. ),
  371. ),
  372. child: Column(
  373. crossAxisAlignment: CrossAxisAlignment.start,
  374. children: [
  375. SizedBox(height: 12.h),
  376. Row(
  377. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  378. children: [
  379. Column(
  380. crossAxisAlignment: CrossAxisAlignment.start,
  381. children: [
  382. Text(
  383. 'Similar',
  384. style: TextStyle(
  385. color: Colors.white,
  386. fontSize: 16.sp,
  387. fontWeight: FontWeight.w700,
  388. ),
  389. ),
  390. Text.rich(
  391. TextSpan(
  392. children: [
  393. TextSpan(
  394. text: '800',
  395. style: TextStyle(
  396. color: Colors.white,
  397. fontSize: 12.sp,
  398. fontWeight: FontWeight.w400,
  399. ),
  400. ),
  401. TextSpan(
  402. text: ' duplicate photos detected',
  403. style: TextStyle(
  404. color: Colors.white
  405. .withValues(alpha: 0.800000011920929),
  406. fontSize: 12.sp,
  407. fontWeight: FontWeight.w400,
  408. ),
  409. ),
  410. ],
  411. ),
  412. ),
  413. ],
  414. ),
  415. Obx(() {
  416. return CleanUpButton(
  417. label: 'Clean up',
  418. size: ImagePickerUtil.formatFileSize(
  419. ImagePickerUtil.similarPhotosSize.value),
  420. onTap: () {
  421. controller.similarCleanClick();
  422. },
  423. );
  424. }),
  425. ],
  426. ),
  427. // SizedBox(height: 19.h),
  428. Spacer(),
  429. Obx(() {
  430. return Row(
  431. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  432. children: List.generate(4, (index) {
  433. return ImageContainer(
  434. size: 70.w,
  435. image: controller.similarPhotos.length < 4
  436. ? Assets.images.iconHomeNoPhoto.image(
  437. width: 70.w * 0.45,
  438. height: 70.w * 0.45,
  439. )
  440. : AssetEntityImage(
  441. width: 70.w,
  442. height: 70.w,
  443. controller.similarPhotos[index],
  444. isOriginal: false,
  445. thumbnailSize: const ThumbnailSize.square(300),
  446. fit: BoxFit.cover,
  447. errorBuilder: (context, error, stackTrace) {
  448. return Assets.images.iconHomeNoPhoto.image(
  449. width: 70.w * 0.45,
  450. height: 70.w * 0.45,
  451. );
  452. },
  453. ));
  454. }),
  455. );
  456. }),
  457. Spacer(),
  458. ],
  459. ),
  460. );
  461. }
  462. Widget quickPhotoCard() {
  463. return Container(
  464. padding: EdgeInsets.symmetric(horizontal: 16.w),
  465. margin: EdgeInsets.only(top: 30.h),
  466. alignment: Alignment.centerLeft,
  467. child: Text(
  468. 'Quick Photo Clean',
  469. style: TextStyle(
  470. color: Colors.white,
  471. fontSize: 18.sp,
  472. fontWeight: FontWeight.w700,
  473. ),
  474. ),
  475. );
  476. }
  477. Widget peopleCard() {
  478. return Container(
  479. margin: EdgeInsets.only(top: 12.h),
  480. width: 328.w,
  481. height: 205.h,
  482. decoration: ShapeDecoration(
  483. color: Colors.white.withValues(alpha: 0.12),
  484. shape: RoundedRectangleBorder(
  485. borderRadius: BorderRadius.circular(14.sp),
  486. ),
  487. ),
  488. child: Stack(
  489. children: [
  490. Column(
  491. crossAxisAlignment: CrossAxisAlignment.start,
  492. children: [
  493. Spacer(),
  494. Padding(
  495. padding: EdgeInsets.only(left: 14.0.w),
  496. child: Text(
  497. 'People',
  498. style: TextStyle(
  499. color: Colors.white,
  500. fontSize: 16.sp,
  501. fontWeight: FontWeight.w700,
  502. ),
  503. ),
  504. ),
  505. Spacer(),
  506. Obx(() {
  507. return Row(
  508. mainAxisAlignment: MainAxisAlignment.spaceEvenly,
  509. children: List.generate(2, (index) {
  510. return ImageContainer(
  511. image: controller.peoplePhotos.length < 2
  512. ? Assets.images.iconHomeNoPhoto.image(
  513. width: 146.w * 0.45,
  514. height: 146.w * 0.45,
  515. )
  516. : Image.file(
  517. width: 146.w,
  518. height: 146.w,
  519. controller.peoplePhotos[index],
  520. fit: BoxFit.cover,
  521. ),
  522. // 可以传入不同的路径
  523. size: 146.w,
  524. );
  525. }),
  526. );
  527. }),
  528. Spacer(),
  529. ],
  530. ),
  531. Positioned(
  532. bottom: 20.h,
  533. right: 20.w,
  534. child: Obx(() {
  535. return CleanUpButton(
  536. label: 'Clean up',
  537. size: ImagePickerUtil.formatFileSize(
  538. ImagePickerUtil.peopleSize.value),
  539. onTap: () {
  540. controller.peopleCleanClick();
  541. },
  542. );
  543. }),
  544. ),
  545. ],
  546. ),
  547. );
  548. }
  549. Widget locationsCard() {
  550. return Container(
  551. padding: EdgeInsets.symmetric(horizontal: 12.w),
  552. margin: EdgeInsets.only(top: 14.h),
  553. width: 328.w,
  554. height: 230.h,
  555. decoration: ShapeDecoration(
  556. color: Colors.white.withValues(alpha: 0.12),
  557. shape: RoundedRectangleBorder(
  558. borderRadius: BorderRadius.circular(14.sp),
  559. ),
  560. ),
  561. child: Stack(
  562. children: [
  563. Column(
  564. crossAxisAlignment: CrossAxisAlignment.start,
  565. children: [
  566. Spacer(),
  567. Text(
  568. 'Locations',
  569. style: TextStyle(
  570. color: Colors.white,
  571. fontSize: 16.sp,
  572. fontWeight: FontWeight.w700,
  573. ),
  574. ),
  575. Spacer(),
  576. Container(
  577. width: 304.w,
  578. height: 171.h,
  579. clipBehavior: Clip.hardEdge,
  580. decoration: ShapeDecoration(
  581. color: Color(0xFF272C33),
  582. shape: RoundedRectangleBorder(
  583. borderRadius: BorderRadius.circular(12.r),
  584. ),
  585. ),
  586. child: Obx(() {
  587. return Center(
  588. child: controller.locationPhoto.value == null
  589. ? Assets.images.iconHomeNoPhoto.image(
  590. width: 60.w,
  591. height: 60.h,
  592. )
  593. : Image.file(
  594. width: 304.w,
  595. height: 171.h,
  596. controller.locationPhoto.value!,
  597. fit: BoxFit.cover,
  598. ),
  599. );
  600. }),
  601. ),
  602. Spacer(),
  603. ],
  604. ),
  605. Positioned(
  606. bottom: 20.h,
  607. right: 8.w,
  608. child: Obx(() {
  609. return CleanUpButton(
  610. label: 'Clean up',
  611. size: ImagePickerUtil.formatFileSize(
  612. ImagePickerUtil.locationsSize.value),
  613. onTap: () {
  614. controller.locationCleanClick();
  615. },
  616. );
  617. }),
  618. ),
  619. ],
  620. ),
  621. );
  622. }
  623. Widget screenshotsAndBlurryCard() {
  624. return Container(
  625. padding: EdgeInsets.symmetric(horizontal: 16.w),
  626. margin: EdgeInsets.only(top: 14.h),
  627. child: Obx(() {
  628. return Row(
  629. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  630. children: [
  631. _buildCard(
  632. 'Screenshots',
  633. 'Clean up',
  634. ImagePickerUtil.formatFileSize(
  635. ImagePickerUtil.screenshotsSize.value),
  636. controller.screenshotPhoto.value == null
  637. ? Assets.images.iconHomeNoPhoto.image(
  638. width: 60.w,
  639. height: 60.h,
  640. )
  641. : Image.file(
  642. width: 144.w,
  643. height: 142.h,
  644. controller.screenshotPhoto.value!,
  645. fit: BoxFit.cover,
  646. ), onTap: () {
  647. controller.screenshotCleanClick();
  648. }),
  649. _buildCard(
  650. 'Blurry',
  651. 'Clean up',
  652. ImagePickerUtil.formatFileSize(
  653. ImagePickerUtil.screenshotsSize.value),
  654. Assets.images.iconHomeNoPhoto.image(
  655. width: 60.w,
  656. height: 60.h,
  657. ), onTap: () {
  658. controller.blurryCleanClick();
  659. }),
  660. ],
  661. );
  662. }),
  663. );
  664. }
  665. Widget _buildCard(String title, String buttonLabel, String size, Image image,
  666. {required Function() onTap}) {
  667. return Stack(
  668. children: [
  669. Container(
  670. width: 160.w,
  671. height: 189.h,
  672. decoration: ShapeDecoration(
  673. color: Colors.white.withValues(alpha: 0.12),
  674. shape: RoundedRectangleBorder(
  675. borderRadius: BorderRadius.circular(14.r),
  676. ),
  677. ),
  678. child: Column(
  679. crossAxisAlignment: CrossAxisAlignment.center,
  680. children: [
  681. Spacer(),
  682. Container(
  683. alignment: Alignment.centerLeft,
  684. padding: EdgeInsets.only(left: 9.w),
  685. child: Text(
  686. title,
  687. style: TextStyle(
  688. color: Colors.white,
  689. fontSize: 16.sp,
  690. fontWeight: FontWeight.w700,
  691. ),
  692. ),
  693. ),
  694. Spacer(),
  695. Container(
  696. width: 144.w,
  697. height: 142.h,
  698. decoration: ShapeDecoration(
  699. color: Color(0xFF272C33),
  700. shape: RoundedRectangleBorder(
  701. borderRadius: BorderRadius.circular(12.r),
  702. ),
  703. ),
  704. child: Center(
  705. child: image,
  706. ),
  707. ),
  708. Spacer(),
  709. ],
  710. ),
  711. ),
  712. Positioned(
  713. bottom: 16.h,
  714. right: 16.w,
  715. child: CleanUpButton(
  716. label: buttonLabel,
  717. size: size,
  718. onTap: onTap,
  719. ),
  720. ),
  721. ],
  722. );
  723. }
  724. }
  725. class CleanUpButton extends StatelessWidget {
  726. final String label;
  727. final String size;
  728. final Function() onTap;
  729. const CleanUpButton({
  730. super.key,
  731. required this.label,
  732. required this.size,
  733. required this.onTap,
  734. });
  735. @override
  736. Widget build(BuildContext context) {
  737. return GestureDetector(
  738. onTap: onTap,
  739. child: Container(
  740. width: 94.w,
  741. height: 44.h,
  742. decoration: ShapeDecoration(
  743. color: Color(0xFF0279FB),
  744. shape: RoundedRectangleBorder(
  745. borderRadius: BorderRadius.circular(10.r),
  746. ),
  747. ),
  748. child: Row(
  749. mainAxisAlignment: MainAxisAlignment.spaceAround,
  750. children: [
  751. Column(
  752. crossAxisAlignment: CrossAxisAlignment.start,
  753. children: [
  754. Spacer(),
  755. Text(
  756. label,
  757. style: TextStyle(
  758. color: Colors.white,
  759. fontSize: 12.sp,
  760. fontWeight: FontWeight.w400,
  761. ),
  762. ),
  763. Text(
  764. size,
  765. style: TextStyle(
  766. color: Colors.white,
  767. fontSize: 16.sp,
  768. height: 1,
  769. fontWeight: FontWeight.w700,
  770. ),
  771. ),
  772. Spacer(),
  773. ],
  774. ),
  775. Assets.images.iconHomeRightArrow.image(
  776. width: 6.52.w,
  777. height: 6.52.h,
  778. ),
  779. ],
  780. ),
  781. ));
  782. }
  783. }
  784. class ImageContainer extends StatelessWidget {
  785. final Image image;
  786. final double size;
  787. const ImageContainer({
  788. super.key,
  789. required this.image,
  790. required this.size,
  791. });
  792. @override
  793. Widget build(BuildContext context) {
  794. return Container(
  795. width: size,
  796. height: size,
  797. clipBehavior: Clip.hardEdge,
  798. decoration: BoxDecoration(
  799. color: Color(0xFF272C33),
  800. borderRadius: BorderRadius.circular(12.r),
  801. ),
  802. child: Center(
  803. child: image,
  804. ),
  805. );
  806. }
  807. }
  808. class PieData {
  809. final String label;
  810. final double value;
  811. final Color color;
  812. PieData(this.label, this.value, this.color);
  813. }