Flutter项目中如何根据服务器返回的支付网关名称自动加载本地Asset图片?
优化Flutter支付网关图片匹配方案
问题背景
我接触Flutter编程时间不长,仍在学习中。目前开发了一个展示用户购物清单的Flutter小程序,该程序从服务器数据库获取支付网关名称,希望根据返回的支付网关名称自动从程序的asset文件夹中调用对应图片并展示给用户。
现有代码
图片路径类(image.dart)
class Images { static const String bKash = 'assets/images/bkash.png'; static const String liqpay = 'assets/images/liqpay.png'; static const String mercadopago = 'assets/images/mercadopago.png'; static const String paymob = 'assets/images/paymob.png'; static const String paystack = 'assets/images/paystack.png'; static const String paytabs = 'assets/images/paytabs.png'; static const String razorpay = 'assets/images/razorpay.png'; static const String snangpay = 'assets/images/senang.png'; static const String sslCommerz = 'assets/images/ssl_commerz.png'; static const String stripe = 'assets/images/stripe.png'; static const String flutterwave = 'assets/images/flutterwave.png'; static const String fawryPay = 'assets/images/fawry_pay.png'; static const String cod = 'assets/images/cod.png'; static const String offlinePay = 'assets/images/offline_pay.png'; static const String walletPay = 'assets/images/wallet_pay.png'; }
图片展示代码
SizedBox( width: 80.0, height: 80.0, child: FittedBox( child: Image.asset( PaymentMethodImage, ), ), ),
原始冗长的if判断方案
if(paymentMethods!.bkash!) PaymentMethodImage = Images.bKash; if(paymentMethods!.liqpay!) PaymentMethodImage = Images.liqpay; if(paymentMethods!.mercadopago!) PaymentMethodImage = Images.mercadopago; if(paymentMethods!.paymobAccept!) PaymentMethodImage = Images.paymob; if(paymentMethods!.paystack!) PaymentMethodImage = Images.paystack; if(paymentMethods!.paytabs!) PaymentMethodImage = Images.paytabs; if(paymentMethods!.razorPay!) PaymentMethodImage = Images.razorpay; if(paymentMethods!.paypal!) PaymentMethodImage = Images.paypal; if(paymentMethods!.senangPay!) PaymentMethodImage = Images.snangpay; if(paymentMethods!.sslCommerzPayment!) PaymentMethodImage = Images.sslCommerz; if(paymentMethods!.stripe!) PaymentMethodImage = Images.stripe; if(paymentMethods!.flutterwave!) PaymentMethodImage = Images.flutterwave; if(paymentMethods!.fawryPay!) PaymentMethodImage = Images.fawryPay;
优化方案
方案1:使用Map建立名称与图片路径的映射
这是最简洁的方案,通过键值对直接关联服务器返回名称和图片路径,避免大量条件判断:
首先修改Images类,添加静态映射:
class Images { // 保留原有静态路径常量 static const String bKash = 'assets/images/bkash.png'; static const String liqpay = 'assets/images/liqpay.png'; static const String mercadopago = 'assets/images/mercadopago.png'; static const String paymob = 'assets/images/paymob.png'; static const String paystack = 'assets/images/paystack.png'; static const String paytabs = 'assets/images/paytabs.png'; static const String razorpay = 'assets/images/razorpay.png'; static const String snangpay = 'assets/images/senang.png'; static const String sslCommerz = 'assets/images/ssl_commerz.png'; static const String stripe = 'assets/images/stripe.png'; static const String flutterwave = 'assets/images/flutterwave.png'; static const String fawryPay = 'assets/images/fawry_pay.png'; static const String cod = 'assets/images/cod.png'; static const String offlinePay = 'assets/images/offline_pay.png'; static const String walletPay = 'assets/images/wallet_pay.png'; static const String defaultPay = 'assets/images/default_payment.png'; // 新增默认兜底图 // 建立支付网关名称与图片路径的映射 static const Map<String, String> paymentMethodMap = { 'bkash': bKash, 'liqpay': liqpay, 'mercadopago': mercadopago, 'paymobAccept': paymob, 'paystack': paystack, 'paytabs': paytabs, 'razorPay': razorpay, 'paypal': paypal, // 需在Images类补充paypal的路径定义 'senangPay': snangpay, 'sslCommerzPayment': sslCommerz, 'stripe': stripe, 'flutterwave': flutterwave, 'fawryPay': fawryPay, 'cod': cod, 'offlinePay': offlinePay, 'walletPay': walletPay, }; }
然后根据服务器返回的名称直接取值,同时添加默认图兜底:
// 假设从服务器拿到的支付网关名称为paymentGatewayName String paymentMethodImage = Images.paymentMethodMap[paymentGatewayName] ?? Images.defaultPay; // 展示图片 SizedBox( width: 80.0, height: 80.0, child: FittedBox( child: Image.asset(paymentMethodImage), ), ),
如果是通过paymentMethods对象的布尔属性判断启用的支付方式,可以遍历Map快速匹配:
String? paymentMethodImage; for (final entry in Images.paymentMethodMap.entries) { switch(entry.key) { case 'bkash': if (paymentMethods?.bkash == true) paymentMethodImage = entry.value; break; case 'liqpay': if (paymentMethods?.liqpay == true) paymentMethodImage = entry.value; break; // 其他支付方式依次匹配 default: break; } if (paymentMethodImage != null) break; // 找到后终止循环 } // 兜底默认图 paymentMethodImage ??= Images.defaultPay;
方案2:使用枚举类型(类型更安全)
通过枚举绑定支付方式名称和图片路径,能避免拼写错误,类型检查更严格:
enum PaymentMethod { bKash('assets/images/bkash.png'), liqpay('assets/images/liqpay.png'), mercadopago('assets/images/mercadopago.png'), paymob('assets/images/paymob.png'), paystack('assets/images/paystack.png'), paytabs('assets/images/paytabs.png'), razorpay('assets/images/razorpay.png'), snangpay('assets/images/senang.png'), sslCommerz('assets/images/ssl_commerz.png'), stripe('assets/images/stripe.png'), flutterwave('assets/images/flutterwave.png'), fawryPay('assets/images/fawry_pay.png'), cod('assets/images/cod.png'), offlinePay('assets/images/offline_pay.png'), walletPay('assets/images/wallet_pay.png'), defaultPay('assets/images/default_payment.png'); final String imagePath; const PaymentMethod(this.imagePath); // 从服务器返回的名称转换为枚举 static PaymentMethod fromName(String name) { return values.firstWhere( (method) => method.name == name, orElse: () => defaultPay, ); } }
使用时直接转换枚举并获取图片路径:
PaymentMethod method = PaymentMethod.fromName(paymentGatewayName); String paymentMethodImage = method.imagePath; // 展示图片 SizedBox( width: 80.0, height: 80.0, child: FittedBox( child: Image.asset(paymentMethodImage), ), ),
方案3:扩展方法(封装原有判断逻辑)
如果不想改动太多原有代码,可以给paymentMethods对应的类添加扩展方法,把判断逻辑封装起来:
// 假设paymentMethods的类型是PaymentMethods extension PaymentMethodsExtension on PaymentMethods { String get paymentMethodImage { if (bkash == true) return Images.bKash; if (liqpay == true) return Images.liqpay; if (mercadopago == true) return Images.mercadopago; if (paymobAccept == true) return Images.paymob; if (paystack == true) return Images.paystack; if (paytabs == true) return Images.paytabs; if (razorPay == true) return Images.razorpay; if (paypal == true) return Images.paypal; if (senangPay == true) return Images.snangpay; if (sslCommerzPayment == true) return Images.sslCommerz; if (stripe == true) return Images.stripe; if (flutterwave == true) return Images.flutterwave; if (fawryPay == true) return Images.fawryPay; return 'assets/images/default_payment.png'; } }
使用时直接调用扩展方法:
String paymentMethodImage = paymentMethods!.paymentMethodImage;
内容的提问来源于stack exchange,提问作者reza kia
相关产品推荐
相关产品推荐

