Add search form above Firestore list in Flutter - flutter

I am trying to render a search form above a list of items from Firestore and filter locally based on what is typed in the form.
I tried adding both widgets to the body like this, but it is only displaying the search form:
body: Column(
children: <Widget>[Searchform(), ContentWidget()],
),
This is the current code which displays a basic list:
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
class Items extends StatefulWidget {
Items({Key key}) : super(key: key);
#override
_ItemsState createState() => _ItemsState();
}
class _ItemsState extends State<Items> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Search'),
),
body: ContentWidget(),
);
}
}
class Searchform extends StatelessWidget {
final TextEditingController _searchController = TextEditingController();
#override
Widget build(BuildContext context) {
return TextField(
controller: _searchController,
decoration: InputDecoration(
labelText: "Search",
hintText: "Search",
prefixIcon: Icon(Icons.search),
border: OutlineInputBorder(
borderRadius: BorderRadius.all(
Radius.circular(15.0),
),
),
),
);
}
}
class ContentWidget extends StatelessWidget {
#override
Widget build(BuildContext context) {
return StreamBuilder<QuerySnapshot>(
stream: Firestore.instance.collection('content').snapshots(),
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (snapshot.hasError) return new Text('Error: ${snapshot.error}');
switch (snapshot.connectionState) {
case ConnectionState.waiting:
return new Text('Loading...');
default:
return new ListView(
children:
snapshot.data.documents.map((DocumentSnapshot document) {
return new ListTile(
title: new Text(document['term']),
);
}).toList(),
);
}
},
);
}
}
What I was thinking of doing is saving the items in local state and filter them based on what is typed in the search box.

this is a very simple way try this code within "snapshot.data.documents.map((DocumentSnapshot document)"
if(_searchController.text.toString().contains(document['term'])){
return new ListTile(
title: new Text(document['term']),
);
}

I have provide simple filter record in listview code.
class FilterDemo extends StatefulWidget {
#override
State<StatefulWidget> createState() {
// TODO: implement createState
return FilterState();
}
}
class FilterState extends State<FilterDemo> {
List<String> items, duplicateList;
TextEditingController editingController = TextEditingController();
#override
void initState() {
// TODO: implement initState
super.initState();
items = List<String>.generate(1000, (i) => "Item $i");
duplicateList = items;
}
void filterSearchResults(String query) {
List<String> dummySearchList = List<String>();
dummySearchList.addAll(duplicateList);
if (query.isNotEmpty) {
List<String> dummyListData = List<String>();
dummySearchList.forEach((item) {
if (item.contains(query)) {
dummyListData.add(item);
}
});
setState(() {
items.clear();
items.addAll(dummyListData);
});
return;
} else {
setState(() {
items.clear();
items.addAll(duplicateList);
});
}
}
#override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
appBar: AppBar(
title: Text("Filter Demo"),
),
body: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: TextField(
onChanged: (value) {
filterSearchResults(value);
},
controller: editingController,
decoration: InputDecoration(
labelText: "Search",
hintText: "Search",
prefixIcon: Icon(Icons.search),
border: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(25.0)))),
),
),
Expanded(
child: ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
return ListTile(
title: Text('${items[index]}'),
);
},
),
),
],
),
);
}
}

