In my program, users can create posts. And every post is called stuff
. When an user created a stuff, automatically a stuffID
assigns to that stuff. Also, I can list those stuffs in user's profile. When a user presses the edit
button of one of their stuffs, a form appears in the screen. So the thing i want to do is when user press the edit button, I want to pass the stuffID
from profile_sheet.dart
class to update_stuff_form.dart
class, so I can know to update the which stuff i will.
I have two .dart file. I used this function in my edit button in profile_sheet.dart file:
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => updateStuffForm(
stuffID: data['stuffID'].toString())));
And I added my key function into update_stuff_form.dart like so:
class updateStuffForm extends StatefulWidget {
//const updateStuffForm({Key? key}) : super(key: key);
updateStuffForm({Key? key, this.stuffID}) : super(key: key);
final String? stuffID;
@override
_updateStuffFormState createState() => _updateStuffFormState();
}
And I called stuffID from end of the update_stuff_form.dart like this:
widget.stuffID
But whenever I run the program and press the edit button, It gaves me error below:
ErrorSummary('No Material widget found.'),
ErrorDescription(
'${context.widget.runtimeType} widgets require a Material '
'widget ancestor.\n'
'In material design, most widgets are conceptually "printed" on '
"a sheet of material. In Flutter's material library, that "
'material is represented by the Material widget. It is the '
'Material widget that renders ink splashes, for instance. '
'Because of this, many material library widgets require that '
'there be a Material widget in the tree above them.',
),
ErrorHint(
'To introduce a Material widget, you can either directly '
'include one, or use a widget that contains Material itself, '
'such as a Card, Dialog, Drawer, or Scaffold.',
),
Here is my full profile_sheet.dart file:
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:unistuff_main/screens/home/update_stuff_form.dart';
class profileSheet extends StatefulWidget {
const profileSheet({Key? key}) : super(key: key);
@override
_profileSheetState createState() => _profileSheetState();
}
class _profileSheetState extends State<profileSheet> {
final _formkey = GlobalKey<FormState>();
//funcs
@override
Widget build(BuildContext context) {
return Container(
child: userStuffList(),
);
}
}
class userStuffList extends StatelessWidget {
const userStuffList({Key? key}) : super(key: key);
void _editStuff(BuildContext context) {
//stuff_form link.
showModalBottomSheet<dynamic>(
isScrollControlled: true,
context: context,
builder: (context) {
return Container(
padding: EdgeInsets.symmetric(vertical: 20.0, horizontal: 60.0),
child: updateStuffForm());
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: _userStuffList(),
);
}
}
class _userStuffList extends StatelessWidget {
void _editStuff(BuildContext context) {
//stuff_form'a yönlendirme.
showModalBottomSheet<dynamic>(
isScrollControlled: true,
context: context,
builder: (context) {
return Container(
padding: EdgeInsets.symmetric(vertical: 20.0, horizontal: 60.0),
child: updateStuffForm());
});
}
@override
Widget build(BuildContext context) {
final FirebaseAuth auth = FirebaseAuth.instance;
final User? user = auth.currentUser;
final _uid = user!.uid;
Query _stuffStream = FirebaseFirestore.instance
.collection('Stuffs')
.where('userID', isEqualTo: _uid);
return Material(
child: StreamBuilder<QuerySnapshot>(
//veri akışı başlatılıyor
//akış oluşturuluyor
stream: _stuffStream.snapshots(),
builder:
(BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (snapshot.hasError) {
return Text('Something is wrong.');
}
if (snapshot.connectionState == ConnectionState.waiting) {
return Text("Loading");
}
return ListView(
//showing the data
children: snapshot.data!.docs.map((DocumentSnapshot document) {
Map<String, dynamic> data =
document.data()! as Map<String, dynamic>;
String stuffID = data['stuffID'];
return ListTile(
title: Text(data['title']),
subtitle: Column(
children: <Widget>[
Text(data['details']),
TextButton(
child: const Text('Düzenle'),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => updateStuffForm(
stuffID: data['stuffID'].toString())));
_editStuff(context);
})
],
),
);
}).toList(),
);
}),
);
}
}
And my full update_stuff_form.dart (My key reference at first class, my widget.stuffID
call all end of it.
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
//import 'package:unistuff_main/screens/home/profile_sheet.dart';
class updateStuffForm extends StatefulWidget {
//const updateStuffForm({Key? key}) : super(key: key);
updateStuffForm({Key? key, this.stuffID}) : super(key: key);
final String? stuffID;
@override
_updateStuffFormState createState() => _updateStuffFormState();
}
class _updateStuffFormState extends State<updateStuffForm> {
final _formkey = GlobalKey<FormState>();
final List<String> categories = ["Spor", "Vasıta", "Elektronik"];
editStuff(stuffID) {
final FirebaseAuth auth = FirebaseAuth.instance;
final User? user = auth.currentUser;
final _uid = user!.uid;
FirebaseFirestore.instance.collection('Stuffs').doc(stuffID).update({
'title': _currentTitle,
'details': _currentDetails,
'price': _currentPrice,
'category': _currentCategory,
'userID': _uid
});
}
bool validatePrice(String str) {
RegExp _numeric = RegExp(r'^-?[0-9] $');
return _numeric.hasMatch(str);
}
//form values
String? _currentTitle;
String? _currentDetails;
String? _currentPrice;
String? _currentCategory;
@override
Widget build(BuildContext context) {
return Form(
key: _formkey,
child: SingleChildScrollView(
child: Column(
children: <Widget>[
Text(
'Edit your stuff',
style: TextStyle(fontSize: 18.0),
),
SizedBox(height: 20.0),
TextFormField(
decoration: InputDecoration(
fillColor: Colors.brown, hintText: 'Title', filled: true),
validator: (val) {
if ((validatePrice(val!) == false)) {
return "Please enter a number";
}
if (val.isEmpty == true) {
return "Please enter a value";
}
return null;
},
onChanged: (val) => setState(() => _currentTitle = val),
),
SizedBox(height: 20.0),
TextFormField(
keyboardType: TextInputType.multiline,
minLines: 1, //Normal textInputField will be displayed
maxLines: 5,
decoration: InputDecoration(
fillColor: Colors.brown, hintText: 'Details', filled: true),
validator: (val) =>
val!.isEmpty ? 'Please add a detail' : null,
onChanged: (val) => setState(() => _currentDetails = val),
),
SizedBox(height: 20.0),
TextFormField(
decoration: InputDecoration(
fillColor: Colors.brown, hintText: 'Price', filled: true),
validator: (val) =>
val!.isEmpty ? 'Please enter a price' : null,
onChanged: (val) => setState(() => _currentPrice = val),
),
SizedBox(height: 20.0),
DropdownButtonFormField(
items: categories.map((category) {
return DropdownMenuItem(
value: category,
child: Text('$category'),
);
}).toList(),
onChanged: (val) =>
setState(() => _currentCategory = val as String?),
),
ElevatedButton(
style: ElevatedButton.styleFrom(
primary: Colors.pink[400],
),
child: Text('Ekle', style: TextStyle(color: Colors.white)),
onPressed: () async {
editStuff(widget.stuffID);
},
),
],
),
),
);
}
}
CodePudding user response:
With the information about screens provided, I can see that your profile_sheet.dart
is not having MaterialApp()
as the first ancestor. So in place of Material()
, use MaterialApp()
.
Inside build
method of profile_sheet.dart, replace Material()
to:
return MaterialApp()