Search code examples
fluttersharedpreferencesflutter-dependencies

Flutter How can I save my date and Boolean value in Share preferences?


This is my output

enter image description here

all these functions are works excellent. But I tried to add sharedPrefence to these dropdowns, select birthday and to the checkbox. But both dropdowns work perfectly, When I select something in the dropdown and click the next button and close the app and reopen again then shows the words that are selected at the last. But after that, I tried to add sharedPrefence to datePicker and thin "Are you agree " check box but then shows some errors. I have no idea how to solve that. EX:- In this, I used a date picker, Agree checkbox and in there shows "Birthday" word as an initial date and check box is unselecting, when the click selects the button then shows the dates and pick date and can select check box then value is true, That works perfectly. But I wanna add shared Preferences to this When added that, after the selected word and close the app and reopened again then should show the date and check box value true that is selected at the last.

my full code.

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';

class FamilyDetailsScreen extends StatefulWidget {
  @override
  State<FamilyDetailsScreen> createState() => _FamilyDetailsScreenState();
}

class _FamilyDetailsScreenState extends State<FamilyDetailsScreen> {
  // 1st dropdown button
  @override
  void initState() {
    super.initState();
    dropdownValueMembers = items.first;
    dropdownValueNumber = number.first;
    dropdownValueBirthday = birthday.first;
    dropdownValueBirthday = Agree.first;
    checkValueMembers();
    checkValueNumber();
    checkValueBirthday();
    checkValueAgree();
  }

  String? dropdownValueMembers;

  // List of items in our dropdown menu
  List<String> items = [
    'howmany',
    'one',
    'two',
    'three  ',
    'four',
    '5 or more'
  ];

  checkValueMembers() {
    _getData();
  }

  _saveData(String dropdownValueMembersShared) async {
    SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
    sharedPreferences.setString("data", dropdownValueMembersShared);
  }

  _getData() async {
    SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
    dropdownValueMembers = sharedPreferences.getString("data") ?? items.first;
    setState(() {});
  }

  // 2nd dropdown button
  // data which child
  String? dropdownValueNumber;
//   // List of items in our dropdown menu
  List<String> number = ['which', '1 st', '2 nd', '3 rd  ', '4 th    ', '5 th'];

  //IF "dropdownValueMembers" is empty pass "which" word as a initial value if al ready selected then pass the shared preference value
  checkValueNumber() {
    _getDataNumber();
  }

  _saveDataNumbers(String dropdownValueNumberShared) async {
    SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
    sharedPreferences.setString("data2", dropdownValueNumberShared);
  }

  _getDataNumber() async {
    SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
    dropdownValueNumber = sharedPreferences.getString("data2") ?? number.first;
    setState(() {});
  }

  //date picker
  DateTime? selectedDate;
  DateTime now = new DateTime.now();
  void showDatePicker() {
    DateTime mindate = DateTime(now.year - 2, now.month, now.day - 29);
    DateTime maxdate = DateTime(now.year - 1, now.month, now.day);
    showCupertinoModalPopup(
        context: context,
        builder: (BuildContext builder) {
          return Container(
            height: MediaQuery.of(context).copyWith().size.height * 0.25,
            color: Colors.white,
            child: CupertinoDatePicker(
              mode: CupertinoDatePickerMode.date,
              initialDateTime: mindate,
              onDateTimeChanged: (value) {
                if (value != null && value != selectedDate) {
                  setState(() {
                    selectedDate = value;
                  });
                }
              },
              maximumDate: maxdate,
              minimumDate: mindate,
            ),
          );
        });
  }

  String? dropdownValueBirthday;
  List<String> birthday = [
    'Birthday',
  ];

  //sharedPreferences birthday
  checkValueBirthday() {
    _getDataBirthday();
  }

  _saveDataBirthday(String dropdownValueBirthdayShared) async {
    SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
    sharedPreferences.setString("dataBirthday", dropdownValueBirthdayShared);
  }

  _getDataBirthday() async {
    SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
    dropdownValueBirthday =
        sharedPreferences.getString("dataBirthday") ?? birthday.first;
    setState(() {});
  }
  
  //////////////////////////////////
  // are you agree button
  //boolean value (are you agree)
  bool isChecked = false;
  

  checkValueAgree() {
    _getDataAgree();
  }

  _saveDataAgree(String dropdownValueAgreeShared) async {
    SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
    sharedPreferences.setBool("Agree", dropdownValueAgreeShared);
  }

