11// ignore_for_file: prefer_const_constructors, prefer_const_literals_to_create_immutables
2+ import 'dart:ffi' ;
23import 'dart:io' ;
34import 'dart:math' ;
45import 'package:flutter/material.dart' ;
56import 'package:provider/provider.dart' ;
67import 'package:sprintf/sprintf.dart' ;
8+ import 'settings_card.dart' ;
79
810// BIN 1 1111 1111 1111 0000 0000 0000 = DEC 33550336
911// 众人将与一人离别,惟其人将觐见奇迹
@@ -20,21 +22,52 @@ randomGen(min, max) {
2022 return x.floor ();
2123}
2224
25+ pass (){
26+ return Void ;
27+ }
28+
2329class MyApp extends StatelessWidget {
30+
2431 const MyApp ({super .key});
2532
2633 @override
2734 Widget build (BuildContext context) {
2835 return ChangeNotifierProvider (
2936 create: (context) => MyAppState (),
30- child: MaterialApp (
31- title: 'NamePicker' ,
32- theme: ThemeData (
33- useMaterial3: true ,
34- colorScheme: ColorScheme .fromSeed (seedColor: const Color .fromARGB (255 , 195 , 255 , 185 )),
35- fontFamily: "HarmonyOS_Sans_SC"
36- ),
37- home: MyHomePage (),
37+ child: Consumer <MyAppState >(
38+ builder: (context, appState, _) {
39+ ThemeMode themeMode;
40+ switch (appState.themeMode) {
41+ case 0 :
42+ themeMode = ThemeMode .system;
43+ break ;
44+ case 1 :
45+ themeMode = ThemeMode .light;
46+ break ;
47+ case 2 :
48+ themeMode = ThemeMode .dark;
49+ break ;
50+ default :
51+ themeMode = ThemeMode .system;
52+ }
53+ return MaterialApp (
54+ title: 'NamePicker' ,
55+ theme: ThemeData (
56+ useMaterial3: true ,
57+ useSystemColors: true ,
58+ fontFamily: "HarmonyOS_Sans_SC" ,
59+ brightness: Brightness .light,
60+ ),
61+ darkTheme: ThemeData (
62+ useMaterial3: true ,
63+ useSystemColors: true ,
64+ fontFamily: "HarmonyOS_Sans_SC" ,
65+ brightness: Brightness .dark,
66+ ),
67+ themeMode: themeMode,
68+ home: MyHomePage (),
69+ );
70+ },
3871 ),
3972 );
4073 }
@@ -46,29 +79,33 @@ class MyAppState extends ChangeNotifier {
4679
4780 GlobalKey ? historyListKey;
4881
82+ // 0: 跟随系统 1: 亮色 2: 暗色
83+ int themeMode = 0 ;
84+ int minValue = 0 ;
85+ int maxValue = 20 ;
86+
87+ void setThemeMode (int mode) {
88+ themeMode = mode;
89+ notifyListeners ();
90+ }
91+
4992 void getNext () {
5093 history.insert (0 , current);
5194 var animatedList = historyListKey? .currentState as AnimatedListState ? ;
5295 // var names = ["sunxiaochuan","fxpick","abcdccb"];
5396 animatedList? .insertItem (0 );
54- current = sprintf ("%s" ,[randomGen (0 , 20 )]);
97+ current = sprintf ("%s" ,[randomGen (minValue, maxValue )]);
5598 notifyListeners ();
5699 }
57100
58- var favorites = < String > [];
59-
60- void toggleFavorite ([String ? pair]) {
61- pair = pair ?? current;
62- if (favorites.contains (pair)) {
63- favorites.remove (pair);
64- } else {
65- favorites.add (pair);
101+ void setRange (int min, int max) {
102+ if (min > max) {
103+ final tmp = min;
104+ min = max;
105+ max = tmp;
66106 }
67- notifyListeners ();
68- }
69-
70- void removeFavorite (String pair) {
71- favorites.remove (pair);
107+ minValue = min;
108+ maxValue = max;
72109 notifyListeners ();
73110 }
74111}
@@ -197,7 +234,38 @@ class _MyHomePageState extends State<MyHomePage> {
197234 }
198235}
199236
200- class GeneratorPage extends StatelessWidget {
237+ class GeneratorPage extends StatefulWidget {
238+ @override
239+ State <GeneratorPage > createState () => _GeneratorPageState ();
240+ }
241+
242+ class _GeneratorPageState extends State <GeneratorPage > {
243+ late TextEditingController minController;
244+ late TextEditingController maxController;
245+
246+ @override
247+ void initState () {
248+ super .initState ();
249+ final appState = Provider .of <MyAppState >(context, listen: false );
250+ minController = TextEditingController (text: appState.minValue.toString ());
251+ maxController = TextEditingController (text: appState.maxValue.toString ());
252+ }
253+
254+ @override
255+ void didChangeDependencies () {
256+ super .didChangeDependencies ();
257+ final appState = Provider .of <MyAppState >(context, listen: false );
258+ minController.text = appState.minValue.toString ();
259+ maxController.text = appState.maxValue.toString ();
260+ }
261+
262+ @override
263+ void dispose () {
264+ minController.dispose ();
265+ maxController.dispose ();
266+ super .dispose ();
267+ }
268+
201269 @override
202270 Widget build (BuildContext context) {
203271 var appState = context.watch <MyAppState >();
@@ -213,14 +281,58 @@ class GeneratorPage extends StatelessWidget {
213281 SizedBox (height: 10 ),
214282 BigCard (pair: pair),
215283 SizedBox (height: 10 ),
284+ // 数字范围选择
285+ Row (
286+ mainAxisAlignment: MainAxisAlignment .center,
287+ children: [
288+ Text ('范围:' ),
289+ SizedBox (
290+ width: 60 ,
291+ child: TextField (
292+ controller: minController,
293+ keyboardType: TextInputType .number,
294+ decoration: InputDecoration (
295+ labelText: '最小' ,
296+ ),
297+ onSubmitted: (v) {
298+ final min = int .tryParse (v) ?? appState.minValue;
299+ appState.setRange (min, appState.maxValue);
300+ },
301+ ),
302+ ),
303+ Text (' ~ ' ),
304+ SizedBox (
305+ width: 60 ,
306+ child: TextField (
307+ controller: maxController,
308+ keyboardType: TextInputType .number,
309+ decoration: InputDecoration (
310+ labelText: '最大' ,
311+ ),
312+ onSubmitted: (v) {
313+ final max = int .tryParse (v) ?? appState.maxValue;
314+ appState.setRange (appState.minValue, max);
315+ },
316+ ),
317+ ),
318+ ],
319+ ),
320+ SizedBox (height: 10 ),
216321 Row (
217322 mainAxisSize: MainAxisSize .min,
218323 children: [
219324 ElevatedButton (
220325 onPressed: () {
326+ // 先同步输入框内容到状态
327+ final min = int .tryParse (minController.text) ?? appState.minValue;
328+ final max = int .tryParse (maxController.text) ?? appState.maxValue;
329+ appState.setRange (min, max);
221330 appState.getNext ();
331+ // 保证输入框内容和状态同步
332+ minController.text = appState.minValue.toString ();
333+ maxController.text = appState.maxValue.toString ();
222334 },
223- child: Text ('点击抽选喵 ' ),
335+ child: Text ('点击抽选 ' ),
224336 ),
225337 ],
226338 ),
@@ -290,10 +402,60 @@ class SettingsPage extends StatelessWidget {
290402 var theme = Theme .of (context);
291403 var appState = context.watch <MyAppState >();
292404 return Column (
293- crossAxisAlignment : CrossAxisAlignment .start ,
405+ spacing : 20 ,
294406 children: [
295- Placeholder ()
296- ]
407+ SizedBox (width: 10 ,),
408+ Text ("外观" , style: TextStyle (fontSize: 20 )),
409+ SettingsCard (
410+ title: Text ("主题模式" ),
411+ leading: Icon (Icons .brightness_6_outlined),
412+ description: "选择亮色、暗色或跟随系统主题" ,
413+ trailing: Row (
414+ mainAxisSize: MainAxisSize .min,
415+ children: [
416+ Tooltip (
417+ message: "跟随系统" ,
418+ child: Row (
419+ children: [
420+ Text ("跟随系统" ),
421+ Radio <int >(
422+ value: 0 ,
423+ groupValue: appState.themeMode,
424+ onChanged: (v) => appState.setThemeMode (v! ),
425+ ),
426+ ]
427+ ),
428+ ),
429+ Tooltip (
430+ message: "亮色" ,
431+ child: Row (
432+ children: [
433+ Text ("亮色" ),
434+ Radio <int >(
435+ value: 1 ,
436+ groupValue: appState.themeMode,
437+ onChanged: (v) => appState.setThemeMode (v! ),
438+ ),
439+ ]
440+ ),
441+ ),
442+ Tooltip (
443+ message: "暗色" ,
444+ child: Row (
445+ children: [
446+ Text ("暗色" ),
447+ Radio <int >(
448+ value: 2 ,
449+ groupValue: appState.themeMode,
450+ onChanged: (v) => appState.setThemeMode (v! ),
451+ ),
452+ ]
453+ ),
454+ ),
455+ ],
456+ ),
457+ ),
458+ ],
297459 );
298460 }
299461}
0 commit comments