我希望你一切都好。我有一个小问题,我想根据另一个 DropdownButton 的值动态改变一个 DropdownButton 的值。
好吧,我将解释我在哪里以及问题是什么:
首先,我有一个包含 3 个元素的StudyCycle列表;
final _studyCycles = const <StudyCycle>[
StudyCycle(cycle: Cycles.elementary, classrooms: <ClassroomsLevels>[
ClassroomsLevels.cp,
ClassroomsLevels.ce1,
ClassroomsLevels.ce2,
ClassroomsLevels.cm1,
ClassroomsLevels.cm2,
]),
StudyCycle(cycle: Cycles.primary, classrooms: <ClassroomsLevels>[
ClassroomsLevels.sixth,
ClassroomsLevels.fifth,
ClassroomsLevels.fourth,
ClassroomsLevels.third,
]),
StudyCycle(cycle: Cycles.secondary, classrooms: <ClassroomsLevels>[
ClassroomsLevels.second,
ClassroomsLevels.first,
ClassroomsLevels.terminal,
])
];
这个StudyCycle列表用于构建第一个 DropdownButton
DropdownButton<StudyCycle>(
value: _selectedStudyCycle,
items: List<DropdownMenuItem<StudyCycle>>.generate(
_studyCycles.length,
(index) => DropdownMenuItem<StudyCycle>(
value: _studyCycles[index],
child: Text(_studyCycles[index].cycle.toString()),
),
),
hint: const Text('Your Study Cycle'),
onChanged: (StudyCycle? studyCycle) {
if (studyCycle != _selectedStudyCycle) {
if (_selectedStudyCycle != null) setState(() => _selectedStudyCycle = null);
if (studyCycle != null) setState(() => _selectedStudyCycle = studyCycle);
}
},
)
并且通过从StudyCycles Dropdown中选择一个StudyCycle,它允许构建另一个 DropdownButton 的值,其中这次包含当前在StudyCycles Dropdown中选择的StudyCycle的ClassroomsLevels(到目前为止一切都很好)
DropdownButton<ClassroomsLevels>(
hint: const Text('Select your classroom'),
value: _selectedClassroom,
items: _selectedStudyCycle == null
? []
: List<DropdownMenuItem<ClassroomsLevels>>.generate(
_selectedStudyCycle!.classrooms.length,
(index) => DropdownMenuItem<ClassroomsLevels>(
value: _selectedStudyCycle!.classrooms[index],
child: Text(_selectedStudyCycle!.classrooms[index].toString()),
),
),
onChanged: (ClassroomsLevels? classroom) => setState(() => _selectedClassroom = classroom),
)
选择ClassroomLevel并更改StudyCycle时会出现问题,我收到此错误:
There should be exactly one item with [DropdownButton]'s value: ClassroomsLevels.fourth.
Either zero or 2 or more [DropdownMenuItem]s were detected with the same value
'package:flutter/src/material/dropdown.dart':
Failed assertion: line 915 pos 15: 'items == null || items.isEmpty || value == null ||
items.where((DropdownMenuItem<T> item) {
return item.value == value;
}).length == 1'
我尽力解决了这个问题,但我不能(而且我真的不明白为什么),所以我依靠你。你能帮我理解错误是什么以及如何解决它吗?
完整的代码
import 'package:flutter/material.dart';
class MyHomePage2 extends StatefulWidget {
const MyHomePage2({Key? key, required this.title}) : super(key: key);
final String title;
@override
State<MyHomePage2> createState() => _MyHomePage2State();
}
class _MyHomePage2State extends State<MyHomePage2> {
final _studyCycles = const <StudyCycle>[
StudyCycle(cycle: Cycles.elementary, classrooms: <ClassroomsLevels>[
ClassroomsLevels.cp,
ClassroomsLevels.ce1,
ClassroomsLevels.ce2,
ClassroomsLevels.cm1,
ClassroomsLevels.cm2,
]),
StudyCycle(cycle: Cycles.primary, classrooms: <ClassroomsLevels>[
ClassroomsLevels.sixth,
ClassroomsLevels.fifth,
ClassroomsLevels.fourth,
ClassroomsLevels.third,
]),
StudyCycle(cycle: Cycles.secondary, classrooms: <ClassroomsLevels>[
ClassroomsLevels.second,
ClassroomsLevels.first,
ClassroomsLevels.terminal,
])
];
StudyCycle? _selectedStudyCycle;
ClassroomsLevels? _selectedClassroom;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text(widget.title)),
body: SizedBox(
width: MediaQuery.of(context).size.width,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
DropdownButton<StudyCycle>(
value: _selectedStudyCycle,
items: List<DropdownMenuItem<StudyCycle>>.generate(
_studyCycles.length,
(index) => DropdownMenuItem<StudyCycle>(
value: _studyCycles[index],
child: Text(_studyCycles[index].cycle.toString()),
),
),
hint: const Text('Your Study Cycle'),
onChanged: (StudyCycle? studyCycle) {
if (studyCycle != _selectedStudyCycle) {
if (_selectedStudyCycle != null) setState(() => _selectedStudyCycle = null);
if (studyCycle != null) setState(() => _selectedStudyCycle = studyCycle);
}
},
),
//
DropdownButton<ClassroomsLevels>(
hint: const Text('Select your classroom'),
value: _selectedClassroom,
items: _selectedStudyCycle == null
? []
: List<DropdownMenuItem<ClassroomsLevels>>.generate(
_selectedStudyCycle!.classrooms.length,
(index) => DropdownMenuItem<ClassroomsLevels>(
value: _selectedStudyCycle!.classrooms[index],
child: Text(_selectedStudyCycle!.classrooms[index].toString()),
),
),
onChanged: (ClassroomsLevels? classroom) => setState(() => _selectedClassroom = classroom),
),
],
),
),
);
}
}
class StudyCycle {
final Cycles cycle;
final List<ClassroomsLevels> classrooms;
final String? description;
final int? iconCodePoint;
const StudyCycle({
required this.cycle,
required this.classrooms,
this.description,
this.iconCodePoint,
});
}
enum Cycles { elementary, primary, secondary, secondaryTechnique }
enum ClassroomsLevels {
cp,
ce1,
ce2,
cm1,
cm2,
sixth,
fifth,
fourth,
third,
second,
first,
terminal,
mechanical,
electronic,
electricity,
inEngineering,
secretariat,
accounting,
economy,
agr1,
agr2,
agr3,
}
谢谢你!