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
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