Когда значение выбирается внутри средства выбора времени, а затем происходит выход из приложения и повторный возврат, значение извлекается. Первое значение. Как я могу сохранить его в общих настройках? Я пытался сохранить его как строку, но безуспешно.
Не могли бы вы попробовать решение, представленное здесь? Если это не сработает, поделитесь кодом, и я буду рад вам помочь.
//This code
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:flutter_localization/flutter_localization.dart';
TimeOfDay _timeOfDaybgm = const TimeOfDay(hour: 5, minute: 30);
void main() {
runApp(
const MaterialApp(
debugShowCheckedModeBanner: false,
home: MyApp()
));
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: ThemeData(
useMaterial3: true,
),
home: const MyHomePage(title: 'لا اله الا الله '),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
void initState() {
super.initState();
getSavedData();
}
getSavedData() async {
final pref = await SharedPreferences.getInstance();
// _timeOfDaybgm=TimeOfDay.fromDateTime(DateTime.parse(pref.getString('_timeOfDay')??_timeOfDay.toString()))
;
setState(() {});
}
@override
void dispose(){
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
TextButton(onPressed:() async {
final TimeOfDay?timeOfDay = await showTimePicker(
context: context,
initialTime:_timeOfDaybgm,
);
if (timeOfDay!= null) {
setState(() {
_timeOfDaybgm=timeOfDay;
});
FocusScope.of(context).unfocus();
final prefs = await SharedPreferences.getInstance();
await prefs.setString('_timeOfDay',_timeOfDaybgm.hour.toString());
}
//notfi();
}, child:const Text("Added time"),
),
Center(child: Text(_timeOfDaybgm.format(context).toString(),style: TextStyle(color: const Color.fromARGB(255, 5, 2, 2)),)),
],
),
),
);
}
}
Вот наименьшее количество изменений, чтобы это демо-приложение заработало.
Я изменил хранилище настроек, чтобы сохранить час как int
вместо string
. Это просто упрощает задачу и требует меньше конверсий.
getSavedData
был изменен для создания объекта TimeOfDay
на основе значения часа, сохраненного в хранилище настроек.
Для minute
я просто использовал значение по умолчанию из _timeOfDaybgm
, которое на данный момент всегда будет 30
. Вы можете обновить код, чтобы также хранить minute
в магазине настроек. Вы можете хранить его отдельно от часа, чтобы было проще.
Вы не можете использовать DateTime.parse
на _timeOfDaybgm.toString()
, потому что DateTime.parse
не понимает синтаксис. Вы можете попробовать распечатать то, что производит _timeOfDaybgm.toString()
, и это определенно не объект DateTime
.
Итак, новая функция выглядит так:
getSavedData() async {
final pref = await SharedPreferences.getInstance();
setState(() {
int savedHour = pref.getInt('_timeOfDay') ?? _timeOfDaybgm.hour;
_timeOfDaybgm = TimeOfDay(hour: savedHour, minute:
_timeOfDaybgm.minute);
});
}
И все вместе:
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
// import 'package:flutter_localization/flutter_localization.dart';
TimeOfDay _timeOfDaybgm = const TimeOfDay(hour: 5, minute: 30);
void main() {
runApp(
const MaterialApp(
debugShowCheckedModeBanner: false,
home: MyApp()
));
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: ThemeData(
useMaterial3: true,
),
home: const MyHomePage(title: 'لا اله الا الله '),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
void initState() {
super.initState();
getSavedData();
}
getSavedData() async {
final pref = await SharedPreferences.getInstance();
// get the saved value from stored prefs
// and make sure to do it inside `setState`
// cannot use DateTime.parse because _timeOfDaybgm.toString() doesn't return a value
// DateTime.parse can understand
setState(() {
int savedHour = pref.getInt('_timeOfDay') ?? _timeOfDaybgm.hour;
_timeOfDaybgm = TimeOfDay(hour: savedHour, minute: 0);
});
}
@override
void dispose(){
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
TextButton(onPressed:() async {
final TimeOfDay?timeOfDay = await showTimePicker(
context: context,
initialTime:_timeOfDaybgm,
);
if (timeOfDay!= null) {
setState(() {
_timeOfDaybgm=timeOfDay;
});
FocusScope.of(context).unfocus();
final prefs = await SharedPreferences.getInstance();
// changed setString to setInt, just makes it easier
await prefs.setInt('_timeOfDay', _timeOfDaybgm.hour);
}
//notfi();
}, child:const Text("Added time"),
),
Center(child: Text(_timeOfDaybgm.format(context).toString(),style: TextStyle(color: const Color.fromARGB(255, 5, 2, 2)),)),
],
),
),
);
}
}
Я запустил код tbold, и он работал без каких-либо проблем. Вы также можете попробовать это с int. Кроме того, если вы хотите продолжить использовать строковый подход, я оставлю код здесь.
//save
await prefs.setString('_timeOfDay', timeOfDay.toString());
//init
Future<void> getSavedData() async {
final pref = await SharedPreferences.getInstance();
String? timeOfDayString = pref.getString('_timeOfDay');
if (timeOfDayString == null) {
return;
}
String extractedTime = timeOfDayString.replaceAll('TimeOfDay(', '').replaceAll(')', '');
List<String> timeParts = extractedTime.split(':');
int hour = int.parse(timeParts[0]);
int minute = int.parse(timeParts[1]);
TimeOfDay timeOfDay = TimeOfDay(hour: hour, minute: minute);
_timeOfDaybgm = timeOfDay;
setState(() {});
}
Попробуйте приведенный ниже код, чтобы сохранить выбранное значение в общих настройках.
String _selectedTime = '';
showTimePicker(
context: context,
initialTime: TimeOfDay.now(),
).then((TimeOfDay? picked) {
if (picked != null && picked != TimeOfDay.now()) {
final String formattedTime = picked.format(context);
setState(() {
_selectedTime = formattedTime;
});
SharedPreferences.getInstance().then((prefs) {
prefs.setString('_timeOfDay', formattedTime);
}).catchError((error) {
// Handle errors if needed
print("Error saving time to SharedPreferences: $error");
});
}