mardi 6 septembre 2022

Flutter: How to store checkbox information (true/false) in Hive?

In my flutter project I have a page which shows a grocery shopping list. The items a user added to the list are retrieved from a hive box. However the amount gets calculated in the build method and is not stored in a box. E.g. on the list I have 40ml milk. "Milk" comes from a hive box but "40ml" are calculated in the build method.

I implemented check boxes for the user to tick off item by item. Now I am looking for a way to save the checkbox boolean (checked = true, unchecked = false) in hive to have the information available when the user leaves and restarts the app. Does anyone know how to do it? I already tried to open a second box to store boolean values but the index of the list item is not stored there, so it messes up my checked list.

Here is my code so far:

class Shopping extends StatefulWidget {
  const Shopping({Key? key}) : super(key: key);

  @override
  State<Shopping> createState() => _ShoppingState();
}

class _ShoppingState extends State<Shopping> {
  List<bool> isChecked = []; //list to initialize grocery list with empty check boxes
  List checkIndexes = []; //list for my bool values from hive
  
  
  

  @override
  void initState() {
     
   _restorePersistedItems(); //tried here to persist checkbox status
   super.initState();
  }


   _restorePersistedItems() async {
   final ___box = Hive.box('checkedItems'); //in this box I store boolean true or false
    print('Values for checked box are  ${Hive.box('checkedItems').values} ');
  if (___box.values.isNotEmpty) {
     List checkIndexes = ___box.values.toList();
        setState(() => isChecked = List.from(checkIndexes));
        print('Values for is checked list from box are  $isChecked ');
    }else{
      final shoppingTransactions = Hive.box('shopping').values.toList();
            print('shopping Transactions list is ${shoppingTransactions}');
            List flatList = shoppingTransactions.expand((i) => i).toList();
            List<IngredientModel> ingredients = flatList.map((e) =>            
            IngredientModel.fromString(e)).toList();
            List<IngredientModel> finalIngredients = [];
          
    for (var item in ingredients) {
       isChecked.add(false);
    }

  }  
   }


  @override
   Widget build(BuildContext context){
    return Scaffold(
       backgroundColor: Colors.grey[900],
         body:  ValueListenableBuilder(
          valueListenable:  Hive.box('shopping').listenable(), //here I retrieve my grocery items
         
          builder: (context, __box, _)  {
            var __box = Hive.box('shopping');
            print('Box is ${__box}');
            final shoppingTransactions = __box.values.toList();
            print('shopping Transactions list is ${shoppingTransactions}');
            List flatList = shoppingTransactions.expand((i) => i).toList();
              print('flat list is ${flatList}');
      
            
           List<IngredientModel> ingredients = flatList.map((e) => 
           IngredientModel.fromString(e)).toList();
           List<IngredientModel> finalIngredients = [];
          
    for (var item in ingredients) { //here I calculate the ingredient amount
      var index = 0;
      bool addedBefore = false;
      for (var element in finalIngredients) {
        if (element.name == item.name) {
          addedBefore = true;
          break;
        } else {
          index++;
        }
      }
      if (addedBefore) {
        finalIngredients[index] = IngredientModel(
            count: finalIngredients[index].count + item.count,
            name: finalIngredients[index].name);
      } else {
        finalIngredients.add(item);
       // isChecked.add(false);
        
      }
      
       
    }
 
  
     if(shoppingTransactions.isEmpty){
      return Column(
        children: [
         SizedBox(height: 100),
          Container(
            padding: EdgeInsets.all(20),
            child:
          Text(
          "no items on your list",
          maxLines: 3,
           textAlign: TextAlign.center,
          style: GoogleFonts.junge(
                                    decoration: TextDecoration.none,
                                    color: Color.fromARGB(255, 163, 168, 186),
                                    fontWeight: FontWeight.bold,
                                    fontSize: 20.0,
                                    height: 1.0),
                  
      )
          ),
          Container(
            child: Icon (IconlyBold.search),
          )
        ]
      );
     }
     else{
 return Column(
          children: [
            Expanded(
              child: ListView.builder(
                                scrollDirection: Axis.vertical,
                                shrinkWrap: true,
                                primary: false,
                               
                                          itemCount:finalIngredients.length,
                                          itemBuilder: (context, index) {
                                      
                                           var checkedItem = 
                                           finalIngredients[index].count.toString() + ' 
                                           ' + finalIngredients[index].name;
                                           return Card(
                                             
                                            color: Colors.transparent,
                                            shape: RoundedRectangleBorder(
                                              borderRadius: BorderRadius.circular(25),
                                              ),
                                              
                                            child:
                                           ListTile(
                                            
                                              dense: true,
                                              visualDensity: VisualDensity(vertical: 
                                                                 -3), // to compact
                                            contentPadding: EdgeInsets.only(left: 15.0, 
                                                                 right: 15.0),
                                             tileColor: Colors.grey.withOpacity(0.2),
                                           shape: RoundedRectangleBorder(
                                             borderRadius: BorderRadius.only(
                                              topLeft: Radius.circular(25),
                                              topRight: Radius.circular(25),
                                              bottomRight: Radius.circular(25),
                                              bottomLeft: Radius.circular(25))),
                                              title: 
                                           Text('$checkedItem',
                                          style: GoogleFonts.nunito(color: Colors.white, fontSize: 18)),
                                          leading: Checkbox(
                                          value: isChecked[index],
                                          onChanged: (value) {
                                            setState(() => isChecked[index] = value!);
                                            print('isChecked value is  ${isChecked[index]} ');
                                            if(isChecked[index] = true){
                                             Hive.box('checkedItems').add((value));
     }
    else{
   Hive.box('checkedItems').add((value));
  ....



Aucun commentaire:

Enregistrer un commentaire