Как сохранить значение, выбранное из средства выбора времени. Внутри общих настроек: Flutter

Когда значение выбирается внутри средства выбора времени, а затем происходит выход из приложения и повторный возврат, значение извлекается. Первое значение. Как я могу сохранить его в общих настройках? Я пытался сохранить его как строку, но безуспешно.


51
5

Ответы:

Не могли бы вы попробовать решение, представленное здесь? Если это не сработает, поделитесь кодом, и я буду рад вам помочь.

stackoverflow


    //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)),)),

          ],
        ),
      ),

    );
  }
}

Решено

Вот наименьшее количество изменений, чтобы это демо-приложение заработало.

  1. Я изменил хранилище настроек, чтобы сохранить час как int вместо string. Это просто упрощает задачу и требует меньше конверсий.

  2. 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");
            });
          }