Search code examples
flutterclassdartgenericssharedpreferences

I cannot save my Data when separating classes


I try to save CheckBox and RadioListTile data . I separated CheckBox and RadioList as Class . Here is My Codes , I tried a lot but I could not fix problem .


Solution

  • I have used your code to reproduce the issue. There are several issues, but no worries:

    1- You should make your Child widgets(MyCheckBox, MyRadio) stateless, as their states are handled by the parent(HomePage).

    2- In home_page.dart: HomePage calls the MyCheckBox widget like following:

    home_page.dart

    class HomePage extends StatefulWidget {
      const HomePage({Key? key}) : super(key: key);
    
      @override
      State<HomePage> createState() => _HomePageState();
    }
    
    class _HomePageState extends State<HomePage> {
      TextEditingController _controller = TextEditingController();
      List<String> fruits = [];
      Helper myHelper = Helper();
      FutureServices future = FutureServices();
      Singers currentSinger = Singers.Ianis;
      @override
      initState() {
        super.initState();
        verileriOku1();
      }
    
      @override
      Widget build(BuildContext context) {
        print("build calıştı");
        return Scaffold(
            appBar: AppBar(title: Text("Storage App")),
            body: ListView(
              children: [
                Padding(
                  padding: const EdgeInsets.all(8.0),
                  child: TextFormField(
                    controller: _controller,
                    decoration: const InputDecoration(hintText: "İsim Giriniz"),
                  ),
                ),
                MyRadio(),
                MyCheckBox(myValue: (value) {
                  value = fruits;
                  
                }),
                TextButton(
                  onPressed: () {
                    print(fruits);
                    print(currentSinger);
                  },
                  child: Text("Yazdır"),
                ),
                TextButton(
                    onPressed: () {
                      var object =
                          MyVariables(_controller.text, currentSinger, fruits);
                      myHelper.verileriKaydet(object);
                    },
                    child: Text("Kaydet")),
              ],
            ));
      }
    
      void verileriOku1() async {
        var info = await myHelper.verileriOku();
    
        setState(() {
          _controller.text = info.name;
          fruits = info.fruitList;
          currentSinger = info.singer;
        });
      }
    }
    

    As we can see, you are not assigning fruits correctly. So one possible solution could be:

    MyCheckBox(myValue: (value) {
      fruits = value;        
    }),
    

    But in the following step, I decided to remove that Function. Instead, you will need to provide the list of fruits to the Child widget directly.

    3- In my_check_box.dart: the MyCheckBox widget has a required Function to communicate with HomePage like the following:

    my_check_box.dart

    class MyCheckBox extends StatefulWidget {
      final Function myValue;
      MyCheckBox({Key? key, required this.myValue}) : super(key: key);
    
      @override
      State<MyCheckBox> createState() => _MyCheckBoxState();
    }
    

    So you needed to pass data between those widgets, and you chose to do it with Function. But since List is passed by reference in Dart language, you can use a List to pass values:

    const MyCheckBox({
      Key? key,
      required this.savedFruits,
      required this.onChanged,
    }) : super(key: key);
    
    final List<String> savedFruits;
    final void Function(bool? value, Meyveler meyve) onChanged;
    

    Another positive side of using a List is now we can check correctly if these fruits are saved fruits:

    my_check_box.dart

    import 'package:flutter/foundation.dart';
    import 'package:flutter/material.dart';
    
    import '../models/enums.dart';
    
    class MyCheckBox extends StatelessWidget {
      const MyCheckBox({
        Key? key,
        required this.savedFruits,
        required this.onChanged,
      }) : super(key: key);
    
      final List<String> savedFruits;
      final void Function(bool? value, Meyveler meyve) onChanged;
    
      @override
      Widget build(BuildContext context) => Column(
            children: [
              for (var meyve in Meyveler.values) check(meyve),
            ],
          );
    
      CheckboxListTile check(Meyveler meyve) => CheckboxListTile(
            title: Text(meyve.name),
            value: savedFruits.contains(describeEnum(meyve)),
            onChanged: (value) => onChanged(value, meyve),
          );
    }
    

    4- When it comes to the radio buttons, There is no connection between HomePage and MyRadio widgets. So take a look please the following solution related to this topic:

    my_radio.dart

    import 'package:flutter/material.dart';
    
    import '../models/enums.dart';
    
    class MyRadio extends StatelessWidget {
      const MyRadio({
        Key? key,
        required this.currentSinger,
        required this.onChanged,
      }) : super(key: key);
    
      final Singers currentSinger;
      final void Function(Singers singer) onChanged;
    
      @override
      Widget build(BuildContext context) => Column(
            children: [
              for (var singer in Singers.values) _radio(singer),
            ],
          );
    
      RadioListTile<Singers> _radio(Singers singer) => RadioListTile(
            title: Text(singer.name),
            value: singer,
            groupValue: currentSinger,
            onChanged: (_) => onChanged(singer),
          );
    }
    

    You can access the modified source code through GitHub.

    If you have further questions, please don't hesitate to write in the comments.