I have provide Code how the saving the items in local state and filter them based on what is typed in the search box.
class UserList extends StatefulWidget {
final FirebaseUser user;
final String currentUserId;
UserList({this.currentUserId, this.user});
#override
_UserListState createState() => _UserListState();
}
class _UserListState extends State<UserList> {
TextEditingController _signUpConfirmPassword = new TextEditingController();
String _myValue = '';
UniqueKey _myKey = UniqueKey();
#override
Widget build(BuildContext context) {
return CupertinoPageScaffold(
navigationBar: CupertinoNavigationBar(
middle: Text("UserList"),
),
child: ListView(
shrinkWrap: true,
children: <Widget>[
Padding(
padding: EdgeInsets.all(10.0),
child: CupertinoTextField(
keyboardType: TextInputType.text,
//inputFormatters: [LengthLimitingTextInputFormatter(60)],
placeholder: 'Search For..',
// placeholderStyle: TextStyle(
// fontWeight: FontWeight.w200
// ),
prefix: Padding(
padding: EdgeInsets.only(left: 10.0),
child: Icon(
Icons.search,
),
),
onChanged: (val) {
if (val.isNotEmpty) {
_myValue = val;
}
setState(() {
_myKey = UniqueKey();
});
},
decoration: BoxDecoration(
border: Border.all(color: primaryColor),
borderRadius: BorderRadius.circular(20.0)),
)),
SizedBox(height: 10.0),
Container(
key: _myKey,
child: FetchUsers(
user: widget.user,
myValue: _myValue,
)),
],
));
}
}
class FetchUsers extends StatefulWidget {
final String myValue;
final FirebaseUser user;
FetchUsers({this.myValue, this.user});
#override
_FetchUsersState createState() => _FetchUsersState();
}
class _FetchUsersState extends State<FetchUsers> {
List searchName = List();
List userName = List();
Future listOfUsers() {
if (widget.myValue.isEmpty) {
return Firestore.instance
.collection('users')
.where('Role', isEqualTo: 'user')
.orderBy('Created', descending: true)
.limit(10)
.getDocuments()
.then((d) {
userName.clear();
d.documents.forEach((f) {
userName.add(f);
});
return userName;
});
} else {
return Firestore.instance
.collection('users')
.where('Role', isEqualTo: 'user')
.limit(10)
.getDocuments()
.then((d) {
searchName.clear();
d.documents.forEach((f) {
if (f.data['Name']
.toString()
.toLowerCase()
.contains(widget.myValue.toLowerCase())) {
searchName.add(f);
}
});
return searchName;
});
}
}
#override
Widget build(BuildContext context) {
return FutureBuilder(
future: listOfUsers(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return Center(
child: CupertinoActivityIndicator(),
);
} else {
return ListView.separated(
physics: ClampingScrollPhysics(),
separatorBuilder: (context, int) {
return Divider();
},
itemCount: snapshot.data.length,
shrinkWrap: true,
padding: EdgeInsets.all(10.0),
itemBuilder: (context, index) {
return Card(
elevation: 7.0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0)),
child: IntrinsicHeight(
child: Padding(
padding: const EdgeInsets.all(10.0),
child: Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
' ${snapshot.data[index]['Name']}',
style: TextStyle(
color: outlineColor,
fontWeight: FontWeight.bold),
),
SizedBox(
height: 5.0,
),
Text(
' ${snapshot.data[index]['Email']}',
),
],
),
Spacer(),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
RaisedButton.icon(
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.circular(20.0)),
color: primaryColor,
onPressed: () {
Navigator.push(
context,
CupertinoPageRoute(
builder: (context) => Chat(
user: widget.user,
name: snapshot.data[index]
['Name'],
peerId: snapshot.data[index]
['UID'],
)));
},
icon: Icon(
Icons.chat,
color: themeColor,
),
label: Text(
"Chat",
style: TextStyle(color: themeColor),
)),
RaisedButton.icon(
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.circular(20.0)),
color: primaryColor,
onPressed: () {
Navigator.push(
context,
CupertinoPageRoute(
builder: (context) =>
SendNotificationOption(
name: snapshot.data[index]
['Name'],
myFcm: snapshot.data[index]
['UID'],
isBroadcast: false,
)));
},
icon: Icon(
Icons.notifications,
color: themeColor,
),
label: Text(
"Notification",
style: TextStyle(color: themeColor),
)),
],
),
],
),
),
));
},
);
}
},
);
}
}
What you have type in Search then that Data is shown in listview]1

Related

how i solve this issue on flutter

