Commit 2caf589685277c324393bd60536dd9b8eedb7d33

Authored by 吴启风
1 parent ad37b653

feat:商品列表图片优化

lib/pages/shop/home/widgets/product_item.dart
@@ -4,8 +4,7 @@ import 'package:flutter_screenutil/flutter_screenutil.dart'; @@ -4,8 +4,7 @@ import 'package:flutter_screenutil/flutter_screenutil.dart';
4 import 'package:wow_english/models/product_entity.dart'; 4 import 'package:wow_english/models/product_entity.dart';
5 5
6 class ProductItem extends StatelessWidget { 6 class ProductItem extends StatelessWidget {
7 - const ProductItem({super.key,  
8 - required this.onTap, this.entity}); 7 + const ProductItem({super.key, required this.onTap, this.entity});
9 8
10 final ProductEntity? entity; 9 final ProductEntity? entity;
11 10
@@ -15,52 +14,27 @@ class ProductItem extends StatelessWidget { @@ -15,52 +14,27 @@ class ProductItem extends StatelessWidget {
15 Widget build(BuildContext context) { 14 Widget build(BuildContext context) {
16 return Container( 15 return Container(
17 decoration: BoxDecoration( 16 decoration: BoxDecoration(
18 - borderRadius: BorderRadius.circular(10.r),  
19 - border: Border.all(  
20 - width: 1.0,  
21 - color: Colors.black  
22 - )  
23 - // image: DecorationImage(  
24 - // image: AssetImage(  
25 - // ''.assetPng,  
26 - // ),  
27 - // fit: BoxFit.fill  
28 - // )  
29 - ),  
30 - padding: EdgeInsets.symmetric(horizontal: 16.w,vertical: 16.h), 17 + borderRadius: BorderRadius.circular(10.r),
  18 + border: Border.all(width: 1.0, color: Colors.black)),
  19 + padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 16.h),
31 child: Row( 20 child: Row(
32 mainAxisAlignment: MainAxisAlignment.spaceBetween, 21 mainAxisAlignment: MainAxisAlignment.spaceBetween,
33 children: [ 22 children: [
34 Container( 23 Container(
35 - width: 124.w, 24 + width: 124.w, // 图片宽度
  25 + height: 124.h, // 图片高度
36 decoration: BoxDecoration( 26 decoration: BoxDecoration(
37 - border: Border.all(  
38 - width: 1.0,  
39 - color: const Color(0xFF333333),  
40 - ),  
41 - image: DecorationImage(  
42 - image: NetworkImage(entity?.picUrl ?? ''),  
43 - ) 27 + borderRadius: BorderRadius.circular(5),
  28 + // 圆角为5
  29 + border: Border.all(width: 1.w, color: const Color(0xFF333333)),
  30 + // 边框宽度为1
  31 + // 使用ClipRRect圆角会有间隙,ClipRRect在裁剪时可能会导致圆角部分的边框显示不完整。
  32 + image: DecorationImage(
  33 + image: NetworkImage(entity?.picUrl ?? ''), // 图片地址
  34 + fit: BoxFit.cover, // 图片填充方式
  35 + ),
44 ), 36 ),
45 ), 37 ),
46 - // CachedNetworkImage(  
47 - // imageUrl: entity?.picUrl ?? '',  
48 - // fit: BoxFit.fill,  
49 - // imageBuilder: (context, imageProvider) =>  
50 - // Container(  
51 - // decoration: BoxDecoration(  
52 - // border: Border.all(  
53 - // width: 1.0,  
54 - // color: const Color(0xFF333333),  
55 - // ),  
56 - // borderRadius: BorderRadius.circular(5.0),  
57 - // ),  
58 - // ),  
59 - // placeholder: (context, url) => const CircularProgressIndicator(),  
60 - // // errorWidget: (context, url, error) => const Icon(Icons.error),  
61 - // height: 124.h,  
62 - // width: 124.w,  
63 - // ),  
64 21.5.horizontalSpace, 38 21.5.horizontalSpace,
65 Expanded( 39 Expanded(
66 child: Column( 40 child: Column(
@@ -72,29 +46,24 @@ class ProductItem extends StatelessWidget { @@ -72,29 +46,24 @@ class ProductItem extends StatelessWidget {
72 softWrap: true, 46 softWrap: true,
73 textAlign: TextAlign.left, 47 textAlign: TextAlign.left,
74 style: TextStyle( 48 style: TextStyle(
75 - fontSize: 12.sp,  
76 - color: const Color(0xFF333333)  
77 - ), 49 + fontSize: 16.sp, color: const Color(0xFF333333)),
78 ), 50 ),
79 RichText( 51 RichText(
80 - text: TextSpan(  
81 - children:[  
82 - TextSpan(  
83 - text: '¥',  
84 - style: TextStyle(  
85 - fontSize: 21.sp,  
86 - color: const Color(0xFFF51A1A),  
87 - )  
88 - ),  
89 - TextSpan(  
90 - text: entity?.price?.toString() ?? '',  
91 - style: TextStyle(  
92 - fontSize: 40.sp,  
93 - color: const Color(0xFFF51A1A),  
94 - ),  
95 - )  
96 - ]  
97 - ), 52 + text: TextSpan(children: [
  53 + TextSpan(
  54 + text: '¥',
  55 + style: TextStyle(
  56 + fontSize: 21.sp,
  57 + color: const Color(0xFFF51A1A),
  58 + )),
  59 + TextSpan(
  60 + text: entity?.price?.toString() ?? '',
  61 + style: TextStyle(
  62 + fontSize: 40.sp,
  63 + color: const Color(0xFFF51A1A),
  64 + ),
  65 + )
  66 + ]),
98 ), 67 ),
99 GestureDetector( 68 GestureDetector(
100 onTap: () { 69 onTap: () {
@@ -107,8 +76,7 @@ class ProductItem extends StatelessWidget { @@ -107,8 +76,7 @@ class ProductItem extends StatelessWidget {
107 border: Border.all( 76 border: Border.all(
108 color: const Color(0xFF333333), 77 color: const Color(0xFF333333),
109 width: 1.0, 78 width: 1.0,
110 - )  
111 - ), 79 + )),
112 padding: EdgeInsets.symmetric( 80 padding: EdgeInsets.symmetric(
113 vertical: 1.h, 81 vertical: 1.h,
114 horizontal: 26.5.w, 82 horizontal: 26.5.w,
@@ -116,9 +84,7 @@ class ProductItem extends StatelessWidget { @@ -116,9 +84,7 @@ class ProductItem extends StatelessWidget {
116 child: Text( 84 child: Text(
117 '立即购买', 85 '立即购买',
118 style: TextStyle( 86 style: TextStyle(
119 - fontSize: 10.sp,  
120 - color: const Color(0xFF333333)  
121 - ), 87 + fontSize: 10.sp, color: const Color(0xFF333333)),
122 ), 88 ),
123 ), 89 ),
124 ) 90 )
@@ -129,4 +95,4 @@ class ProductItem extends StatelessWidget { @@ -129,4 +95,4 @@ class ProductItem extends StatelessWidget {
129 ), 95 ),
130 ); 96 );
131 } 97 }
132 -}  
133 \ No newline at end of file 98 \ No newline at end of file
  99 +}
lib/pages/shopping/view.dart
@@ -19,33 +19,31 @@ Widget buildRadioOption({ @@ -19,33 +19,31 @@ Widget buildRadioOption({
19 required bool isSelected, 19 required bool isSelected,
20 required ValueChanged onSelect, 20 required ValueChanged onSelect,
21 }) { 21 }) {
22 - return  
23 - GestureDetector(  
24 - onTap: () {  
25 - onSelect(value);  
26 - },  
27 - child: Row(  
28 - crossAxisAlignment: CrossAxisAlignment.center,  
29 - children: [  
30 - Image(image: icon, width: 25.0.w, height: 25.0.h, fit: BoxFit.contain),  
31 - const SizedBox(width: 10.0),  
32 - Expanded(  
33 - child: Text(  
34 - text,  
35 - style: TextStyle(color: const Color(0xFF333333), fontSize: 12.5.sp),  
36 - ), 22 + return GestureDetector(
  23 + onTap: () {
  24 + onSelect(value);
  25 + },
  26 + child: Row(
  27 + crossAxisAlignment: CrossAxisAlignment.center,
  28 + children: [
  29 + Image(image: icon, width: 25.0.w, height: 25.0.h, fit: BoxFit.contain),
  30 + const SizedBox(width: 10.0),
  31 + Expanded(
  32 + child: Text(
  33 + text,
  34 + style: TextStyle(color: const Color(0xFF333333), fontSize: 12.5.sp),
37 ), 35 ),
38 - Image(  
39 - image: isSelected  
40 - ? AssetImage('checked'.assetPng)  
41 - : AssetImage('unchecked'.assetPng),  
42 - width: 22.0.w,  
43 - height: 22.0.h,  
44 - ),  
45 - ],  
46 - ),  
47 - );  
48 - 36 + ),
  37 + Image(
  38 + image: isSelected
  39 + ? AssetImage('checked'.assetPng)
  40 + : AssetImage('unchecked'.assetPng),
  41 + width: 22.0.w,
  42 + height: 22.0.h,
  43 + ),
  44 + ],
  45 + ),
  46 + );
49 } 47 }
50 48
51 class ShoppingPage extends StatelessWidget { 49 class ShoppingPage extends StatelessWidget {
@@ -83,22 +81,22 @@ class _ShoppingView extends StatelessWidget { @@ -83,22 +81,22 @@ class _ShoppingView extends StatelessWidget {
83 child: Row( 81 child: Row(
84 crossAxisAlignment: CrossAxisAlignment.start, 82 crossAxisAlignment: CrossAxisAlignment.start,
85 children: [ 83 children: [
86 - CachedNetworkImage(  
87 - imageUrl: bloc.productData?.detailPicUrl ?? '',  
88 - imageBuilder: (context, imageProvider) => Container(  
89 - decoration: BoxDecoration(  
90 - image: DecorationImage(  
91 - image: imageProvider,  
92 - fit: BoxFit.cover,  
93 - ),  
94 - borderRadius: BorderRadius.circular(5.0), 84 + Container(
  85 + width: 210.w, // 图片宽度
  86 + height: 210.h, // 图片高度
  87 + decoration: BoxDecoration(
  88 + borderRadius: BorderRadius.circular(5.w),
  89 + // 圆角为5
  90 + border:
  91 + Border.all(width: 1.w, color: const Color(0xFF333333)),
  92 + // 边框宽度为1
  93 + // 使用ClipRRect圆角会有间隙,ClipRRect在裁剪时可能会导致圆角部分的边框显示不完整。
  94 + image: DecorationImage(
  95 + image: NetworkImage(bloc.productData?.detailPicUrl ?? ''),
  96 + // 图片地址
  97 + fit: BoxFit.cover, // 图片填充方式
95 ), 98 ),
96 ), 99 ),
97 - placeholder: (context, url) =>  
98 - const CircularProgressIndicator(),  
99 - // errorWidget: (context, url, error) => const Icon(Icons.error),  
100 - height: 210.0.h,  
101 - width: 210.0.w,  
102 ), 100 ),
103 const SizedBox(width: 35.5), 101 const SizedBox(width: 35.5),
104 Expanded(child: _paymentWidget()) 102 Expanded(child: _paymentWidget())
@@ -117,26 +115,21 @@ Widget _paymentWidget() => BlocBuilder<ShoppingBloc, ShoppingState>( @@ -117,26 +115,21 @@ Widget _paymentWidget() => BlocBuilder<ShoppingBloc, ShoppingState>(
117 crossAxisAlignment: CrossAxisAlignment.start, 115 crossAxisAlignment: CrossAxisAlignment.start,
118 children: [ 116 children: [
119 RichText( 117 RichText(
120 - text: TextSpan(  
121 - children: [  
122 - TextSpan(  
123 - text: '套餐价格:',  
124 - style:  
125 - TextStyle(color: const Color(0xFF333333), fontSize: 16.5.sp)  
126 - ),  
127 - TextSpan(  
128 - text: '¥${bloc.productData?.price ?? ''}',  
129 - style:  
130 - TextStyle(color: const Color(0xFFE5262A), fontSize: 16.5.sp)  
131 - ),  
132 - ]  
133 - ), 118 + text: TextSpan(children: [
  119 + TextSpan(
  120 + text: '套餐价格:',
  121 + style: TextStyle(
  122 + color: const Color(0xFF333333), fontSize: 16.5.sp)),
  123 + TextSpan(
  124 + text: '¥${bloc.productData?.price ?? ''}',
  125 + style: TextStyle(
  126 + color: const Color(0xFFE5262A), fontSize: 16.5.sp)),
  127 + ]),
134 ), 128 ),
135 const SizedBox(height: 14.5), 129 const SizedBox(height: 14.5),
136 Text( 130 Text(
137 '套餐名称:${bloc.productData?.name}', 131 '套餐名称:${bloc.productData?.name}',
138 - style:  
139 - TextStyle(color: const Color(0xFF333333), fontSize: 16.sp), 132 + style: TextStyle(color: const Color(0xFF333333), fontSize: 16.sp),
140 maxLines: 2, 133 maxLines: 2,
141 ), 134 ),
142 const SizedBox(height: 14.5), 135 const SizedBox(height: 14.5),
@@ -158,7 +151,8 @@ Widget _paymentWidget() => BlocBuilder<ShoppingBloc, ShoppingState>( @@ -158,7 +151,8 @@ Widget _paymentWidget() => BlocBuilder<ShoppingBloc, ShoppingState>(
158 value: PaymentChannel.wechatPay.payChannelType, 151 value: PaymentChannel.wechatPay.payChannelType,
159 icon: AssetImage('weixin'.assetPng), 152 icon: AssetImage('weixin'.assetPng),
160 text: PaymentChannel.wechatPay.payChannelName, 153 text: PaymentChannel.wechatPay.payChannelName,
161 - isSelected: bloc.curPaymentChannel.payChannelType == PaymentChannel.wechatPay.payChannelType, 154 + isSelected: bloc.curPaymentChannel.payChannelType ==
  155 + PaymentChannel.wechatPay.payChannelType,
162 onSelect: (newValue) { 156 onSelect: (newValue) {
163 bloc.add(ChangePaymentChannelEvent(PaymentChannel.wechatPay)); 157 bloc.add(ChangePaymentChannelEvent(PaymentChannel.wechatPay));
164 }, 158 },
@@ -168,7 +162,8 @@ Widget _paymentWidget() => BlocBuilder<ShoppingBloc, ShoppingState>( @@ -168,7 +162,8 @@ Widget _paymentWidget() => BlocBuilder<ShoppingBloc, ShoppingState>(
168 value: PaymentChannel.aliPay.payChannelType, 162 value: PaymentChannel.aliPay.payChannelType,
169 icon: AssetImage('zhifubao'.assetPng), 163 icon: AssetImage('zhifubao'.assetPng),
170 text: PaymentChannel.aliPay.payChannelName, 164 text: PaymentChannel.aliPay.payChannelName,
171 - isSelected: bloc.curPaymentChannel.payChannelType == PaymentChannel.aliPay.payChannelType, 165 + isSelected: bloc.curPaymentChannel.payChannelType ==
  166 + PaymentChannel.aliPay.payChannelType,
172 onSelect: (newValue) { 167 onSelect: (newValue) {
173 bloc.add(ChangePaymentChannelEvent(PaymentChannel.aliPay)); 168 bloc.add(ChangePaymentChannelEvent(PaymentChannel.aliPay));
174 }, 169 },
@@ -178,25 +173,26 @@ Widget _paymentWidget() => BlocBuilder<ShoppingBloc, ShoppingState>( @@ -178,25 +173,26 @@ Widget _paymentWidget() => BlocBuilder<ShoppingBloc, ShoppingState>(
178 mainAxisAlignment: MainAxisAlignment.spaceBetween, 173 mainAxisAlignment: MainAxisAlignment.spaceBetween,
179 children: [ 174 children: [
180 RichText( 175 RichText(
181 - text: TextSpan(  
182 - children: [  
183 - const TextSpan(  
184 - text: '需支付:',  
185 - style:  
186 - TextStyle(color: Color(0xFF333333), fontSize: 12.5, fontFamily: 'PingFangSC-Regular')  
187 - ),  
188 - TextSpan(  
189 - text: '¥${bloc.productData?.price ?? ''}',  
190 - style:  
191 - TextStyle(color: const Color(0xFFE7383B), fontSize: 41.sp, fontFamily: 'PingFangSC-Regular')  
192 - ),  
193 - ]  
194 - ), 176 + text: TextSpan(children: [
  177 + const TextSpan(
  178 + text: '需支付:',
  179 + style: TextStyle(
  180 + color: Color(0xFF333333),
  181 + fontSize: 12.5,
  182 + fontFamily: 'PingFangSC-Regular')),
  183 + TextSpan(
  184 + text: '¥${bloc.productData?.price ?? ''}',
  185 + style: TextStyle(
  186 + color: const Color(0xFFE7383B),
  187 + fontSize: 41.sp,
  188 + fontFamily: 'PingFangSC-Regular')),
  189 + ]),
195 ), 190 ),
196 // 确认支付按钮 191 // 确认支付按钮
197 GestureDetector( 192 GestureDetector(
198 onTap: () { 193 onTap: () {
199 - bloc.add(DoPayEvent(bloc.productData, bloc.curPaymentChannel)); 194 + bloc.add(
  195 + DoPayEvent(bloc.productData, bloc.curPaymentChannel));
200 }, 196 },
201 child: Image( 197 child: Image(
202 width: 105.w, 198 width: 105.w,