Home > Back-end >  Flutter - Hive - Only one List item displayed when changing screen / page
Flutter - Hive - Only one List item displayed when changing screen / page

Time:01-11

On the add Weight screen I pick a weight and a date and then it gets stored in a list in the Hive database, once I press "Save". It also returns me to the Homepage, where I would like to depict the stored list items in a ListView.Builder. I only get the last item on the list and not the whole list. When I am at the add weight screen, I see that there are more items in the list, but once I return to homepage only the last one exists.

AddWeightScreen

import 'package:flutter/material.dart';
import 'package:flutter/src/widgets/container.dart';
import 'package:flutter/src/widgets/framework.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'package:intl/intl.dart';
import 'package:weighty/components/my_alert_box.dart';
import 'package:weighty/data/database.dart';
import 'package:weighty/screens/home_page.dart';

class AddWeight extends StatefulWidget {
  const AddWeight({super.key});

  @override
  State<AddWeight> createState() => _AddWeightState();
}

class _AddWeightState extends State<AddWeight> {
  Database db = Database();
  final _myBox = Hive.box("mybox");
  double _currentValue = 0;
  DateTime _dateTime = DateTime.now();
  String formattedDate = DateFormat('d MMM yyyy').format(DateTime.now());
  final _weightController = TextEditingController();

  void _showDatePicker() {
    showDatePicker(
      context: context,
      initialDate: DateTime.now(),
      firstDate: DateTime(2000),
      lastDate: DateTime.now(),
    ).then((value) {
      setState(() {
        _dateTime = value!;
        formattedDate = DateFormat('d MMM yyyy').format(_dateTime);
      });
    });
  }

// add weight from text -  keyboard
  void _dialogNumber() {
    showDialog(
        context: context,
        builder: (context) {
          return MyAlertBox(
              controller: _weightController,
              hintText: "Enter today's weight...",
              onSave: () {
                if (double.parse(_weightController.text) > 200) {
                  _weightController.text = "200";
                }
                setState(() {
                  _currentValue = double.parse(_weightController.text);
                });

                _weightController.clear();
                Navigator.pop(context);
              },
              onCancel: cancelDialogBox);
        });
  }

  //save method
  void _saveWeightAndDate() {
    setState(() {
      db.weightList.add([_currentValue, formattedDate]);
    });
    db.saveData();

    Navigator.push(
      context,
      MaterialPageRoute(
        builder: (context) => const HomePage(),
      ),
    );
  }

