Flutter射箭计分表添加第二轮计分列的实现求助
解决方案:实现两轮射箭计分表并排布局
先修正你原有代码里的一个明显错误:Target 7绑定了num8controller,Target 20绑定了num7controller,这会导致计分混乱,重构时会一并修复。
核心思路是把单轮的计分区域封装成可复用组件,再用Row将两个单轮组件横向排列,既保持代码整洁,也避免布局嵌套错误。以下是完整的实现代码:
import 'package:flutter/material.dart'; void main() => runApp(const MyApp()); class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { const appTitle = 'Twin City Bowmen Score Sheet'; return MaterialApp( title: appTitle, home: Scaffold( appBar: AppBar(title: const Text(appTitle)), body: const ScoreSheet(), ), ); } } class ScoreSheet extends StatefulWidget { const ScoreSheet({super.key}); @override State<ScoreSheet> createState() => _ScoreSheetState(); } class _ScoreSheetState extends State<ScoreSheet> { // 第一轮20个靶位的控制器 final List<TextEditingController> round1Controllers = List.generate(20, (_) => TextEditingController()); // 第二轮20个靶位的控制器 final List<TextEditingController> round2Controllers = List.generate(20, (_) => TextEditingController()); String round1Result = '0'; String round2Result = '0'; String totalResult = '0'; // 计算单轮总分 int calculateRoundScore(List<TextEditingController> controllers) { return controllers.fold(0, (sum, controller) { return sum + (int.tryParse(controller.text) ?? 0); }); } void calculateAllScores() { setState(() { final r1 = calculateRoundScore(round1Controllers); final r2 = calculateRoundScore(round2Controllers); round1Result = r1.toString(); round2Result = r2.toString(); totalResult = (r1 + r2).toString(); }); } @override Widget build(BuildContext context) { return SingleChildScrollView( padding: const EdgeInsets.all(16), child: Column( children: [ // 横向排列两轮计分区域 Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ // 第一轮计分列 Expanded( child: ScoreColumn( roundName: '第一轮', controllers: round1Controllers, ), ), const SizedBox(width: 16), // 第二轮计分列 Expanded( child: ScoreColumn( roundName: '第二轮', controllers: round2Controllers, ), ), ], ), const SizedBox(height: 24), // 计算按钮 ElevatedButton( onPressed: calculateAllScores, child: const Text('计算总分'), ), const SizedBox(height: 16), // 总分展示 Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ Column( children: [ const Text('第一轮总分:', style: TextStyle(fontSize: 18)), Text(round1Result, style: const TextStyle(fontSize: 24, fontWeight: FontWeight.bold)), ], ), Column( children: [ const Text('第二轮总分:', style: TextStyle(fontSize: 18)), Text(round2Result, style: const TextStyle(fontSize: 24, fontWeight: FontWeight.bold)), ], ), Column( children: [ const Text('总合计:', style: TextStyle(fontSize: 18)), Text(totalResult, style: const TextStyle(fontSize: 24, fontWeight: FontWeight.bold, color: Colors.red)), ], ), ], ), ], ), ); } @override void dispose() { // 销毁所有控制器,避免内存泄漏 for (var controller in round1Controllers) { controller.dispose(); } for (var controller in round2Controllers) { controller.dispose(); } super.dispose(); } } // 可复用的单轮计分列组件 class ScoreColumn extends StatelessWidget { final String roundName; final List<TextEditingController> controllers; const ScoreColumn({ super.key, required this.roundName, required this.controllers, }); @override Widget build(BuildContext context) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(roundName, style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold)), const SizedBox(height: 8), // 生成20个靶位行 ...List.generate(20, (index) { return Padding( padding: const EdgeInsets.symmetric(vertical: 4), child: Row( children: [ SizedBox( width: 80, child: Text('Target ${index + 1}:'), ), Expanded( child: TextField( keyboardType: TextInputType.number, controller: controllers[index], textAlign: TextAlign.center, decoration: const InputDecoration( border: OutlineInputBorder(), contentPadding: EdgeInsets.symmetric(vertical: 8), ), ), ), ], ), ); }), ], ); } }
关键优化点说明
- 组件复用:将单轮计分区域封装为
ScoreColumn,避免重复代码,也方便后续扩展多轮需求 - 控制器管理:用列表存储两轮的控制器,替代单个变量命名,更易维护
- 布局结构:用
Row包裹两个Expanded的ScoreColumn,保证两列平分宽度,避免布局溢出 - 错误处理:使用
int.tryParse替代int.parse,防止空输入导致的崩溃 - 内存管理:在
dispose方法中销毁所有控制器,避免内存泄漏
内容的提问来源于stack exchange,提问作者securityNVR NVR
相关产品推荐
相关产品推荐

