[英]Flutter: How to pass snapshot to floating action button?
I want to pass this documentSnapshot
to my FloatingActionButton
so that I can use it on another page, but how?我想将此
documentSnapshot
传递到我的FloatingActionButton
以便我可以在另一个页面上使用它,但是如何呢? I want to pass the documentSnapshot
data to my AddTaskPage
.我想将
documentSnapshot
数据传递给我的AddTaskPage
。
My documentSnapshot
is under StreamBuilder
.我的
documentSnapshot
在StreamBuilder
下。
This is my code:这是我的代码:
final DocumentSnapshot documentSnapshot = snapshot.data!.docs[index];
This is my FloatingActionButton
:这是我的
FloatingActionButton
:
floatingActionButton: FadeInRight(
delay: const Duration(milliseconds: 200),
duration: const Duration(milliseconds: 500),
child: FloatingActionButton.extended(
label: const Text(
'Add Timeline',
style: TextStyle(
color: Colors.white,
fontFamily: 'poppins',
fontWeight: FontWeight.w400,
fontSize: 15,
letterSpacing: 1,
),
),
backgroundColor: Colors.black,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(6),
),
onPressed: () {
showModalBottomSheet(
// isScrollControlled: true,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(10),
topRight: Radius.circular(10),
),
),
context: context,
builder: (context) => const AddTaskPage(),
);
},
),
),
This is my AddTaskPage() code:这是我的 AddTaskPage() 代码:
import 'package:animate_do/animate_do.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:provider/provider.dart';
import 'package:todoapp/authentication/auth.provider.dart';
import 'package:todoapp/models/timeline.model.dart';
import 'package:todoapp/services/notifications_service.dart';
class AddTaskPage extends StatefulWidget {
const AddTaskPage({
super.key,
});
@override
State<AddTaskPage> createState() => _AddTaskPageState();
}
class _AddTaskPageState extends State<AddTaskPage> {
final dateController = TextEditingController();
final timeController = TextEditingController();
final topicController = TextEditingController();
final _formKey = GlobalKey<FormState>();
final db = FirebaseFirestore.instance;
final notifyHelper = NotifyHelper();
DocumentReference uidRef = FirebaseFirestore.instance
.collection('timeline')
.doc(FirebaseAuth.instance.currentUser!.uid);
void dateOnTap() async {
TimeOfDay? pickTime = await showTimePicker(
context: context,
initialEntryMode: TimePickerEntryMode.input,
initialTime: TimeOfDay.now());
if (pickTime != null) {
DateTime parsedTime =
DateFormat.jm().parse(pickTime.format(context).toString());
//converting to DateTime so that we can further format on different pattern.
String formattedTime = DateFormat().add_jm().format(parsedTime);
setState(() {
timeController.text = formattedTime;
// DateFormat.yMMMMd().format(pickTime);
});
}
}
// String uidFunction(String uid) {
// // dart unique string generator
// String _randomString = uid.toString() +
// math.Random().nextInt(9999).toString() +
// math.Random().nextInt(9999).toString() +
// math.Random().nextInt(9999).toString();
// return _randomString;
// }
void addFunction() async {
final uid =
await Provider.of<AuthProvider>(context, listen: false).getCurrentUID();
DocumentReference ref =
db.collection('users').doc(uid).collection('time-line').doc();
if (dateController.text.trim().isNotEmpty &&
timeController.text.trim().isNotEmpty &&
topicController.text.trim().isNotEmpty) {
await db
.collection('users')
.doc(uid)
.collection('time-line')
.add(Timeline(
id: ref.id, // auto generated id
date: dateController.text.trim(),
time: timeController.text.trim(),
topic: topicController.text.trim(),
isDone: false)
.toJson());
// DateTime date = DateFormat.jm().parse(timeController.text.toString());
// var myTime = DateFormat('HH:mm').format(date);
// var hour = int.parse(formattedTime.toString().split(':')[0]);
// var min = int.parse(formattedTime.toString().split(':')[1]);
notifyHelper.displayNotification(
title: topicController.text.trim(), body: 'Don\'t forget your task!');
// notifyHelper.scheduledNotification(hour, min, timeline);
} else {
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
content: Text(
'All fields required!',
style: TextStyle(fontFamily: 'poppins', fontWeight: FontWeight.w400),
)));
}
Navigator.of(context).pop();
}
void cancelAddFunction() {
Navigator.of(context).pop();
}
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 30, vertical: 15),
child: Column(
children: [
Container(
width: 60,
height: 5,
decoration: BoxDecoration(
color: Colors.grey.shade300,
borderRadius: BorderRadius.circular(10)),
),
const SizedBox(
height: 20,
),
const Align(
alignment: Alignment.topLeft,
child: Text(
'Add timeline 🗓️',
style: TextStyle(
color: Colors.black,
fontFamily: 'poppins',
fontWeight: FontWeight.w500,
fontSize: 20,
letterSpacing: 1),
),
),
const SizedBox(
height: 30,
),
Form(
key: _formKey,
child: Column(
children: [
textFieldDate(
dateController, 'Date', Icons.date_range_outlined),
const SizedBox(
height: 20,
),
textFieldTime(
timeController,
DateFormat.jm().format(DateTime.now()),
const Icon(
Icons.calendar_month_outlined,
color: Colors.black,
),
dateOnTap),
const SizedBox(
height: 20,
),
textFieldTopic(
topicController,
'Topic',
const Icon(
Icons.topic_outlined,
color: Colors.black,
)),
],
),
),
Expanded(child: Container()),
btnSection()
],
),
);
}
Widget textFieldDate(
controller,
hintText,
icon,
) {
return FadeInUp(
duration: const Duration(milliseconds: 700),
child: TextFormField(
readOnly: true,
cursorColor: Colors.black,
style: const TextStyle(
fontFamily: 'poppins',
fontWeight: FontWeight.w400,
fontSize: 15,
color: Colors.black),
onTap: (() async {
DateTime? pickDate = await showDatePicker(
context: context,
initialDate: DateTime.now(),
firstDate: DateTime(2000),
lastDate: DateTime(3000));
if (pickDate != null) {
setState(() {
controller.text = DateFormat.yMMMMd().format(pickDate);
});
}
}),
decoration: InputDecoration(
contentPadding: const EdgeInsets.all(15),
prefixIcon: Icon(
icon,
color: Colors.black,
),
filled: true,
fillColor: Colors.white,
hintText: hintText,
hintStyle: const TextStyle(
fontFamily: 'poppins',
fontWeight: FontWeight.w400,
fontSize: 15,
color: Color(0xff929292)),
focusedBorder: const OutlineInputBorder(
borderSide: BorderSide(color: Colors.black, width: 1)),
enabledBorder: const OutlineInputBorder(
borderSide: BorderSide(color: Colors.grey, width: 1)),
errorBorder: const OutlineInputBorder(
borderSide: BorderSide(
color: Colors.red, style: BorderStyle.solid, width: 1)),
focusedErrorBorder: const OutlineInputBorder(
borderSide: BorderSide(
color: Colors.red, style: BorderStyle.solid, width: 1))),
controller: controller,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please fill the text field!';
}
return null;
},
),
);
}
Widget textFieldTime(controller, hintText, icon, dateOnTap) {
return FadeInUp(
duration: const Duration(milliseconds: 700),
child: TextFormField(
readOnly: true,
cursorColor: Colors.black,
style: const TextStyle(
fontFamily: 'poppins',
fontWeight: FontWeight.w400,
fontSize: 15,
color: Colors.black),
onTap: dateOnTap,
decoration: InputDecoration(
contentPadding: const EdgeInsets.all(15),
prefixIcon: icon,
filled: true,
fillColor: Colors.white,
hintText: hintText,
hintStyle: const TextStyle(
fontFamily: 'poppins',
fontWeight: FontWeight.w400,
fontSize: 15,
color: Color(0xff929292)),
focusedBorder: const OutlineInputBorder(
borderSide: BorderSide(color: Colors.black, width: 1)),
enabledBorder: const OutlineInputBorder(
borderSide: BorderSide(color: Colors.grey, width: 1)),
errorBorder: const OutlineInputBorder(
borderSide: BorderSide(
color: Colors.red, style: BorderStyle.solid, width: 1)),
focusedErrorBorder: const OutlineInputBorder(
borderSide: BorderSide(
color: Colors.red, style: BorderStyle.solid, width: 1))),
controller: controller,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please fill the text field!';
}
return null;
},
),
);
}
Widget textFieldTopic(controller, hintText, icon) {
return FadeInUp(
duration: const Duration(milliseconds: 700),
child: TextFormField(
minLines: 1,
maxLines: 3,
cursorColor: Colors.black,
style: const TextStyle(
fontFamily: 'poppins',
fontWeight: FontWeight.w400,
fontSize: 15,
color: Colors.black),
decoration: InputDecoration(
contentPadding: const EdgeInsets.all(15),
prefixIcon: icon,
filled: true,
fillColor: Colors.white,
hintText: hintText,
hintStyle: const TextStyle(
fontFamily: 'poppins',
fontWeight: FontWeight.w400,
fontSize: 15,
color: Color(0xff929292)),
focusedBorder: const OutlineInputBorder(
borderSide: BorderSide(color: Colors.black, width: 1)),
enabledBorder: const OutlineInputBorder(
borderSide: BorderSide(color: Colors.grey, width: 1)),
errorBorder: const OutlineInputBorder(
borderSide: BorderSide(
color: Colors.red, style: BorderStyle.solid, width: 1)),
focusedErrorBorder: const OutlineInputBorder(
borderSide: BorderSide(
color: Colors.red, style: BorderStyle.solid, width: 1))),
controller: controller,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please fill the text field!';
}
return null;
},
),
);
}
Widget btnAddTimeline(addFunction, text) {
return FadeInUp(
duration: const Duration(milliseconds: 500),
delay: const Duration(milliseconds: 200),
child: ElevatedButton(
onPressed: addFunction,
style: ButtonStyle(
elevation: MaterialStateProperty.all(0),
backgroundColor: MaterialStateProperty.all(Colors.black),
fixedSize: MaterialStateProperty.all(const Size(0, 54)),
shape: MaterialStateProperty.all(RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10)))),
child: Text(
text,
style: const TextStyle(
color: Colors.white,
fontFamily: 'poppins',
fontWeight: FontWeight.w400,
fontSize: 17,
letterSpacing: 1),
)),
);
}
Widget btnCancelAddTimeline(cancelAddFunction, icon) {
return FadeInLeft(
duration: const Duration(milliseconds: 500),
delay: const Duration(milliseconds: 200),
child: ElevatedButton(
onPressed: cancelAddFunction,
style: ButtonStyle(
side: MaterialStateProperty.all(
const BorderSide(color: Colors.black)),
elevation: MaterialStateProperty.all(0),
backgroundColor: MaterialStateProperty.all(Colors.white),
fixedSize: MaterialStateProperty.all(const Size(0, 54)),
shape: MaterialStateProperty.all(RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10)))),
child: Icon(
icon,
color: Colors.black,
)),
);
}
Widget btnSection() {
return Row(
children: [
Expanded(
flex: 1,
child: btnCancelAddTimeline(cancelAddFunction, Icons.clear)),
const SizedBox(
width: 10,
),
Expanded(
flex: 4, child: btnAddTimeline(addFunction, 'Add New Timeline'))
],
);
}
}
Depend a lot of what you want to do with these data and where you define your document snapshot.很大程度上取决于您要对这些数据执行的操作以及定义文档快照的位置。
But reading your question, i guess your FAB is defined in a Scaffold and your StreamBuilder inside the Scaffold body?但是阅读您的问题,我猜您的 FAB 是在脚手架中定义的,而您的 StreamBuilder 是在脚手架体内定义的吗?
If so you can invert these and access documentSnapshot.data()
in all of your Scaffold children (FAB included).如果是这样,您可以反转这些并在所有脚手架子项(包括 FAB)中访问
documentSnapshot.data()
)。 Something like that:像这样的东西:
StreamBuilder(
stream: getUsersTimelineSnapshots(context)
.map((snapshot) => snapshot.docs.toList()),
builder: (context, snapshot) {
if (snapshot.hasError) {
return Scaffold(
body: Text('Error: ${snapshot.error}'),
);
}
if (!snapshot.hasData) {
return Scaffold(
body: Text('Loading...'),
);
}
return Scaffold(
//Your FAB
floatingActionButton: FadeInRight(
delay: const Duration(milliseconds: 200),
duration: const Duration(milliseconds: 500),
child: FloatingActionButton.extended(
label: const Text(
'Add Timeline',
style: TextStyle(
color: Colors.white,
fontFamily: 'poppins',
fontWeight: FontWeight.w400,
fontSize: 15,
letterSpacing: 1),
),
backgroundColor: Colors.black,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(6)),
onPressed: () {
showModalBottomSheet(
// isScrollControlled: true,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(10),
topRight: Radius.circular(10))),
context: context,
builder: (context) => const AddTaskPage(snapshot.data));//Here you will get a List<DocumentSnapshot>
},
),
),
//Rest of your old scaffold here
);
},
);
But again, without more infos about your code, it will be difficult to provide a more accurate answer.但是同样,如果没有关于您的代码的更多信息,将很难提供更准确的答案。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.