The Problem is that the List elements that the user enters in Textfields are rendered correctly. After App restart, the elements are removed from the List and from UI too.
Here is the code:
I created a model class with variables
class CardData {
CardData(this.name, this.university, this.department, this.rollNumber,
this.emailId);
final String name;
final String university;
final String department;
final String rollNumber;
final String emailId;
}
Here is the form I used to get Data from user
import 'package:flutter/material.dart';
import 'package:student_card/models/card_data.dart';
class MyForm extends StatefulWidget {
const MyForm({super.key, required this.onAddNewData});
final void Function(CardData newData) onAddNewData;
@override
State<MyForm> createState() => _MyFormState();
}
class _MyFormState extends State<MyForm> {
final nameController = TextEditingController();
final universityController = TextEditingController();
final departmentController = TextEditingController();
final rollController = TextEditingController();
final emailIdController = TextEditingController();
@override
void dispose() {
nameController.dispose();
universityController.dispose();
departmentController.dispose();
rollController.dispose();
emailIdController.dispose();
super.dispose();
}
OutlineInputBorder myfocusborder() {
return const OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(20)),
borderSide: BorderSide(
color: Colors.greenAccent,
width: 3,
));
}
OutlineInputBorder myinputborder() {
//return type is OutlineInputBorder
return const OutlineInputBorder(
//Outline border type for TextFeild
borderRadius: BorderRadius.all(Radius.circular(20)),
borderSide: BorderSide(
color: Colors.redAccent,
width: 3,
));
}
showUserData() {
widget.onAddNewData(CardData(
nameController.text,
universityController.text,
departmentController.text,
rollController.text,
emailIdController.text));
}
@override
Widget build(BuildContext context) {
return Column(
children: [
const SizedBox(
height: 30,
),
TextField(
// cursorColor: Theme.of(context).colorScheme.onPrimary,
controller: nameController,
decoration: InputDecoration(
label: const Text('Your Name'),
hintText: 'Name',
border: myinputborder(),
focusedBorder: myfocusborder(),
enabledBorder: myinputborder()),
),
const SizedBox(
height: 20,
),
TextField(
controller: universityController,
decoration: InputDecoration(
label: const Text('University Name'),
hintText: 'University',
border: myinputborder(),
focusedBorder: myfocusborder(),
enabledBorder: myinputborder()),
),
const SizedBox(
height: 20,
),
TextField(
controller: departmentController,
decoration: InputDecoration(
label: const Text('Your Department'),
hintText: 'Department',
border: myinputborder(),
focusedBorder: myfocusborder(),
enabledBorder: myinputborder()),
),
const SizedBox(
height: 20,
),
TextField(
controller: rollController,
decoration: InputDecoration(
label: const Text('Your Registration Id.'),
hintText: 'Roll Numver',
border: myinputborder(),
focusedBorder: myfocusborder(),
enabledBorder: myinputborder()),
),
const SizedBox(
height: 20,
),
TextField(
controller: emailIdController,
decoration: InputDecoration(
label: const Text('Your Email Id.'),
hintText: 'Email',
border: myinputborder(),
focusedBorder: myfocusborder(),
enabledBorder: myinputborder()),
),
const SizedBox(
height: 20,
),
ElevatedButton(
onPressed: () {
showUserData();
},
child: const Text('Submit'))
],
);
}
}
List with dummy data and adding elements to it
import 'package:flutter/material.dart';
import 'package:student_card/Widgets/data_list.dart';
import 'package:student_card/models/card_data.dart';
import 'package:student_card/Widgets/form.dart';
class StudentCard extends StatefulWidget {
const StudentCard({super.key});
@override
State<StudentCard> createState() {
return _StudentCardState();
}
}
class _StudentCardState extends State<StudentCard> {
List<CardData> listData = [
CardData('Moiz', 'UMT', 'Software', 'FA21-BEE-106', '[email protected]'),
];
void addNewData(CardData newData) {
setState(() {
listData.add(newData);
});
}
showFormSheet(BuildContext context) {
showModalBottomSheet(
isScrollControlled: true,
context: context,
builder: (context) {
return Container(
padding: const EdgeInsets.symmetric(
horizontal: 20,
vertical: 15,
),
child: Column(
children: [
MyForm(
onAddNewData: addNewData,
)
],
),
);
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Student Card Maker'),
backgroundColor: const Color(0xFFC539B4),
actions: [
IconButton(
onPressed: () {
showFormSheet(context);
},
icon: const Icon(Icons.add))
],
),
body: Container(
padding: const EdgeInsets.all(10),
child: Column(
children: [
const Text('The data below'),
const SizedBox(
height: 10,
),
Expanded(
child: DataList(data: listData),
)
],
),
),
);
}
}
Rensdering it with ListView.Builder
import 'package:flutter/material.dart';
import 'package:student_card/models/card_data.dart';
class CardItem extends StatelessWidget {
const CardItem({super.key, required this.studentData});
final CardData studentData;
@override
Widget build(BuildContext context) {
// Full screen width and height
double Width = MediaQuery.of(context).size.width;
double height = MediaQuery.of(context).size.height;
// Height (without SafeArea)
var padding = MediaQuery.of(context).viewPadding;
double height1 = height - padding.top - padding.bottom;
double realHeight = 0.75 * height1;
double realWidth = 0.90 * Width;
// Height (without status bar)
// double height2 = height - padding.top;
return Container(
height: realHeight,
width: realWidth,
padding: const EdgeInsets.all(5),
child: Card(
child: Column(
children: [
Text(studentData.name),
Text(studentData.university),
Text(studentData.department),
Text(studentData.rollNumber),
Text(studentData.emailId),
],
),
),
),
);
}
}
2
Answers
After the restart, all your widgets are built from scratch, so your
listData
will contain only dummy data. If you want to preserve added elements after restart, you need to store them in some database.Okay, see when the app restarts it start the execution from the main with releasing all your previous memory usage, so you want to preserve the data entered by the user so that it is not lost when the app is restarted. So there are few different ways to achieve it: shared_preferences, sqflite and hive.
So, with Shared Preferences, you can save simple stuff like settings or small user data. It’s good when you don’t need fancy queries. Here it’s not applicable with your case (still if you want to use it you can covert your
card
model to json and save it. but i don’t recommend it.)Now, SQLite using the sqflite package is great for structured and larger datasets. You can do all sorts of database stuff with it, like adding, reading, updating, and deleting data. It’s best for your data, you just make a table for
card
and add new entries in table and retrieve at app restart.Lastly, there’s Hive. It’s nice for lightweight data storage, like lists or maps. It’s quick and easy to use, especially when you don’t want to deal with complex databases. It’s like Map (key value pair),