Commit 2caf589685277c324393bd60536dd9b8eedb7d33
1 parent
ad37b653
feat:商品列表图片优化
Showing
2 changed files
with
103 additions
and
141 deletions
lib/pages/shop/home/widgets/product_item.dart
| ... | ... | @@ -4,8 +4,7 @@ import 'package:flutter_screenutil/flutter_screenutil.dart'; |
| 4 | 4 | import 'package:wow_english/models/product_entity.dart'; |
| 5 | 5 | |
| 6 | 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 | 9 | final ProductEntity? entity; |
| 11 | 10 | |
| ... | ... | @@ -15,52 +14,27 @@ class ProductItem extends StatelessWidget { |
| 15 | 14 | Widget build(BuildContext context) { |
| 16 | 15 | return Container( |
| 17 | 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 | 20 | child: Row( |
| 32 | 21 | mainAxisAlignment: MainAxisAlignment.spaceBetween, |
| 33 | 22 | children: [ |
| 34 | 23 | Container( |
| 35 | - width: 124.w, | |
| 24 | + width: 124.w, // 图片宽度 | |
| 25 | + height: 124.h, // 图片高度 | |
| 36 | 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 | 38 | 21.5.horizontalSpace, |
| 65 | 39 | Expanded( |
| 66 | 40 | child: Column( |
| ... | ... | @@ -72,29 +46,24 @@ class ProductItem extends StatelessWidget { |
| 72 | 46 | softWrap: true, |
| 73 | 47 | textAlign: TextAlign.left, |
| 74 | 48 | style: TextStyle( |
| 75 | - fontSize: 12.sp, | |
| 76 | - color: const Color(0xFF333333) | |
| 77 | - ), | |
| 49 | + fontSize: 16.sp, color: const Color(0xFF333333)), | |
| 78 | 50 | ), |
| 79 | 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 | 68 | GestureDetector( |
| 100 | 69 | onTap: () { |
| ... | ... | @@ -107,8 +76,7 @@ class ProductItem extends StatelessWidget { |
| 107 | 76 | border: Border.all( |
| 108 | 77 | color: const Color(0xFF333333), |
| 109 | 78 | width: 1.0, |
| 110 | - ) | |
| 111 | - ), | |
| 79 | + )), | |
| 112 | 80 | padding: EdgeInsets.symmetric( |
| 113 | 81 | vertical: 1.h, |
| 114 | 82 | horizontal: 26.5.w, |
| ... | ... | @@ -116,9 +84,7 @@ class ProductItem extends StatelessWidget { |
| 116 | 84 | child: Text( |
| 117 | 85 | '立即购买', |
| 118 | 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 | 95 | ), |
| 130 | 96 | ); |
| 131 | 97 | } |
| 132 | -} | |
| 133 | 98 | \ No newline at end of file |
| 99 | +} | ... | ... |
lib/pages/shopping/view.dart
| ... | ... | @@ -19,33 +19,31 @@ Widget buildRadioOption({ |
| 19 | 19 | required bool isSelected, |
| 20 | 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 | 49 | class ShoppingPage extends StatelessWidget { |
| ... | ... | @@ -83,22 +81,22 @@ class _ShoppingView extends StatelessWidget { |
| 83 | 81 | child: Row( |
| 84 | 82 | crossAxisAlignment: CrossAxisAlignment.start, |
| 85 | 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 | 101 | const SizedBox(width: 35.5), |
| 104 | 102 | Expanded(child: _paymentWidget()) |
| ... | ... | @@ -117,26 +115,21 @@ Widget _paymentWidget() => BlocBuilder<ShoppingBloc, ShoppingState>( |
| 117 | 115 | crossAxisAlignment: CrossAxisAlignment.start, |
| 118 | 116 | children: [ |
| 119 | 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 | 129 | const SizedBox(height: 14.5), |
| 136 | 130 | Text( |
| 137 | 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 | 133 | maxLines: 2, |
| 141 | 134 | ), |
| 142 | 135 | const SizedBox(height: 14.5), |
| ... | ... | @@ -158,7 +151,8 @@ Widget _paymentWidget() => BlocBuilder<ShoppingBloc, ShoppingState>( |
| 158 | 151 | value: PaymentChannel.wechatPay.payChannelType, |
| 159 | 152 | icon: AssetImage('weixin'.assetPng), |
| 160 | 153 | text: PaymentChannel.wechatPay.payChannelName, |
| 161 | - isSelected: bloc.curPaymentChannel.payChannelType == PaymentChannel.wechatPay.payChannelType, | |
| 154 | + isSelected: bloc.curPaymentChannel.payChannelType == | |
| 155 | + PaymentChannel.wechatPay.payChannelType, | |
| 162 | 156 | onSelect: (newValue) { |
| 163 | 157 | bloc.add(ChangePaymentChannelEvent(PaymentChannel.wechatPay)); |
| 164 | 158 | }, |
| ... | ... | @@ -168,7 +162,8 @@ Widget _paymentWidget() => BlocBuilder<ShoppingBloc, ShoppingState>( |
| 168 | 162 | value: PaymentChannel.aliPay.payChannelType, |
| 169 | 163 | icon: AssetImage('zhifubao'.assetPng), |
| 170 | 164 | text: PaymentChannel.aliPay.payChannelName, |
| 171 | - isSelected: bloc.curPaymentChannel.payChannelType == PaymentChannel.aliPay.payChannelType, | |
| 165 | + isSelected: bloc.curPaymentChannel.payChannelType == | |
| 166 | + PaymentChannel.aliPay.payChannelType, | |
| 172 | 167 | onSelect: (newValue) { |
| 173 | 168 | bloc.add(ChangePaymentChannelEvent(PaymentChannel.aliPay)); |
| 174 | 169 | }, |
| ... | ... | @@ -178,25 +173,26 @@ Widget _paymentWidget() => BlocBuilder<ShoppingBloc, ShoppingState>( |
| 178 | 173 | mainAxisAlignment: MainAxisAlignment.spaceBetween, |
| 179 | 174 | children: [ |
| 180 | 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 | 192 | GestureDetector( |
| 198 | 193 | onTap: () { |
| 199 | - bloc.add(DoPayEvent(bloc.productData, bloc.curPaymentChannel)); | |
| 194 | + bloc.add( | |
| 195 | + DoPayEvent(bloc.productData, bloc.curPaymentChannel)); | |
| 200 | 196 | }, |
| 201 | 197 | child: Image( |
| 202 | 198 | width: 105.w, | ... | ... |