problem_card.dart 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. import 'package:flutter/material.dart';
  2. import '../models/problem.dart';
  3. /// 题目列表卡片
  4. class ProblemCard extends StatelessWidget {
  5. final Problem problem;
  6. final bool isSelected;
  7. final bool isInCart;
  8. final VoidCallback onTap;
  9. final ValueChanged<String> onAddToCart;
  10. final ValueChanged<String>? onRemoveFromCart;
  11. const ProblemCard({
  12. super.key,
  13. required this.problem,
  14. this.isSelected = false,
  15. this.isInCart = false,
  16. required this.onTap,
  17. required this.onAddToCart,
  18. this.onRemoveFromCart,
  19. });
  20. @override
  21. Widget build(BuildContext context) {
  22. return Card(
  23. margin: const EdgeInsets.symmetric(horizontal: 8, vertical: 2),
  24. color: isSelected ? Theme.of(context).colorScheme.primaryContainer : null,
  25. child: ListTile(
  26. dense: true,
  27. leading: _typeIcon(),
  28. title: Text(
  29. '${problem.questionType} · ${problem.difficultyLabel}(${problem.difficulty})',
  30. style: const TextStyle(fontSize: 13),
  31. ),
  32. subtitle: Text(
  33. 'ID: ${problem.id}',
  34. style: TextStyle(fontSize: 11, color: Colors.grey.shade600),
  35. ),
  36. trailing: Row(
  37. mainAxisSize: MainAxisSize.min,
  38. children: [
  39. if (!problem.isAnnotated)
  40. const Icon(Icons.warning_amber, size: 16, color: Colors.orange),
  41. if (isInCart)
  42. IconButton(
  43. icon: const Icon(Icons.remove_shopping_cart, size: 18, color: Colors.red),
  44. onPressed: () => onRemoveFromCart?.call(problem.id),
  45. tooltip: '从试题篮移除',
  46. )
  47. else
  48. IconButton(
  49. icon: const Icon(Icons.add_shopping_cart, size: 18),
  50. onPressed: () => onAddToCart(problem.id),
  51. tooltip: '加入试题篮',
  52. ),
  53. ],
  54. ),
  55. onTap: onTap,
  56. ),
  57. );
  58. }
  59. Widget _typeIcon() {
  60. IconData icon;
  61. Color color;
  62. switch (problem.questionType) {
  63. case '单选题':
  64. icon = Icons.radio_button_checked;
  65. color = Colors.blue;
  66. break;
  67. case '多选题':
  68. icon = Icons.check_box;
  69. color = Colors.purple;
  70. break;
  71. case '填空题':
  72. icon = Icons.edit_note;
  73. color = Colors.orange;
  74. break;
  75. case '解答题':
  76. icon = Icons.assignment;
  77. color = Colors.green;
  78. break;
  79. default:
  80. icon = Icons.question_mark;
  81. color = Colors.grey;
  82. }
  83. return Icon(icon, color: color, size: 20);
  84. }
  85. }