I am trying the code put by Resocoder for integrating the Hive with Flutter. Everything was going fine but i got stuck at a place from where i cant figure out what to do. If you see contactsbox is throwing error stating that itsa n object and i cant use lingth property on it or even any other property. I have market the partof the code in bold throwing error. Any idea why is this error happening. HOw shall i use contactsBox as List unable to understand it. Any help would be great
contact_page.dart
import 'package:flutter/material.dart';
import 'package:hive/hive.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'new_contact_form.dart';
import 'contact.dart';
class ContactPage extends StatelessWidget {
const ContactPage({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Hive Tutorial'),
),
body: Column(
children: [
Expanded(
child: _buildListView(),
),
NewContactForm(),
],
),
);
}
Widget _buildListView() {
return ValueListenableBuilder(
valueListenable: Hive.box('contacts').listenable(), builder:
(context, contactsBox, _) {
return ListView.builder(**itemCount: contactsBox.length** , itemBuilder: (context, index) {
final contact = contactsBox.getAt(index) as Contact;
return ListTile(
title: Text(contact.name!),
subtitle: Text(contact.age.toString()),
trailing: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
IconButton(
icon: Icon(Icons.refresh),
onPressed: () {
contactsBox!.putAt(
index,
Contact('${contact.name}*', contact.age + 1),
);
},
),
IconButton(
icon: Icon(Icons.delete),
onPressed: () {
contactsBox.deleteAt(index);
},
)
],
),
);
}
);
}
);
}
new_contact_form.dart
import 'package:db_app/contact.dart';
import 'package:flutter/material.dart';
import 'package:hive/hive.dart';
class NewContactForm extends StatefulWidget {
const NewContactForm({Key? key}) : super(key: key);
#override
State<NewContactForm> createState() => _NewContactFormState();
}
class _NewContactFormState extends State<NewContactForm> {
final _formKey = GlobalKey<FormState>();
String? _name;
String? _age;
void addContact(Contact cnt) {
final contactBox = Hive.box('contacts');
contactBox.add(cnt);
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Form(
child: Column(
children: [
TextFormField(
decoration: InputDecoration(labelText: 'Name'),
onSaved: (value) => _name = value,
),
SizedBox(height: 10),
TextFormField(
decoration: InputDecoration(labelText: 'Age'),
onSaved: (value) => _age = value,
keyboardType: TextInputType.number,
),
ElevatedButton(
onPressed: () {
_formKey.currentState!.save();
final newContact = Contact(_name, int.parse(_age!));
addContact(newContact);
},
child: Text('Add New Contact'),
),
],
),
));
}
}
Related
import 'package:firebase_database/firebase_database.dart';
import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_auth/firebase_auth.dart';
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
home: Authentication (),
);
}
}
class Authentication extends StatelessWidget {
const Authentication({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return StreamBuilder(
stream: FirebaseAuth.instance.authStateChanges(),
builder: (context, snapshot){
if(!snapshot.hasData){
return const SignInScreen(
providerConfigs: [
EmailProviderConfiguration()
],
);
}
return const Diarymain ();
},
);
}
}
class Diarymain extends StatefulWidget {
const Diarymain({Key? key}) : super(key: key);
#override
State<Diarymain> createState() => _DiarymainState();
}
class _DiarymainState extends State<Diarymain> {
final fbs = FirebaseDatabase.instance;
var currentUser = FirebaseAuth.instance.currentUser;
#override
Widget build(BuildContext context) {
final ref = fbs.ref().child('diary').child(currentUser!.uid);
return Scaffold(
floatingActionButton: FloatingActionButton(
backgroundColor: Colors.grey[350],
onPressed: () {
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (_) => AddEditDiary(),
),
);
},
child: const Icon(
Icons.add,
),
),
appBar: AppBar(title: Text('Diary'),),
body: FirebaseAnimatedList(
query: ref,
shrinkWrap: true,
itemBuilder: (context, snapshot, animation, index) {
return GestureDetector(
onTap: () {},
child: Container(
child: Padding(
padding: const EdgeInsets.all(8.0),
// child: ListView.builder(
// itemBuilder: (context, index) {
child: ListTile(
shape: RoundedRectangleBorder(
side: const BorderSide(
color: Colors.white,
),
borderRadius: BorderRadius.circular(10),
),
tileColor: Colors.blue[50],
trailing: IconButton(
icon: Icon(
Icons.delete,
color: Colors.blueGrey[900],
),
onPressed: () {
ref.child(snapshot.key!).remove();
},
),
title: Text(
snapshot.value.toString(),
style: const TextStyle(
fontSize: 25,
fontWeight: FontWeight.bold,
),
),
),
// },)
),
),
);
},
),
);
}
}
class AddEditDiary extends StatefulWidget {
const AddEditDiary({Key? key}) : super(key: key);
#override
State<AddEditDiary> createState() => _AddEditDiaryState();
}
class _AddEditDiaryState extends State<AddEditDiary> {
TextEditingController title = TextEditingController();
TextEditingController subtitle = TextEditingController();
final fbs = FirebaseDatabase.instance;
var currentUser = FirebaseAuth.instance.currentUser;
#override
Widget build(BuildContext context) {
final ref = fbs.ref().child('diary').child(currentUser!.uid);
return Scaffold(
appBar: AppBar(title: Text('Add'),),
body: ListView(
children: <Widget> [
Padding(
padding: const EdgeInsets.all(8.0),
child: TextFormField(
controller: title,
decoration: InputDecoration(
labelText: 'Title',
hintText: 'Enter Title',
border: OutlineInputBorder(),
),
)
),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextFormField(
controller: subtitle,
decoration: InputDecoration(
labelText: 'Subtitle',
hintText: 'Enter Subtitle',
border: OutlineInputBorder(),
),
)
),
Padding(
padding: const EdgeInsets.all(8.0),
child: RaisedButton(
onPressed: () {
ref
.push()
.set({
'title' : title.text,
'subtitle' : subtitle.text,
})
.asStream();
Navigator.pushReplacement(
context, MaterialPageRoute(builder: (_) => Diarymain()));
},
child: Text('Save', style: TextStyle(color: Colors.white),),
color: Colors.pink,
),
)
]
)
);
}
}
I'm trying to make a diary and two things which are title and subtitle are stored in the firebase real-time database. Below part of code shows how they are added in the firebase.
child: RaisedButton(
onPressed: () {
ref
.push()
.set({
'title' : title.text,
'subtitle' : subtitle.text,
})
.asStream();
When title and subtitles are shown on the page, I want to show them separately and I think I need something value to refer them individually.
In my code, "snapshot.value.toString()," shows only both title and subtitle together.
Is there any way to indicate them separately?
I would appreciate it if anyone can help me with this.
I'm trying to implement a search function into my app. Right now I got a ListView, which displays the data I get from a Firebase Database as a Stream. Do you have any Ideas how to search this List?
Here is my code for the ListView:
import "package:rate_my_food_1/models/imbiss.dart";
import "package:provider/provider.dart";
import "package:rate_my_food_1/widgets/imbiss_tile.dart";
class ImbissList extends StatefulWidget {
#override
_ImbissListState createState() => _ImbissListState();
}
class _ImbissListState extends State<ImbissList> {
#override
Widget build(BuildContext context) {
final imbiss = Provider.of<List<Imbiss>>(context);
return Column(
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: TextField(
decoration: InputDecoration(hintText: "Suchen...", hintStyle: TextStyle(color: Colors.white)),
style: TextStyle(color: Colors.white),
),
),
SizedBox(height: 10,),
Expanded(
child: ListView.builder(
shrinkWrap: true,
itemCount: imbiss.length ?? 0,
itemBuilder: (context, index){
return ImbissTile(imbiss: imbiss[index]);
},
),
),
],
);
}
}
And here is how I implemented the ListView in my homescreen of the App:
import 'package:rate_my_food_1/models/imbiss.dart';
import "package:rate_my_food_1/services/database.dart";
import "package:provider/provider.dart";
import "package:rate_my_food_1/widgets/imbiss_list.dart";
class Home extends StatefulWidget {
#override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
#override
Widget build(BuildContext context) {
return StreamProvider<List<Imbiss>>.value(
value: DatabaseService().imbisses,
child: Scaffold(
backgroundColor: Colors.grey[800],
//Add Button
floatingActionButton: FloatingActionButton(
onPressed: (){
Navigator.pushNamed(context, "/add");
},
child: Icon (Icons.add),
backgroundColor: Colors.cyanAccent,
),
body: Column(
children: <Widget>[
SafeArea(child: SizedBox(height: 10.0,)),
//Imbissliste
Expanded(child: ImbissList()),
],
)
)
);
}
}
I was thinking about making a second List in which I can Filter only for objects which contain what I'm writing into the TextField, but I have no clue how to do that properly.
Do you have any Ideas on how to search in this ListView?
If you need any more code from my Project, please let me know.
Thanks for all answers!
Yoqora
EDIT:
This is my Code atm, with the problem that it doesn't show the ListView and TextField when I start the app:
import "package:rate_my_food_1/models/imbiss.dart";
import "package:provider/provider.dart";
import "package:rate_my_food_1/widgets/imbiss_tile.dart";
class ImbissList extends StatefulWidget {
#override
_ImbissListState createState() => _ImbissListState();
}
class _ImbissListState extends State<ImbissList> {
List<Imbiss> imbiss = [];
List<Imbiss> filteredImbiss = [];
#override
initState() {
imbiss = Provider.of<List<Imbiss>>(context);
filteredImbiss = imbiss;
super.initState();
}
#override
Widget build(BuildContext context) {
return Column(
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: TextField(
decoration: InputDecoration(hintText: "Suchen...", hintStyle: TextStyle(color: Colors.white)),
style: TextStyle(color: Colors.white),
onChanged: (value) {
setState(() {
filteredImbiss = imbiss.where((imbiss) => imbiss.name.contains(value)).toList();
});
},
),
),
SizedBox(height: 10,),
Expanded(
child: ListView.builder(
shrinkWrap: true,
itemCount: filteredImbiss.length,
itemBuilder: (context, index){
return ImbissTile(imbiss: filteredImbiss[index]);
},
),
),
],
);
}
}`
We can filter the retrieved data using a key in state. This key kan be updated using the onChanged(String) method from the TextField widget. We simply filter the list on every build, please see the example below:
class ImbissList extends StatefulWidget {
#override
_ImbissListState createState() => _ImbissListState();
}
class _ImbissListState extends State<ImbissList> {
// The search key to filter the imbisses.
String key = '';
#override
Widget build(BuildContext context) {
var imbisses = Provider.of<List<Imbiss>>(context);
// Filter the imbisses using the key.
imbisses = imbisses.where((imbiss) {
return imbiss.name.contains(key);
}).toList();
return Column(
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: TextField(
decoration: InputDecoration(
hintText: "Suchen...",
hintStyle: TextStyle(color: Colors.white)),
style: TextStyle(color: Colors.white),
onChanged: (value) {
// Update the key when the value changes.
setState(() => key = value);
},
),
),
SizedBox(
height: 10,
),
Expanded(
child: ListView.builder(
shrinkWrap: true,
itemCount: imbisses.length,
itemBuilder: (context, index) {
return ImbissTile(imbiss: imbisses[index]);
},
),
),
],
);
}
}
Hey i tried the same thing but i'm getting a blank screen, if possible can you please share the source code.
Edit: I figured out where i was going wrong. Thank you so much for the solution this was really helpful
I am new to Flutter and I am creating a notes app. i want to pass the title and text of the new note from a "new note" page to the home page where all other notes are.
I want to pass the title and text to the first page where I can create a list of saved notes as the number of notes grow using a List view. What am I doing wrong?
Here is my code for the home page:
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart';
import 'package:notes/newnote.dart';
void main() {
runApp(MaterialApp(home: MyApp(), initialRoute: 'main.dart', routes: {
'/home': (context) => MyApp(),
'/newnote': (context) => NewNote(),
}));
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Notes',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: FirstPage(),
);
}
}
int x = 0;
class FirstPage extends StatefulWidget {
String title ;
String text ;
FirstPage({Key key, #required this.title,#required this.text}) : super(key: key);
void pri() {print(title);}
#override
_MyAppState createState() => _MyAppState();
}
Map data = {};
class _MyAppState extends State<FirstPage> {
#override
Widget build(BuildContext context) {
//final dat args = ModalRoute.of(context).settings.arguments;
return Scaffold(
appBar: AppBar(
title: Text(
"Note-It!",
textAlign: TextAlign.center,
style: TextStyle(color: Colors.white),
),
backgroundColor: Colors.black,
),
body: Column(
//
children: <Widget>[
Padding(
padding: EdgeInsets.fromLTRB(19.0, 19.0, 19.0, 19.0),
),
Expanded(
child: ListView.builder(
itemCount: x,
itemBuilder: (context, index) {
return ListTile(
title: Text(widget.title),
// onTap: () {
// Navigator.push( context,MaterialPageRoute( builder: (context) =>
// DetailScreen(notedata: datas[index])));
// }
);
}),
),
Align(
alignment: Alignment.bottomRight,
child: FloatingActionButton(
child: Icon(Icons.add),
backgroundColor: Colors.black,
onPressed: () {
setState(() {
Navigator.push(context, new MaterialPageRoute(
builder: (context) =>
new NewNote(t1: null, t2: null)
));
});
}),
),
],
),
);
}
}
and here is my code for "new note" page
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart';
import 'package:notes/main.dart';
void main() {
runApp(MaterialApp(home: NewNote()));
}
final fromController1 = TextEditingController();
final fromController2 = TextEditingController();
var instance;
class NewNote extends StatelessWidget {
String t1; //requesting data here
String t2;
NewNote({Key key, #required this.t1,#required this.t2}) : super(key: key);
// final String d;
//
// NewNote({
// Key key,
// #required this.d,
// }) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("New Note"),
backgroundColor: Colors.black,
),
body: SingleChildScrollView(
child: Padding(
padding: EdgeInsets.fromLTRB(19.0, 19.0, 19.0, 19.0),
child: SingleChildScrollView(
child: Column(children: <Widget>[
TextField(
controller: fromController1,
decoration: InputDecoration(
border: OutlineInputBorder(), labelText: "Title"),
style: TextStyle(fontSize: 28.0),
),
Padding(padding: EdgeInsets.fromLTRB(19.0, 19.0, 19.0, 0.0)),
TextField(
controller: fromController2,
decoration: InputDecoration(
border: OutlineInputBorder(), labelText: "Text"),
style: TextStyle(fontSize: 20.0),
maxLines: null,
),
Padding(padding: EdgeInsets.fromLTRB(19.0, 19.0, 19.0, 0.0)),
Align(
alignment: Alignment.bottomCenter,
child: FloatingActionButton.extended(
label: Text("Save Note"),
icon: Icon(Icons.save),
backgroundColor: Colors.black,
onPressed: () {
x++;
t1 = fromController1.text;
t2 = fromController2.text;
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => MyApp(), //pass your title and text to NewNote
),
).then((value){
FirstPage(title: t1, text: t2);
});
},
),
),
]),
),
),
),
);
}
}
You have already passed the title and string in the first page from new note page. You are just not displaying it onto the screen with right syntax.
Change this
title: Text(
"Note-It!",
textAlign: TextAlign.center,
style: TextStyle(color: Colors.white),
),
to
title: Text(
this.widget.title,
textAlign: TextAlign.center,
style: TextStyle(color: Colors.white),
),
I have a louded information in RealTime database in format for example:
record
0
Club: "Club1"
Name: "Ronaldo"
Place: "London"
date: "25.07.2020"
email: "flutter#gmail.com"
phone: "12345678"
I have created a list that consists of names and clubs and I want to go to the full information according to the form by clicking on the Name, but I can't write the code. Please help to the new programmer
import 'package:firebase_database/firebase_database.dart';
import 'package:flutter/material.dart';
import 'package:.../anketa/tile.dart';
class Anketa extends StatefulWidget {
Anketa({Key key, this.title}) : super(key: key);
final String title;
#override
_AnketaState createState() => _AnketaState();
}
class _AnketaState extends State<Anketa> {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text("Registration form",
style: TextStyle(
fontWeight: FontWeight.w200,
fontSize: 30,
fontFamily: 'Roboto',
fontStyle: FontStyle.italic)),
RegisterStudent(),
]),
)),
);
}
}
class RegisterStudent extends StatefulWidget {
RegisterStudent({Key key}) : super(key: key);
#override
_RegisterStudentState createState() => _RegisterStudentState();
}
class _RegisterStudentState extends State<RegisterStudent> {
final _formKey = GlobalKey<FormState>();
final listOfClubs = ["Club1", "Club2", "Club3", "Club4"];
String dropdownValue = "Club1";
final clubController = TextEditingController();
final nameController = TextEditingController();
final placeController = TextEditingController();
final dateController = TextEditingController();
final emailController = TextEditingController();
final phoneController = TextEditingController();
final rawController = TextEditingController();
final dbRef = FirebaseDatabase.instance.reference().child("record");
#override
Widget build(BuildContext context) {
return Form(
key: _formKey,
child: SingleChildScrollView(
child: Column(children: <Widget>[
Padding(
padding: EdgeInsets.all(20.0),
child: TextFormField(
controller: nameController,
decoration: InputDecoration(
labelText: "EnterName",
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(10.0),
),
),
// The validator receives the text that the user has entered.
validator: (value) {
if (value.isEmpty) {
return "Enter name";
}
return null;
},
),
),
Padding(
padding: EdgeInsets.all(20.0),
child: DropdownButtonFormField(
value: dropdownValue,
icon: Icon(Icons.arrow_downward),
decoration: InputDecoration(
labelText: "Club",
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(10.0),
),
),
items: listOfClubs.map((String value) {
return new DropdownMenuItem<String>(
value: value,
child: new Text(value),
);
}).toList(),
onChanged: (String newValue) {
setState(() {
this.dropdownValue = newValue;
});
},
validator: (value) {
if (value.isEmpty) {
return 'Club';
}
return null;
},
),
),
Padding(
padding: EdgeInsets.all(20.0),
child: TextFormField(
keyboardType: TextInputType.number,
controller: dateController,
decoration: InputDecoration(
labelText: "Date",
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(10.0),
),
),
// The validator receives the text that the user has entered.
validator: (value) {
if (value.isEmpty) {
return 'Date';
}
return null;
},
),
),
Padding(
padding: EdgeInsets.all(20.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
RaisedButton(
color: Colors.lightBlue,
onPressed: () {
if (_formKey.currentState.validate()) {
dbRef.push().set({
"Name": nameController.text,
"date": dateController.text,
"Club": dropdownValue
}).then((_) {
Scaffold.of(context).showSnackBar(
SnackBar(content: Text('Add')));
dateController.clear();
nameController.clear();
}).catchError((onError) {
Scaffold.of(context)
.showSnackBar(SnackBar(content: Text(onError)));
});
}
},
child: Text('Enter'),
),
RaisedButton(
color: Colors.amber,
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => ListOfNames()),
);
},
child: Text('Go to'),
),
],
)),
])));
}
#override
void dispose() {
super.dispose();
dateController.dispose();
nameController.dispose();
}
}
and this is the second page with a list, from where I want to go to full information
import 'package:flutter/material.dart';
import 'package:firebase_database/firebase_database.dart';
class ListOfNames extends StatelessWidget {
final dbRef = FirebaseDatabase.instance.reference().child("record");
List<Map<dynamic,dynamic>> lists = List();
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.grey.shade300,
appBar: AppBar(
backgroundColor: Colors.deepPurple,
title: Text("List of students"),
),
body: StreamBuilder(
stream: dbRef.onValue,
builder: (context, AsyncSnapshot<Event> snapshot) {
if (snapshot.hasData) {
lists.clear();
DataSnapshot dataValues = snapshot.data.snapshot;
Map<dynamic, dynamic> values = dataValues.value;
values.forEach((key, values) {
lists.add(values);
});
return new ListView.builder(
shrinkWrap: true,
itemCount: lists.length,
itemBuilder: (BuildContext context, int index) {
itemBuilder: (BuildContext context, int index) {
return ListTile(
title:Text(lists[index]["Name"], style: TextStyle(height: 2.5, fontSize:20.0),),
subtitle:Text(lists[index]['Club'], style: TextStyle(fontSize:16.0),),
onTap: (){
// in this line i have a problem...
Navigator.push(context, MaterialPageRoute(builder: (context) => DetailPage(snapshot.data[index]['Name']),
)
);
},
);
});
}
return CircularProgressIndicator();
})
);
}
}
I want to create such a page:
class DetailPage extends StatelessWidget {
List<Map<dynamic,dynamic>> data ;
DetailPage ({this.data});
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(data.name),
// here I want to show the all information from the form about one person from the list
),
);
}
}
In the body of the scaffold of 'DetailsPage' use 'Card' widget with 'Text' widgets to show the info. Like Card(child:Text('${data.clubLoc}').
I am building an app and in it, I have the names of people in a list from which I could add/delete, etc.. The problem is this list is not saved when I close the app, which is inconvenient.
I heard you can use shared Preferences to save simple objects like this, without complicating things like using SQLite and json.
So I'd like to know what's the suggested way to persist this data and load it etc.
Thanks in Advance and have a great day :)
Here is the code:
import 'package:flutter/material.dart';
import 'package:zakif_yomi3/NewPerson.dart';
import 'package:shared_preferences/shared_preferences.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.purple,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final List<String> people = [];
void _addNewPerson(String name) {
setState(() {
people.add(name);
});
}
void _startAddNewPerson(BuildContext ctx) {
showModalBottomSheet(
context: ctx,
builder: (_) {
return GestureDetector(
onTap: () {},
child: NewPerson(_addNewPerson),
behavior: HitTestBehavior.opaque,
);
},
);
}
void _deletePerson(int value ) {
setState(() {
people.removeAt(value);
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: Text(
'People',
style: TextStyle(fontSize: 30),
),
actions: <Widget>[
IconButton(
icon: Icon(Icons.add),
onPressed: () => _startAddNewPerson(context),
)
],
),
body: ListView.builder(
itemCount: this.people.length,
itemBuilder: (context, value) {
return Card(
color: Colors.amberAccent[200],
elevation: 3,
child: Container(
child: ListTile(
leading: Text(value.toString()),
title: Text(
people[value],
),
trailing: IconButton(
icon: Icon(Icons.delete),
onPressed: () {
_deletePerson(value);
},
),
),
),
);
},
),
);
}
}
And the NewPerson object:
import 'package:flutter/material.dart';
class NewPerson extends StatefulWidget {
final Function addTx;
NewPerson(this.addTx);
#override
_NewPersonState createState() => _NewPersonState();
}
class _NewPersonState extends State<NewPerson> {
final _nameController = TextEditingController();
void _submitData() {
final name = _nameController.text;
widget.addTx(
name
);
Navigator.of(context).pop();
}
#override
Widget build(BuildContext context) {
return Card(
elevation: 5,
child: Container(
padding: EdgeInsets.all(10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
TextField(
decoration: InputDecoration(labelText: 'Name'),
controller: _nameController,
onSubmitted: (_) => _submitData(),
),
RaisedButton(
child: Text('Add Person'),
color: Theme.of(context).primaryColor,
textColor: Theme.of(context).textTheme.button.color,
onPressed: _submitData,
),
],
),
),
);
}
}
You could use this functions to persist and load data from shared preferences.
Get SharedPreferences from here.
To persist data to SharedPreferences, called after adding or deleting a new element to the list.
_persistData() async {
SharedPreferences preferences = await SharedPreferences.getInstance();
await preferences.setStringList("persons", _people);
}
To load data from SharedPreferences, usually called in initState.
_loadData() async {
SharedPreferences preferences = await SharedPreferences.getInstance();
setState(() {
_people = preferences.getStringList("persons");
});
}