[英]In Flutter, how to make a user selected dropdown menu option leads to a specific route?
New coder here that's self-taught, so I apologize in advance if my questions is confusing or does not use the right coding terms.这里的新编码员是自学的,所以如果我的问题令人困惑或没有使用正确的编码术语,我提前道歉。
I am trying to create a practice app on flutter, user can select different aspect of the game they like and the app will suggest a game that suit them.我正在尝试在 flutter 上创建一个练习应用程序,用户可以 select 他们喜欢的游戏的不同方面,该应用程序会建议适合他们的游戏。
For the purpose of this app, I will have like 10 games pre-selected to suggest to users.出于这个应用程序的目的,我将预先选择 10 款游戏来推荐给用户。
I have 2 dropdown widget: Genre and difficulty.我有 2 个下拉小部件:类型和难度。
Here is my code:这是我的代码:
//dropdown menu for game genre
class DropDown1Widget extends StatefulWidget {
DropDown1Widget({Key key}) : super(key: key);
@override
_DropDown1WidgetState createState() => _DropDown1WidgetState();
}
class _DropDown1WidgetState extends State<DropDown1Widget> {
String dropdownValue = 'RPG';
@override
Widget build(BuildContext context) {
return DropdownButton<String>(
value: dropdownValue,
icon: Icon(Icons.arrow_drop_down),
iconSize: 24,
elevation: 16,
style: TextStyle(fontWeight: FontWeight.bold, color: Colors.deepPurple),
underline: Container(
height: 2,
color: Colors.deepPurpleAccent,
),
onChanged: (String newValue) {
setState(() {
dropdownValue = newValue;
});
},
items: <String>[
'RPG',
'Shooting',
'Sport',
'Racing',
'Random!'
].map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
);
}
}
//Drop down menu 2 for difficulty level
class DropDown2Widget extends StatefulWidget {
DropDown2Widget({Key key}) : super(key: key);
@override
_DropDown2WidgetState createState() => _DropDown2WidgetState();
}
class _DropDown2WidgetState extends State<DropDown2Widget> {
String dropdownValue = 'Hard';
@override
Widget build(BuildContext context) {
return DropdownButton<String>(
value: dropdownValue,
icon: Icon(Icons.arrow_drop_down),
iconSize: 24,
elevation: 16,
style: TextStyle(fontWeight: FontWeight.bold, color: Colors.pink),
underline: Container(
height: 2,
color: Colors.pinkAccent,
),
onChanged: (String newValue) {
setState(() {
dropdownValue = newValue;
});
},
items: <String>['Hard', 'Intermediate', 'Easy', 'Random!']
.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
);
}
}
So far I just have these 2 dropdownmenu widgets placed in one of my routes, but I would like for it to lead to a specific route when user select a specific combination of the dropdown menus and press submit.到目前为止,我只是将这 2 个下拉菜单小部件放置在我的一条路线中,但我希望它在用户 select 下拉菜单的特定组合并按提交时引导到特定路线。
For example, if an user selects genre: RPG, difficulty level: Hard, and presses "submit" (I also have a onPress button waiting to take the user to the specific route), it would take them to a route that shows "Dark Soul 2".例如,如果用户选择类型:RPG,难度级别:Hard,然后按“提交”(我还有一个 onPress 按钮等待将用户带到特定路线),它会将他们带到显示“黑暗灵魂 2"。
I am guessing I have to do some if-else codes, but i am not sure how to implement it.我猜我必须做一些 if-else 代码,但我不确定如何实现它。
Also, if user select "Random" for the dropdownmenu, how do i implement random selection of the routes that the app leads to?此外,如果用户 select 为下拉菜单“随机”,我如何实现应用程序引导的路由的随机选择?
Sorry for the wordy question, still have a lot to learn.抱歉这个冗长的问题,还有很多东西要学。
You can handle the route navigation using any package or a basic onGenerateRoute()
.您可以使用任何 package 或基本的
onGenerateRoute()
来处理路线导航。 Here I have used a quick hack to show the concept, which is an example of how not to do things.在这里,我使用了一个快速的技巧来展示这个概念,这是一个如何不做事的例子。 So, replace route generation logic with more robust code.
因此,用更健壮的代码替换路由生成逻辑。
main() async {
runApp(MyApp());
}
String makeGenreLevelName(Genre genre, DifficultyLevel level) => '${describeEnum(genre)}_${describeEnum(level)}';
Map<String, Widget Function(BuildContext)> routes;
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
if (routes == null) {
routes = {'/': (context) => SO()}; //HACK
Genre.values.forEach(
(g) {
DifficultyLevel.values.forEach(
(l) {
routes[makeGenreLevelName(g, l)] = (context) => //
Scaffold(appBar: AppBar(title: Text(makeGenreLevelName(g, l))));
},
);
},
);
}
return MaterialApp(
routes: routes, //use onGenerateRoute or any other logic instead of HACK
initialRoute: '/',
);
}
}
class SO extends StatelessWidget {
Genre selectedGenre = Genre.Random;
DifficultyLevel selectedDiffLevel = DifficultyLevel.Random;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Center(
child: IntrinsicWidth(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
GenreDDWidget(
initial: selectedGenre,
onItemChange: (Genre g) => selectedGenre = g,
),
LevelDDWidget(
initial: selectedDiffLevel,
onItemChange: (DifficultyLevel d) => selectedDiffLevel = d,
),
],
),
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
print('-' * 20);
print('Selected Genre: $selectedGenre');
print('Selected Level: $selectedDiffLevel');
var playGenre = selectedGenre;
var playLevel = selectedDiffLevel;
assert(!(Genre.values.length == 1 && Genre.values.first == Genre.Random));
assert(!(DifficultyLevel.values.length == 1 && DifficultyLevel.values.first == DifficultyLevel.Random));
while (playGenre == Genre.Random) playGenre = (Genre.values.toList()..shuffle()).first;
while (playLevel == DifficultyLevel.Random) playLevel = (DifficultyLevel.values.toList()..shuffle()).first;
// the genre and the level for upcoming game in the next screen
print('Upcoming Game Genre: $playGenre');
print('Upcoming Game Level: $playLevel');
Navigator.pushNamed(context, makeGenreLevelName(playGenre, playLevel));
},
),
);
}
}
class GenreDDWidget extends StatefulWidget {
final Function(Genre) onItemChange;
final Genre initial;
GenreDDWidget({Key key, this.onItemChange, this.initial}) : super(key: key);
@override
_GenreDDWidgetState createState() => _GenreDDWidgetState(initial);
}
class _GenreDDWidgetState extends State<GenreDDWidget> {
Genre dropdownValue;
_GenreDDWidgetState(this.dropdownValue);
@override
Widget build(BuildContext context) {
return DropdownButton<Genre>(
value: dropdownValue,
icon: Icon(Icons.arrow_drop_down),
iconSize: 24,
elevation: 16,
style: TextStyle(fontWeight: FontWeight.bold, color: Colors.deepPurple),
underline: Container(
height: 2,
color: Colors.deepPurpleAccent,
),
isExpanded: true,
onChanged: (value) {
setState(() => dropdownValue = value);
widget.onItemChange(value);
},
items: Genre.values
.map(
(value) => DropdownMenuItem(
value: value,
child: Text(describeEnum(value)),
),
)
.toList(),
);
}
}
//Drop down menu 2 for difficulty level
class LevelDDWidget extends StatefulWidget {
final Function(DifficultyLevel) onItemChange;
final DifficultyLevel initial;
LevelDDWidget({Key key, this.onItemChange, this.initial}) : super(key: key);
@override
_LevelDDWidgetState createState() => _LevelDDWidgetState(initial);
}
class _LevelDDWidgetState extends State<LevelDDWidget> {
DifficultyLevel dropdownValue;
_LevelDDWidgetState(this.dropdownValue);
@override
Widget build(BuildContext context) {
return DropdownButton<DifficultyLevel>(
value: dropdownValue,
icon: Icon(Icons.arrow_drop_down),
iconSize: 24,
elevation: 16,
style: TextStyle(fontWeight: FontWeight.bold, color: Colors.pink),
underline: Container(
height: 2,
color: Colors.pinkAccent,
),
isExpanded: true,
onChanged: (value) {
setState(() => dropdownValue = value);
widget.onItemChange(value);
},
items: DifficultyLevel.values
.map(
(value) => DropdownMenuItem(
value: value,
child: Text(describeEnum(value)),
),
)
.toList(),
);
}
}
enum Genre {
RPG,
Shooting,
Sport,
Racing,
Random,
}
enum DifficultyLevel {
Hard,
Intermediate,
Easy,
Random,
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.