  _getDataAgree() async {
    SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
    dropdownValueNumber = sharedPreferences.getBool("Agree") ?? isChecked.first;
    setState(() {});
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      resizeToAvoidBottomInset: false,
      body: SafeArea(
        child: Column(
          children: <Widget>[
            const Text(
              'family details',
              textAlign: TextAlign.center,
              style: TextStyle(
                color: Colors.black,
                fontSize: 18.00,
                fontWeight: FontWeight.w700,
              ),
            ),
            const SizedBox(
              height: 30,
            ),
            Padding(
              padding: const EdgeInsets.only(top: 10, left: 15),
              child: Row(
                children: <Widget>[
                  const Icon(
                    Icons.brightness_1,
                    color: Colors.black,
                    size: 10.0,
                  ),
                  const Padding(
                    padding: EdgeInsets.only(left: 13),
                    child: Text(
                      "Number of children",
                      style:
                      TextStyle(fontSize: 15, fontWeight: FontWeight.w600),
                    ),
                  ),
                ],
              ),
            ),
            const SizedBox(
              height: 25,
            ),
            Row(
              children: [
                Padding(
                  padding: const EdgeInsets.only(left: 2),
                  child: Container(
                    height: 25,
                    decoration: BoxDecoration(
                      boxShadow: const <BoxShadow>[
                        //apply shadow on Dropdown button
                        BoxShadow(
                            color: Color.fromRGBO(
                                0, 0, 0, 0.37), //shadow for button
                            blurRadius: 5) //blur radius of shadow
                      ],
                      color: Colors.white,
                      borderRadius: BorderRadius.circular(15),
                    ),
                    child: DropdownButton(
                      underline: Container(),
                      borderRadius: BorderRadius.circular(20),
                      // Initial Value
                      value: dropdownValueMembers,
                      // Down Arrow Icon
                      icon: const Icon(Icons.keyboard_arrow_down),
                      // Array list of items
                      items: items.map((String data) {
                        return DropdownMenuItem(
                          value: data,
                          child: SizedBox(
                            height: 15,
                            width: 120.0, // for example
                            child: Text(data,
                                style: const TextStyle(
                                    fontSize: 13.0,
                                    fontWeight: FontWeight.w700),
                                textAlign: TextAlign.center),
                          ),
                        );
                      }).toList(),
                      // After selecting the desired option,it will
                      // change button value to selected value
                      onChanged: (String? newValue) {
                        setState(
                              () {
                            dropdownValueMembers = newValue!;
                          },
                        );
                      },
                    ),
                  ),
                ),
              ],
            ),
            Row(
              children: [
                Padding(
                  padding: const EdgeInsets.only(left: 20),
                  child: Text('Which child'),
                ),
                Padding(
                  padding: const EdgeInsets.only(left: 100, right: 0, top: 20),
                  child: Container(
                    height: 30,
                    decoration: BoxDecoration(
                      boxShadow: const <BoxShadow>[
                        //apply shadow on Dropdown button
                        BoxShadow(
                            color: Color.fromRGBO(
                                0, 0, 0, 0.37), //shadow for button
                            blurRadius: 5) //blur radius of shadow
                      ],
                      color: Colors.white,
                      borderRadius: BorderRadius.circular(15),
                    ),
                    child: DropdownButton(
                      underline: Container(),
                      borderRadius: BorderRadius.circular(20),
                      // Initial Value
                      value: dropdownValueNumber,
                      // Down Arrow Icon
                      icon: const Icon(Icons.keyboard_arrow_down),
                      // Array list of items
                      items: number.map((String number) {
                        return DropdownMenuItem(
                          value: number,
                          child: SizedBox(
                            height: 17,
                            width: 120.0, // for example
                            child: Text(number,
                                style: const TextStyle(
                                    fontSize: 13.0,
                                    fontWeight: FontWeight.w700),
                                textAlign: TextAlign.center),
                          ),
                        );
                      }).toList(),
                      // After selecting the desired option,it will
                      // change button value to selected value
                      onChanged: (String? newNumber) {
                        setState(
                              () {
                            dropdownValueNumber = newNumber!;
                          },
                        );
                      },
                    ),
                  ),
                ),
              ],
            ),
            const SizedBox(
              height: 60,
            ),
            Padding(
              padding: const EdgeInsets.only(left: 15),
              child: Row(
                children: <Widget>[
                  const Icon(
                    Icons.brightness_1,
                    color: Colors.black,
                    size: 10,
                  ),
                  const Padding(
                    padding: EdgeInsets.only(left: 15.0),
                    child: Text("birthday",
                        style: TextStyle(
                          fontSize: 16.0,
                        )),
                  ),
                  Padding(
                    padding: const EdgeInsets.only(left: 25.0),
                    child: SizedBox(
                      width: 110.0,
                      height: 25.0,
                      child: DecoratedBox(
                        decoration: BoxDecoration(
                          borderRadius: BorderRadius.circular(12),
                          color: Colors.white,
                        ),
                        child: Center(
                          child: Text(
                            selectedDate == null
                                ? (dropdownValueBirthday ?? birthday.first)
                                : '${selectedDate?.year}/${selectedDate?.month}/${selectedDate?.day} ',
                            style: const TextStyle(
                                fontSize: 16, fontWeight: FontWeight.w500),
                          ),
                        ),
                      ),
                    ),
                  ),
                  Padding(
                    padding: const EdgeInsets.only(left: 15.0),
                    child: SizedBox(
                      width: 88.0,
                      height: 25.0,
                      child: MaterialButton(
                        onPressed: showDatePicker,
                        shape: const StadiumBorder(),
                        color: Colors.blue,
                        child: const Text(
                          'select',
                          style: TextStyle(color: Colors.white, fontSize: 12),
                        ),
                      ),
                    ),
                  ),
                ],
              ),
            ),
            Padding(
              padding: const EdgeInsets.only(left: 15.0),
              child: Row(
                children: <Widget>[
                  const Icon(
                    Icons.brightness_1,
                    color: Colors.black,
                    size: 10,
                  ),
                  const Padding(
                    padding: EdgeInsets.only(left: 15.0),
                    child: Text(
                      "Are  you agree",
                      style:
                      TextStyle(fontSize: 16, fontWeight: FontWeight.w500),
                    ),
                  ),
                  const Padding(
                    padding: EdgeInsets.only(left: 30),
                    child: Text(
                      'yes',
                      style:
                      TextStyle(fontSize: 15, fontWeight: FontWeight.bold),
                    ),
                  ),
                  Checkbox(
                    shape: RoundedRectangleBorder(
                      borderRadius: BorderRadius.circular(8.0),
                    ),
                    side: MaterialStateBorderSide.resolveWith(
                          (states) =>
                          BorderSide(width: 3.0, color: Colors.blueAccent),
                    ),
                    value: isChecked,
                    onChanged: (bool? value) {
                      setState(() {
                        isChecked = value!;
                      });
                    },
                  ),
                ],
              ),
            ),
            Padding(
              padding: const EdgeInsets.only(bottom: 0.0, top: 150),
              child: SizedBox(
                width: 160.0,
                height: 35.0,
                child: ElevatedButton(
                    style: ButtonStyle(
                      shape: MaterialStateProperty.all<RoundedRectangleBorder>(
                        RoundedRectangleBorder(
                          borderRadius: BorderRadius.circular(18.0),
                          side: const BorderSide(
                            color: Colors.blueAccent,
                          ),
                        ),
                      ),
                    ),
                    onPressed: () {
                      //do null check 1st
                      _saveData(dropdownValueMembers!);
                      _saveDataNumbers(dropdownValueNumber!);
                      _saveDataBirthday(dropdownValueBirthday!);
                      _saveDataAgree(isChecked!);
                    },
                    child: const Text('next')),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

How to solve and how to add sharedPreference to this datepicker and to checkbox


Solution

  • Lot's of ways to go about it. Simplist way in your case, get rid of all the setStates in all your methods except the last one. You're layering all those setStates and they're calling while other things are still awaiting.

    I suggest awaiting each method before calling any setState. You can't await in the initState, but in the first method, call the each of the subsequent ones with awaits from there. So just call checkValueMembers(); (or create a new one getAllValues or whatever).

    Within getAllValues, await all the other methods.

    Then you can be sure that everything is done, and finally, call setState this way:

    WidgetsBinding.instance.addPostFrameCallback((_) {
      setState((){});
    });
    

    It ensures you don't call setState until the entire widget tree is done.

    Entire thing could look like this: remember to get rid of all the other setStates

      Future checkValueMembers() async {
        await _getData();
        await _getDataNumber();
        await _getDataBirthday();
        await _getDataAgree();
        WidgetsBinding.instance.addPostFrameCallback((_) {
          setState((){});
        });
      }