  // cancel new weight input
  void cancelDialogBox() {
    // clear textfield
    _weightController.clear();

    // pop dialog box
    Navigator.of(context).pop();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Color(0xFFD9F0FF),
      body: Padding(
        padding: const EdgeInsets.all(20.0),
        child: Column(
          children: [
            const SizedBox(
              height: 28.0,
            ),
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                const Text(
                  "Add Weight",
                  style: TextStyle(fontSize: 36, fontWeight: FontWeight.w600),
                ),
                MaterialButton(
                  onPressed: () {
                    Navigator.pop(context);
                  },
                  child: const Text(
                    'CANCEL',
                    style: TextStyle(
                      color: Color(0xff878472),
                      fontSize: 16.0,
                      fontWeight: FontWeight.bold,
                    ),
                  ),
                ),
              ],
            ),
            const SizedBox(height: 30),
            Expanded(
              child: Column(
                mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                children: [
                  Expanded(
                    child: MaterialButton(
                      onPressed: _dialogNumber,
                      child: Text(
                        _currentValue.toStringAsFixed(2)   " kg",
                        style: TextStyle(
                            color: Color(0xFF006B8F),
                            fontSize: 46,
                            fontWeight: FontWeight.w500),
                      ),
                    ),
                  ),
                  const SizedBox(height: 30),
                  Slider(
                    value: _currentValue,
                    min: 0,
                    max: 200,
                    onChanged: ((value) {
                      setState(() {
                        _currentValue = value;
                      });
                    }),
                  ),
                  const SizedBox(height: 30),
                  TextButton.icon(
                    onPressed: _showDatePicker,
                    icon: const Icon(
                      Icons.date_range_outlined,
                      size: 24.0,
                      color: Color(0xff878472),
                    ),
                    label: Text(
                      formattedDate,
                      style: TextStyle(color: Color(0xff878472), fontSize: 18),
                    ),
                  ),
                  const SizedBox(height: 30),
                  ElevatedButton(
                    onPressed: _saveWeightAndDate,
                    child: Text(
                      'SAVE',
                      style:
                          TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
                    ),
                    style: ElevatedButton.styleFrom(
                      elevation: 24,
                      padding:
                          EdgeInsets.symmetric(vertical: 20, horizontal: 80),
                      shape: RoundedRectangleBorder(
                        borderRadius: BorderRadius.circular(30),
                        side: BorderSide(color: Colors.white, width: 2),
                      ),
                    ),
                  ),
                  const SizedBox(height: 30),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }
}

HomePage

import 'package:flutter/material.dart';

import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'package:weighty/components/weight_tile.dart';
import 'package:weighty/data/database.dart';
import 'package:weighty/main.dart';
import 'package:weighty/screens/add_weight.dart';

class HomePage extends StatefulWidget {
  const HomePage({super.key});

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  @override
  void initState() {
    //First time ever opening app, Create default data
    // if (_myBox.get("WEIGHTLIST") == null) {

    // }

    //already exists data

    db.loadData();

    // db.saveData();

    super.initState();
  }

  Database db = Database();
  final _myBox = Hive.box("mybox");

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.grey[100],
      floatingActionButton: FloatingActionButton(
        backgroundColor: Color(0xff006B8F),
        onPressed: () {
          Navigator.push(
            context,
            MaterialPageRoute(
              builder: (context) => const AddWeight(),
            ),
          );
        },
        child: const Icon(Icons.add),
      ),
      floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
      body: Padding(
        padding: const EdgeInsets.all(20.0),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.start,
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            SizedBox(height: 28),
            Text(
              "CURRENT",
              style: TextStyle(
                color: Colors.grey[500],
                fontSize: 16.0,
                fontWeight: FontWeight.bold,
              ),
            ),
            Text(
              db.weightList.length == 0
                  ? "00.0 Kg"
                  : db.weightList.last[0].toStringAsFixed(2)   " kg",
              style: TextStyle(
                color: Color(0xFF006B8F),
                fontSize: 46.0,
                fontWeight: FontWeight.bold,
              ),
            ),
            SizedBox(height: 40),
            Center(
              child: Text(
                "GRAPH",
                style: TextStyle(
                  fontSize: 16.0,
                  fontWeight: FontWeight.bold,
                ),
              ),
            ),
            Expanded(
              child: ListView.builder(
                itemCount: db.weightList.length,
                itemBuilder: (context, index) {
                  return WeightTile(
                    date: db.weightList[index][1],
                    weight: db.weightList[index][0].toStringAsFixed(2),
                  );
                },
              ),
            ),
            ElevatedButton(
                onPressed: () {
                  print(db.weightList.length);
                },
                child: Text('Print!')),
          ],
        ),
      ),
    );
  }
}

Hive Database

import 'package:hive_flutter/hive_flutter.dart';

class Database {
  //reference the box
  final _myBox = Hive.box("mybox");

  // Empty Weight List
  List weightList = [];

  // void createInitialData() {
  //   weightList = [];
  // }

  //load the date from the db
  void loadData() {
    weightList = _myBox.get("WEIGHTLIST");
  }

  //save the weight

  void saveData() {
    _myBox.put("WEIGHTLIST", weightList);
  }
}

Please help :)

CodePudding user response:

It sounds like the problem is that when you navigate back to the HomePage, the widget is not re-build.

To fix that, you should call setState when AddWeight is closed. To do that you can do something like:

onPressed: async () {
    await Navigator.push(
        context,
        MaterialPageRoute(
            builder: (context) => const AddWeight(),
        ),
   );
   setState({});
},

CodePudding user response:

For whole list you have to first get old list which is saved in hive then sum this list and save in to hive Output is

For you example you have to update saveData method in to a Database class

void saveData() {
    List hiveList = _myBox.get("WEIGHTLIST");
    if (hiveList.isNotEmpty) {
      hiveList  = weightList;
    } else {
      hiveList = weightList;
    }
    _myBox.put("WEIGHTLIST", hiveList);
  }

You will be get whole list into a homescreen

enter image description here

CodePudding user response:

I could not rebuild your project to debug it. so I'm kind of taking a shot in the darkness. there is a widget called valuelistenablebuilder which gets rebuilt when ever a value changes you can set your box to the value being listened by this widget and rebuild every time a new value is added to your box you can find an example on this page

  • Related