when I am debug this its shown a error on search bar when I try to text on emulator here is the code please resolve this thanks
LateInitializationError: Field 'name' has not been initialized.
import 'dart:async';
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: HomePage(),
);
}
}
class HomePage extends StatefulWidget {
#override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
String url = "https://owlbot.info/api/v4/dictionary/";
String token = "7ba05536bd11ff8e22800cbda80951376c59ed84";
TextEditingController textEditingController = TextEditingController();
late StreamController _streamController;
late Stream _stream;
late Timer _debounce;
searchText() async {
if (textEditingController.text == null ||
textEditingController.text.isEmpty) {
_streamController.add(null);
return;
}
_streamController.add("waiting");
Uri uri = Uri.parse(url+textEditingController.text.trim());
http.Response response = await http.get (uri, headers: {"Authorization": "Token " + token});
_streamController.add(json.decode(response.body));
}
#override
void initState() {
super.initState();
_streamController = StreamController();
_stream=_streamController.stream;
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.green,
title: Text(
"Dictionery",
style: TextStyle(color: Colors.white),
),
centerTitle: true,
bottom: PreferredSize(
preferredSize: Size.fromHeight(45),
child: Row(
children: [
Expanded(
child: Container(
margin: const EdgeInsets.only(left: 12, bottom: 11),
decoration:
BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(24),
),
child: TextFormField(
onChanged: (String text) {
if (_debounce.isActive) _debounce.cancel();
_debounce = Timer(const Duration(milliseconds: 1000), () {
searchText();
},
);
},
controller: textEditingController,
decoration: InputDecoration(
hintText: "Search for Word",
contentPadding: const EdgeInsets.only(left: 24),
border: InputBorder.none,
),
),
),
),
IconButton(
icon:Icon(
Icons.search,
color: Colors.white,
),
onPressed: (){
searchText();
},
),
],
),
),
),
body: Container(
margin: EdgeInsets.all(8.0),
child: StreamBuilder(
builder:(BuildContext context, AsyncSnapshot snapshot){
if(snapshot.data== null)
{
return Center(
child: Text('Enter A Search Word'),
);
}
if(snapshot.data == "waiting"){
return Center(
child: CircularProgressIndicator(),
);
}
return ListView.builder(
itemCount: snapshot.data["defination"].length,
itemBuilder: (BuildContext context , int index)
{
return ListBody(
children: [
Container(
color: Colors.grey[300],
child: ListTile(
leading:snapshot.data["definations"][index]["image_url"] == null
? null:
CircleAvatar(
backgroundImage: NetworkImage(snapshot.data["definations"][index]["image_url"]),
),
title: Text(textEditingController.text.trim()
+"(" + snapshot.data["definations"][index]["type"]+")"),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
snapshot.data["defination"][index]["defination"]),
)
],
);
},
);
},
stream: _stream,
),
),
);
}
}
when i debug this and touch on screen for text its give me error late initialization
Current issue is _debounce has not been initialized. Instead of late, make it nullable Timer? _debounce;.
And changes will be
child: TextFormField(
onChanged: (String text) async {
if (_debounce != null && _debounce!.isActive) {
_debounce!.cancel();
_debounce = Timer(
const Duration(milliseconds: 1000),
() async {
await searchText();
},
);
}
},
Full snippet
import 'dart:async';
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: HomePage(),
);
}
}
class HomePage extends StatefulWidget {
#override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
String url = "https://owlbot.info/api/v4/dictionary/";
String token = "7ba05536bd11ff8e22800cbda80951376c59ed84";
TextEditingController textEditingController = TextEditingController();
late StreamController _streamController;
late Stream _stream;
Timer? _debounce;
Future<void> searchText() async {
if (textEditingController.text.isEmpty) {
_streamController.add(null);
return;
}
_streamController.add("waiting");
Uri uri = Uri.parse(url + textEditingController.text.trim());
http.Response response =
await http.get(uri, headers: {"Authorization": "Token " + token});
_streamController.add(json.decode(response.body));
}
#override
void initState() {
super.initState();
_streamController = StreamController();
_stream = _streamController.stream;
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.green,
title: Text(
"Dictionery",
style: TextStyle(color: Colors.white),
),
centerTitle: true,
bottom: PreferredSize(
preferredSize: Size.fromHeight(45),
child: Row(
children: [
Expanded(
child: Container(
margin: const EdgeInsets.only(left: 12, bottom: 11),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(24),
),
child: TextFormField(
onChanged: (String text) async {
if (_debounce != null && _debounce!.isActive) {
_debounce!.cancel();
_debounce = Timer(
const Duration(milliseconds: 1000),
() async {
await searchText();
},
);
}
},
controller: textEditingController,
decoration: InputDecoration(
hintText: "Search for Word",
contentPadding: const EdgeInsets.only(left: 24),
border: InputBorder.none,
),
),
),
),
IconButton(
icon: Icon(
Icons.search,
color: Colors.white,
),
onPressed: () {
searchText();
},
),
],
),
),
),
body: Container(
margin: EdgeInsets.all(8.0),
child: StreamBuilder(
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.data == null) {
return Center(
child: Text('Enter A Search Word'),
);
}
if (snapshot.data == "waiting") {
return Center(
child: CircularProgressIndicator(),
);
}
return ListView.builder(
itemCount: snapshot.data["defination"].length,
itemBuilder: (BuildContext context, int index) {
return ListBody(
children: [
Container(
color: Colors.grey[300],
child: ListTile(
leading: snapshot.data["definations"][index]
["image_url"] ==
null
? null
: CircleAvatar(
backgroundImage: NetworkImage(snapshot
.data["definations"][index]["image_url"]),
),
title: Text(textEditingController.text.trim() +
"(" +
snapshot.data["definations"][index]["type"] +
")"),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
snapshot.data["defination"][index]["defination"]),
)
],
);
},
);
},
stream: _stream,
),
),
);
}
}

Deleting Item out of List, Listview.build shows wrong data

I have a Stateful widget that i pass a list to (for example 2 items).
After I delete an item, the widget should rebuild itself.
Unfortunately, the deleted item is still displayed and the other one is not.
When I re-enter the widget, the correct item is loaded.
There is a similar problem List not updating on deleting item
but maybe someone can explain me what i did wrong and why provider is helping me here instead of setState?
My code is:
import 'package:firebase_database/firebase_database.dart';
import 'package:flutter/material.dart';
import 'package:trip_planner/util/dialog_box.dart';
import 'package:trip_planner/util/previewUrl.dart';
class BookingPage extends StatefulWidget {
final List toDoList;
BookingPage({
super.key,
required this.toDoList,
});
#override
State<BookingPage> createState() => _BookingPageState();
}
class _BookingPageState extends State<BookingPage> {
//text controller
final _controller = TextEditingController();
final _database = FirebaseDatabase.instance.ref();
//Liste is an example what i have in my list
List toDoList2 = [
["https://www.booking.com/Share-Rnv2Kf", true],
["https://www.booking.com/Share-3hKQ0r", true],
];
void initState(){
super.initState();
}
void deleteTask(int index){
setState(() {
widget.toDoList.removeAt(index);
});
//DatabaseReference _testRef = _database.child("Hotel:");
//_testRef.set(widget.toDoList.toString());
}
//save new Item
void saveNewItem(){
setState(() {
widget.toDoList.add([_controller.text, false]);
//DatabaseReference _testRef = _database.child("Hotel:");
//_testRef.set(widget.toDoList.toString());
_controller.clear();
});
Navigator.of(context).pop();
}
void createNewItem(){
showDialog(
context: context,
builder: (context){
return DialogBox(
controller: _controller,
onSave: saveNewItem,
onCancel: () => Navigator.of(context).pop(),
);
},
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Booking Seiten'),
elevation: 0,
),
floatingActionButton: FloatingActionButton(
onPressed: createNewItem,
child: Icon(Icons.add),
),
body: ListView.builder(
itemCount: widget.toDoList.length,
itemBuilder: (context, index){
return PreviewUrl(
url2: widget.toDoList[index][0],
deleteFunction: (context) => setState(() => deleteTask(index)),
);
},
),
);
}
}
i thought setState does the same thing as when i re-enter the widget, but it doesn't.
import 'package:any_link_preview/any_link_preview.dart';
import 'package:flutter/material.dart';
import 'package:flutter_slidable/flutter_slidable.dart';
import 'package:url_launcher/url_launcher.dart';
class PreviewUrl extends StatelessWidget {
final String url2;
//Function(bool?)? onChanged;
Function(BuildContext)? deleteFunction;
PreviewUrl({
super.key,
required this.url2,
required this.deleteFunction,
//required this.onChanged,
});
Future openBrowserURL({
required String url,
bool inApp = false,
}) async {
if(await canLaunch(url)){
await launch(
url,
forceSafariVC: inApp, //iOS
forceWebView: inApp, //Android
enableJavaScript: true, //Android
);
}
}
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(1.0),
child: Slidable(
endActionPane: ActionPane(
motion: StretchMotion(),
children: [
SlidableAction(
onPressed: deleteFunction,
icon: Icons.delete,
backgroundColor: Colors.red.shade300,
borderRadius: BorderRadius.circular(12),
)
],
),
child: Container(
child: AnyLinkPreview.builder(
link: url2,
itemBuilder: (context, metadata, imageProvider) => Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (imageProvider != null)
GestureDetector(
onTap: () async {
final url = url2;
openBrowserURL(url: url, inApp: true);
},
child: Container(
constraints: BoxConstraints(
maxHeight: MediaQuery.of(context).size.width *0.25,
),
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(12),
topRight: Radius.circular(12)),
image: DecorationImage(
image: imageProvider,
fit: BoxFit.cover,
),
),
),
),
Container(
width: double.infinity,
color: Theme.of(context).primaryColor.withOpacity(0.6),
padding: const EdgeInsets.symmetric(
vertical: 10, horizontal: 15),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (metadata.title != null)
Text(
metadata.title!,
maxLines: 1,
style:
const TextStyle(fontWeight: FontWeight.w500),
),
const SizedBox(height: 5),
if (metadata.desc != null)
Text(
metadata.desc!,
maxLines: 1,
style: Theme.of(context).textTheme.bodySmall,
),
Text(
metadata.url ?? url2,
maxLines: 1,
style: Theme.of(context).textTheme.bodySmall,
),
],
),
),
],
),
),
),
),
);
}
}
If you run the simplified version of your code in DartPad - it will work:
import 'package:flutter/material.dart';
const Color darkBlue = Color.fromARGB(255, 18, 32, 47);
List toDoList = [
["Button 1", true],
["Button 2", true],
];
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark().copyWith(
scaffoldBackgroundColor: darkBlue,
),
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Center(
child: BookingPage(toDoList: toDoList),
),
),
);
}
}
class BookingPage extends StatefulWidget {
final List toDoList;
const BookingPage({
super.key,
required this.toDoList,
});
#override
State<BookingPage> createState() => _BookingPageState();
}
class _BookingPageState extends State<BookingPage> {
//Liste is an example what i have in my list
List toDoList2 = [
["Button 1", true],
["Button 2", true],
];
#override
void initState() {
super.initState();
}
void deleteTask(int index) {
setState(() {
widget.toDoList.removeAt(index);
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Booking Seiten'),
elevation: 0,
),
body: ListView.builder(
itemCount: widget.toDoList.length,
itemBuilder: (context, index) {
return ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: Colors.lightBlue,
padding: const EdgeInsets.all(12),
textStyle: const TextStyle(fontSize: 22),
),
child: Text(widget.toDoList[index][0]!),
onPressed: () => setState(() => deleteTask(index)),
);
},
),
);
}
}
Which tells me that the problem is your PreviewUrl. My guess is - it is a statful widget, and when the tree rebuilds - it will link the old State object to the first item.
Using Keys might help, something like:
return PreviewUrl(
key: ObjectKey(widget.toDoList[index]),
url2: widget.toDoList[index][0],
deleteFunction: (context) => setState(() => deleteTask(index)),
);

Flutter - Provider - Clearing Data itself when navigate

When I in a page and added some quantity and navigate to another page and come back to added more quantity data is cleared.
Here's my code.
add_inv_stream.dart
class AddInvStream extends StatelessWidget {
const AddInvStream({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
FirebaseServices services = FirebaseServices();
final provider = Provider.of<InventoryProvider>(context);
return StreamBuilder<QuerySnapshot>(
stream: services.inventory
.where('fishType', isEqualTo: provider.inventoryData['fishType'])
.where('status', isEqualTo: true)
.snapshots(),
builder: (context, snapshot) {
if (snapshot.hasError) {
return const Center(child: Text('Something wrong!'));
}
if (snapshot.connectionState == ConnectionState.waiting) {
return const Center(child: CircularProgressIndicator());
}
if (snapshot.data!.size == 0) {
return const Center(
child: Text('No inventories'),
);
}
return AddInvData(snapshot: snapshot, services: services);
},
);
}
}
add_inv_data.dart
class AddInvData extends StatefulWidget {
final AsyncSnapshot<QuerySnapshot<Object?>> snapshot;
final FirebaseServices services;
const AddInvData({Key? key, required this.snapshot, required this.services})
: super(key: key);
#override
State<AddInvData> createState() => _AddInvDataState();
}
class _AddInvDataState extends State<AddInvData> {
final _qty = TextEditingController();
List sellerList = [];
#override
Widget build(BuildContext context) {
final providerr = Provider.of<InventoryProvider>(context);
return ListView.builder(
padding: const EdgeInsets.all(15.0),
physics: const ScrollPhysics(),
shrinkWrap: true,
itemCount: widget.snapshot.data!.size,
itemBuilder: (context, index) {
Map<String, dynamic> sellerData =
widget.snapshot.data!.docs[index].data() as Map<String, dynamic>;
int sellerQty = int.parse(sellerData['qty']);
return InkWell(
onTap: () {
showDialog(
context: context,
useRootNavigator: false,
builder: (context) {
return Dialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(40),
),
elevation: 16,
child: Container(
padding: const EdgeInsets.all(20),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text('Quantity in kg: '),
const SizedBox(width: 10),
Container(
height: 60,
width: 60,
decoration: BoxDecoration(
border: Border.all(color: Colors.black),
),
child: TextFormField(
controller: _qty,
textAlign: TextAlign.center,
keyboardType: TextInputType.number,
decoration: const InputDecoration(
border: InputBorder.none,
),
),
),
],
),
const SizedBox(height: 50),
TextButton(
onPressed: () async {
Map<String, dynamic> seller = {
'date': sellerData['date'],
'qty': _qty.text,
};
sellerList.add(seller);
providerr.getData(sellerList: sellerList);
print(providerr.inventoryData['sellerList']);
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => const InvDetails(),
));
},
child: const Text('ASSIGN'),
),
],
),
),
);
},
);
},
child: Padding(
padding: const EdgeInsets.fromLTRB(10, 0, 10, 30),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
sellerData['date'],
style: const TextStyle(fontSize: 18),
),
Text(
'${sellerData['qty']} kg',
style: const TextStyle(fontSize: 18),
),
],
),
),
);
},
);
}
}
inv_details.dart
class InvDetails extends StatelessWidget {
const InvDetails({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: TextButton(
onPressed: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => const AddInv(),
));
},
child: const Text('Add Inventory'),
),
),
);
}
}
inv_provider.dart
class InventoryProvider with ChangeNotifier {
Map<String, dynamic> inventoryData = {};
getData({List? sellerList}) {
if (sellerList != null) {
inventoryData['sellerList'] = sellerList;
}
notifyListeners();
}
}
Here printing at the first
[{date: 10/31/2022, qty: 1}]
When I navigate to InvDetails from AddInvData and when the button is clicked it's printing
[{date: 11/25/2022, qty: 1}]
Data is not updating
But if I didn't navigate.
i.e If I stay in AddInvData and added quantity it is updating.
inv_data.dart (Added textbutton part only ) removed navigate
TextButton(
onPressed: () async {
Map<String, dynamic> seller = {
'date': sellerData['date'],
'qty': _qty.text,
};
sellerList.add(seller);
providerr.getData(sellerList: sellerList);
print(providerr.inventoryData['sellerList']);
},
prints
[{date: 10/31/2022, qty: 1}]
[{date: 10/31/2022, qty: 1}, {date: 11/25/2022, qty: 1}]
Why this is not hapenning when navigate and come back to previous page?

Flutter : Adding item from one list view to another list view

I am trying to select one item from phone contacts list (List view widget)
class PhoneContacts extends StatefulWidget {
const PhoneContacts({Key? key}) : super(key: key);
#override
State<PhoneContacts> createState() => _PhoneContactsState();
}
class _PhoneContactsState extends State<PhoneContacts> {
List<Contact> _contacts = [];
late PermissionStatus _permissionStatus;
late Customer _customer;
#override
void initState(){
super.initState();
getAllContacts();
}
void getAllContacts() async {
_permissionStatus = await Permission.contacts.request();
if(_permissionStatus.isGranted) {
List<Contact> contacts = await ContactsService.getContacts(withThumbnails: false);
setState(() {
_contacts = contacts;
});
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Phone Contacts"),
backgroundColor: Colors.indigo[600],
),
body: Container(
padding: const EdgeInsets.all(5),
child: ListView.builder(
itemCount: _contacts.length,
itemBuilder: (BuildContext context, int index) {
Contact contact = _contacts[index];
return contactItem(contact);
}
),
),
);
}
Widget contactItem(Contact contact){
return ListTile(
onTap: () {
Navigator.of(context).push(MaterialPageRoute(builder: (context)=>Dashboard(contact)));
},
leading: const CircleAvatar(
backgroundColor: Colors.pinkAccent,
child: Icon(Icons.person_outline_outlined)),
title : Text(contact.displayName.toString()),
subtitle: Text(contact.phones!.first.value.toString()),
);
}
}
and insert and display it to dashboard list (another List view widget)
class Dashboard extends StatefulWidget {
final Contact? contact;
const Dashboard([this.contact]);
#override
State<Dashboard> createState() => _DashboardState();
}
class _DashboardState extends State<Dashboard> {
final Color? themeColor = Colors.indigo[600];
late GlobalKey<RefreshIndicatorState> refreshKey;
late List<CardGenerator> existingCustomerContactList = getCustomerContactList();
#override
void initState(){
super.initState();
refreshKey=GlobalKey<RefreshIndicatorState>();
}
void addCustomerContact() {
existingCustomerContactList.add(
CardGenerator(
Text(widget.contact!.displayName.toString()),
const Icon(Icons.account_circle),
Text(widget.contact!.phones!.first.value.toString())));
}
List<CardGenerator> getCustomerContactList () {
existingCustomerContactList = [
CardGenerator(
const Text('Dave', style: TextStyle(fontSize: 24.0), textAlign: TextAlign.start,),
const Icon(Icons.account_circle, size: 100, color: Colors.white,),
const Text('Address 1')),
CardGenerator(
const Text('John', style: TextStyle(fontSize: 24.0)),
const Icon(Icons.account_circle, size: 100, color: Colors.white),
const Text('Address 2')),
CardGenerator(
const Text('Richard', style: TextStyle(fontSize: 24.0)),
const Icon(Icons.account_circle, size: 100, color: Colors.white),
const Text('Address 3')),
];
return existingCustomerContactList;
}
Future<void> refreshList() async {
await Future.delayed(const Duration(seconds: 1));
setState(() => {
addCustomerContact(),
getCustomerContactList()
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.grey[50],
appBar: AppBar(
title: const Text("Dashboard"),
backgroundColor: themeColor,
),
body: RefreshIndicator(
key: refreshKey,
onRefresh: () async {
await refreshList();
},
child: Column(
children: [
Expanded(
child: ListView.builder(
itemCount: existingCustomerContactList.length,
key: UniqueKey(),
itemBuilder: (BuildContext context, int index) {
return OpenContainer(
closedColor: Colors.transparent,
closedElevation: 0.0,
openColor: Colors.transparent,
openElevation: 0.0,
transitionType: ContainerTransitionType.fadeThrough,
closedBuilder: (BuildContext _, VoidCallback openContainer) {
return Card(
color: Colors.white,
child: GestureDetector(
onTap: openContainer,
child: SizedBox(
height: 140,
child: Row(
children: [
Container(
decoration: const BoxDecoration(
color: Colors.indigo,
borderRadius: BorderRadius.only(topLeft: Radius.circular(7.0),bottomLeft: Radius.circular(7.0))
),
height: 140,
width: 120,
child: existingCustomerContactList[index].icon,
),
Column(
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: existingCustomerContactList[index].title,
),
Padding(
padding: const EdgeInsets.all(8.0),
child: existingCustomerContactList[index].address,
),
],
)
],
),
),
),
);
},
openBuilder: (BuildContext _, VoidCallback openContainer) {
return ConsumerHome();
}
);
}),
),
],
),
),
);
}
}
I found the
selected item has been added to the Dashboard items list but when I refresh it it doesn't newly added item in the dashboard list view.
I am a newcomer in flutter please bare with me. I already did my search for this problem unfortunately, no luck.
Change the order of execution. You are adding the item in the list and then making a new list again in the current order
addCustomerContact(),
getCustomerContactList()
change this to
getCustomerContactList()
addCustomerContact(),

How to fix "Too many positional arguments: 1 expected, but 3 found." issue in flutter

I'm new to flutter.
I need to get product information through a form using flutter provider.
I can get one object(like String name value only). But when I add multiple parameters, it shows the following error.
Too many positional arguments: 1 expected, but 3 found.
This is the code I wrote.
Model class
class Item {
String itemName;
String description;
double itemPrice;
Item(this.itemName, this.description, this.itemPrice);
}
ChangeNotifier class
class ItemAddNotifier extends ChangeNotifier {
List<Item> itemList = [];
addItem(String itemName, String description, double itemPrice) {
Item item = Item(itemName, description, itemPrice);
itemList.add(item);
notifyListeners();
}
}
Add items
class AddItems extends StatelessWidget {
final TextEditingController _itemNameTextEditing = TextEditingController();
final TextEditingController _itemDescriptionTextEditing =
TextEditingController();
final TextEditingController _itemPriceTextEditing = TextEditingController();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Kavishka'),
),
body: Container(
padding: EdgeInsets.all(30.0),
child: Column(
children: [
TextField(
controller: _itemNameTextEditing,
decoration: InputDecoration(
contentPadding: EdgeInsets.all(15.0),
hintText: 'Item Name',
),
),
SizedBox(
height: 20.0,
),
TextField(
controller: _itemDescriptionTextEditing,
decoration: InputDecoration(
contentPadding: EdgeInsets.all(15.0),
hintText: 'Item Description',
),
),
SizedBox(
height: 20.0,
),
TextField(
controller: _itemPriceTextEditing,
decoration: InputDecoration(
contentPadding: EdgeInsets.all(15.0),
hintText: 'Item Price',
),
),
SizedBox(
height: 20.0,
),
RaisedButton(
child: Text('ADD ITEM'),
onPressed: () async {
if (_itemNameTextEditing.text.isEmpty) {
return;
}
await Provider.of<ItemAddNotifier>(context, listen: false)
.addItem(
_itemNameTextEditing.text,
_itemDescriptionTextEditing.text,
_itemPriceTextEditing.text);
Navigator.pop(context);
},
),
],
),
),
);
}
}
Home Screen
class HomeScreen extends StatelessWidget {
const HomeScreen({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Kavishka'),
actions: [
IconButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
fullscreenDialog: true,
builder: (context) {
return AddItems();
},
),
);
},
icon: Icon(Icons.add))
],
),
body: Container(
padding: EdgeInsets.all(30.0),
child: Column(
children: [
Consumer<ItemAddNotifier>(builder: (context, itemAddNotifier, _) {
return ListView.builder(
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemCount: itemAddNotifier.itemList.length,
itemBuilder: (context, index) {
return Padding(
padding: EdgeInsets.all(15.0),
child: Column(
children: [
Text(
itemAddNotifier.itemList[index].itemName,
style:
TextStyle(fontSize: 20.0, color: Colors.black),
),
],
),
);
});
})
],
),
),
);
}
}
Main
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: (BuildContext context) {
return ItemAddNotifier();
},
child: MaterialApp(
home: Container(
color: Colors.white,
child: HomeScreen(),
),
),
);
}
}
It shows the error in Item item = Item(itemName, description, itemPrice); line.
If someone can help me to fix this issue.
Thank you.