I am unable to display the messages that i receive i am using firebase firestore. i am trying to get all the messages with the stream builder and displaying it.
Stream Builder Class
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:instagram_clone/Models/user_model.dart';
import 'package:instagram_clone/Provider/user_provider.dart';
import 'package:instagram_clone/utils/circular_progress_indicator.dart';
import 'package:instagram_clone/utils/colors.dart';
import 'package:instagram_clone/utils/utils.dart';
import 'package:instagram_clone/widgets/message_bubbles.dart';
import 'package:provider/provider.dart';
import '../resources/Firestore_methods.dart';
class MessagesScreen extends StatefulWidget {
String recieveruid;
MessagesScreen({Key? key,required this.recieveruid}) : super(key: key);
#override
State<MessagesScreen> createState() => _MessagesScreenState();
}
class _MessagesScreenState extends State<MessagesScreen> {
String recieverName=' ';
String reciverDp=' ';
bool isFetched=false;
TextEditingController messagecontoller=TextEditingController();
void sendMessage()async{
if(messagecontoller.text.isNotEmpty){
String res=await FireStoreMethods().sendMessage(
senderUid: FirebaseAuth.instance.currentUser!.uid,
recieverUid: widget.recieveruid,
message: messagecontoller.text);
if(res!='success'){
Utils().showSnackBar(context, 'Unable to send message kindly check your connection', Colors.red);
}
}
}
void getRecieverDetails()async{
DocumentSnapshot ref= await FirebaseFirestore.instance.collection('users').doc(widget.recieveruid).get();
recieverName=ref['username'];
reciverDp=ref['photourl'];
setState(() {
isFetched=true;
});
}
#override
void initState() {
print(widget.recieveruid);
getRecieverDetails();
// TODO: implement initState
super.initState();
}
#override
void dispose() {
messagecontoller.dispose();
// TODO: implement dispose
super.dispose();
}
bool _isReciever=true;
#override
Widget build(BuildContext context) {
UserModel user=Provider.of<UserProvider>(context).getUser;
return !isFetched?Center(child: CircularIndicator,):Scaffold(
appBar: AppBar(
title: Text(recieverName),
backgroundColor: mobileBackgroundColor,
centerTitle: true,
),
body: Stack(
children: [
Container(
height: MediaQuery.of(context).size.height*0.8,
child: StreamBuilder(
stream: FirebaseFirestore.instance
.collection('chats')
.where('senderuid',isEqualTo: FirebaseAuth.instance.currentUser!.uid )
.where('recieveruid',isEqualTo: widget.recieveruid)
.snapshots(),
builder: (context,AsyncSnapshot<QuerySnapshot<Map<String,dynamic>>>snapshot){
if(!snapshot.hasData || snapshot.connectionState==ConnectionState.waiting){
return Center(child: CircularIndicator);
}
else{
return ListView.builder(
itemCount: snapshot.data!.docs.length,
itemBuilder: (context,index){
if(snapshot.data!.docs[index]['senderuid']==FirebaseAuth.instance.currentUser!.uid){
return MessageBubbles(profilePic: user.photourl,
message: snapshot.data!.docs[index]['message'],
date: snapshot.data!.docs[index]['datetime'],
isReciever: false);
}
else{
return MessageBubbles(
profilePic: reciverDp,
message: snapshot.data!.docs[index]['message'],
date:snapshot.data!.docs[index]['datetime'],
isReciever: true);
}
});
}
}
),
),
Align(
alignment: Alignment.bottomCenter,child: Container(
child: Row(
children: [
Expanded(
child: TextFormField(
controller: messagecontoller,
maxLines: null,
decoration: InputDecoration(
hintText: 'Message...',
contentPadding: EdgeInsets.symmetric(horizontal: 8),
border: InputBorder.none
),
),
),
TextButton(onPressed: ()async{
sendMessage();
messagecontoller.clear();
}, child: Text('Send',style: TextStyle(
color: Colors.blueAccent,
fontWeight: FontWeight.bold,
fontSize: 15
),))
],
),
decoration: BoxDecoration(
border: Border.all(color: secondaryColor),
borderRadius: BorderRadius.circular(20),
color: mobileBackgroundColor,
),
),),
],
),
);
}
}
Here is Message Bubble Class
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import '../utils/colors.dart';
class MessageBubbles extends StatefulWidget {
String profilePic;
String message;
final date;
bool isReciever;
MessageBubbles({Key? key,
required this.profilePic,
required this.message,
required this.date,
required this.isReciever
}) : super(key: key);
#override
State<MessageBubbles> createState() => _MessageBubblesState();
}
class _MessageBubblesState extends State<MessageBubbles> {
#override
Widget build(BuildContext context) {
return widget.isReciever?Padding(
padding: const EdgeInsets.symmetric(vertical: 4.0),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
CircleAvatar(
backgroundImage: NetworkImage(widget.profilePic),
),
FittedBox(
child: Container(
width: MediaQuery.of(context).size.width*0.6,
constraints: BoxConstraints(
maxWidth: double.infinity,
maxHeight: double.infinity
),
decoration: BoxDecoration(
borderRadius: BorderRadius.only
(topRight: Radius.circular(10),
bottomLeft: Radius.circular(10),
bottomRight: Radius.circular(10),
),
color: Colors.grey.withOpacity(0.3),
),
child: Padding(
padding: const EdgeInsets.all(10.0),
child: Text(widget.message),
),
),
),
Text(DateFormat.yMMMd().format(widget.date.toDate()),style: TextStyle(
color: secondaryColor,
fontSize: 12
),),
],
),
],
),
):
Padding(
padding: const EdgeInsets.symmetric(vertical: 4.0),
child: Column(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Text(DateFormat.yMMMd().format(widget.date.toDate()).toString(),style: TextStyle(
color: secondaryColor,
fontSize: 12
),),
FittedBox(
child: Container(
width: MediaQuery.of(context).size.width*0.6,
constraints: BoxConstraints(
maxWidth: double.infinity,
maxHeight: double.infinity
),
decoration: BoxDecoration(
borderRadius: BorderRadius.only
(topRight: Radius.circular(10),
bottomLeft: Radius.circular(10),
topLeft: Radius.circular(10),
),
color: Colors.blueAccent,
),
child: Padding(
padding: const EdgeInsets.all(10.0),
child: Text(widget.message),
),
),
),
CircleAvatar(
backgroundImage: NetworkImage(widget.profilePic),
),
],
),
],
),
);
}
}
Here is the output snippet
Here is the firebase collection snippet
current stream's snapshot is List Type of Recieveruid // senderuid>recieveruid>snapshots()
and you get the user id from senderuid’s snapshots() ? feel something wrong....
I think you should set up a separate listener for senderuid
Related
I created a button shape called 'VocabularyWordsButton' and when I try it under a ListView it works just fine. But when I make 100 buttons under ListView, I want to find them via Search Bar. But I don't know how to do it somehow.
What I want to do: I want to distinguish the buttons by filtering the word 'englishWord' among the buttons listed below. When I enter the word in 'englishWord' in Search Bar, I want the buttons containing that word to be filtered.
If I do something like below, only the texts inside are listed, not the button I made.
VocabularyWordsButton.dart
import 'package:being_moroccan/AdHelper.dart';
import 'package:flutter/material.dart';
import 'package:audioplayers/audioplayers.dart';
import 'package:sizer/sizer.dart';
import 'package:google_mobile_ads/google_mobile_ads.dart';
import 'package:easy_localization/easy_localization.dart';
class VocabularyWordsButton extends StatefulWidget {
VocabularyWordsButton(
{required this.englishWord,
required this.trasncribedWord,
required this.arabicWord,
required this.sound});
final String englishWord;
final String trasncribedWord;
final String arabicWord;
final String sound;
#override
_VocabularyWordsButtonState createState() => _VocabularyWordsButtonState();
}
class _VocabularyWordsButtonState extends State<VocabularyWordsButton> {
AdHelper adHelper = AdHelper();
#override
void didChangeDependencies() {
// TODO: implement didChangeDependencies
super.didChangeDependencies();
adHelper.myLargeBanner.load();
}
bool _canShowButton = true;
void hideWidget() {
setState(() {
_canShowButton = !_canShowButton;
});
}
final AudioCache _audioCache = AudioCache(
prefix: 'audio/',
fixedPlayer: AudioPlayer()..setReleaseMode(ReleaseMode.STOP),
);
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: !_canShowButton
? Column(
children: [
Container(
height: 195.h / 6,
decoration: BoxDecoration(
color: Colors.transparent,
borderRadius: BorderRadius.all(Radius.circular(20)),
),
child: Container(
height: 100,
child: Column(
children: [
Container(
width: MediaQuery.of(context).size.width,
decoration: BoxDecoration(
borderRadius:
BorderRadius.all(Radius.circular(20))),
child: Center(
child: TextButton(
onPressed: () {
hideWidget();
},
child: Container(
width: MediaQuery.of(context).size.width,
child: Center(
child: Text(
widget.englishWord,
style: TextStyle(
fontSize: 30.sp / 2,
color: Colors.white),
),
),
),
),
),
),
ElevatedButton(
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all<Color>(
Colors.transparent),
shape: MaterialStateProperty.all<
RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius:
BorderRadius.all(Radius.circular(20)),
),
),
),
onPressed: () {
print('cal');
_audioCache.play('${widget.sound}.mp3');
},
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Padding(
padding: const EdgeInsets.all(2.0),
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(
'TRANSCRIBED'.tr(),
style: TextStyle(
fontSize: 25.sp / 2,
),
),
Container(
width:
MediaQuery.of(context).size.width /
2,
height: 60.h / 7,
child: Center(
child: Text(
widget.trasncribedWord,
style: TextStyle(
fontSize: 25.sp / 2,
),
),
),
),
],
),
),
Padding(
padding: const EdgeInsets.all(2.0),
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(
'ARABIC'.tr(),
style: TextStyle(
fontSize: 25.sp / 2,
),
),
Container(
width:
MediaQuery.of(context).size.width /
2,
height: 60.h / 7,
child: Center(
child: Text(
widget.arabicWord,
style: TextStyle(
fontSize: 25.sp / 2,
),
),
),
),
],
),
),
],
),
),
),
],
),
),
),
Container(
height: 100,
child: AdWidget(ad: adHelper.myLargeBanner),
),
],
)
: Container(
width: MediaQuery.of(context).size.width / 2,
decoration: BoxDecoration(
color: Colors.grey.withOpacity(0.1),
borderRadius: BorderRadius.all(Radius.circular(20))),
child: Center(
child: ElevatedButton(
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.all<Color>(Colors.transparent),
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(20)),
),
),
),
onPressed: () {
hideWidget();
},
child: Container(
width: MediaQuery.of(context).size.width,
child: Center(
child: Text(
widget.englishWord,
style:
TextStyle(fontSize: 30.sp / 2, color: Colors.white),
),
),
),
),
),
),
);
}
}
DictionaryScreen.dart
import 'package:sizer/sizer.dart';
import 'package:flutter/material.dart';
import 'package:easy_localization/easy_localization.dart';
import 'VocabularyWords/VocabularyWordsButton.dart';
class DictionaryScreen extends StatefulWidget {
static const String id = 'Dictionary_Screen';
const DictionaryScreen({Key? key}) : super(key: key);
#override
_DictionaryScreenState createState() => _DictionaryScreenState();
}
class _DictionaryScreenState extends State<DictionaryScreen> {
TextEditingController editingController = TextEditingController();
// final duplicateItems = List<String>.generate(10000, (i) => "Item $i");
// var items = List<String>();
List<VocabularyWordsButton> words = [
VocabularyWordsButton(
englishWord: 'To pray'.tr(),
trasncribedWord: 'Sella',
arabicWord: 'صْلّى',
sound: 'Sella',
),
VocabularyWordsButton(
englishWord: 'To prefer'.tr(),
trasncribedWord: 'Feddel',
arabicWord: 'فْضّلْ',
sound: 'Feddel',
)
];
#override
void initState() {
super.initState();
}
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(),
body: Container(
child: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: TextField(
onChanged: (value) {
setState(() {});
},
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(
shrinkWrap: true,
itemCount: words.length,
itemBuilder: (context, index) {
if (editingController.text.isEmpty) {
return ListTile(
title: Text('${words[index].englishWord} '),
);
} else if (words[index]
.englishWord
.toLowerCase()
.contains(editingController.text)) {
return ListTile(
title: Text('${words[index].englishWord} '),
);
} else {
return Container();
}
}),
),
],
),
),
);
}
}
I used the RefreshIndicator to pull to refresh the page data but it not working
This is my code!! help me to over come the issue on refresh on data
import 'dart:async';
import 'package:apitest3/services/api_manager.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'models/statusinfo.dart';
import 'package:flutter/services.dart';
class TestPage extends StatefulWidget {
const TestPage({Key? key}) : super(key: key);
#override
_TestPageState createState() => _TestPageState();
}
class _TestPageState extends State<TestPage> {
late Future<Status> _status;
final GlobalKey<RefreshIndicatorState> _refreshIndicatorkey =
new GlobalKey<RefreshIndicatorState>();
#override
void initState() {
_status = API_Manager().getStatus();
super.initState();
WidgetsBinding.instance?.addPostFrameCallback(
(_) => _refreshIndicatorkey.currentState?.show());
}
#override
Widget build(BuildContext context) {
final key = new GlobalKey<ScaffoldState>();
return Scaffold(
body: SafeArea(
child: RefreshIndicator(
key: keyStatus,
onRefresh: () => _status,
child: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [Colors.purple, Colors.blue])),
padding: EdgeInsets.all(4),
child: FutureBuilder<Status>(
future: _status,
builder: (context, snapshot) {
if (snapshot.hasData) {
return ListView.builder(
padding: EdgeInsets.all(4),
itemCount: 1,
itemBuilder: (context, index) {
var result = snapshot.data!.result.syncInfo;
return Flexible(
child: Card(
elevation: 20,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
color: Colors.indigo.shade900,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: [
Container(
child: Text(
"Latest Block Hash ",
style: TextStyle(
fontSize: 15,
color: Colors.white),
)),
],
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: [
RaisedButton.icon(
color: Colors.blueAccent,
onPressed: () {
Clipboard.setData(ClipboardData(
text: result.latestBlockHash));
key.currentState!
.showSnackBar(new SnackBar(
backgroundColor:Colors.amberAccent,
content: new Text(
"Copied to Latest Block Hash!!",
style: TextStyle(
color: Colors.red),
),
));
},
icon: Icon(
Icons.copy,
color: Colors.white,
size: 15,
),
label: Text(
"${result.latestBlockHash}",
style: TextStyle(
fontSize: 7.1,
color: Colors.white),
overflow: TextOverflow.ellipsis,
maxLines: 1,
)),
),
),
),
);
}
}
),
),
Card(
color: Colors.blueAccent,
child: Padding(
padding: const EdgeInsets.all(6.0),
child: Container(
height: 20,
child: Row(
children: [
Text(
" ${result.latestBlockTime
.toString()}",
style: TextStyle(
fontSize: 10,
color: Colors.white),
),
],
),
],
),
),
);
});
} else
return Center(child: CircularProgressIndicator()
//CupertinoActivityIndicator()
);
},
),
),
),
),
);
}
}
I don't know what i made mistake on this code for refresh function
And all so i try to root navigation method but it pop more pages on the same page so once try to close the page it there several pages to close,
so, try to help me on proper way to pull refresh on the page.
You need to update the state after refreshing on onRefresh callback. Currently, you are just assigning it to a Future variable.
This is a simple way to do it.
RefreshIndicator(
onRefresh: () { setState((){
// Update your data here
}); },
child: ...
)
I am currently doing a chat app using flutter. I have 2 users and when one users start to chat with other user ,a document will be added in the "Chats" collection. If "user 1" starts a chat, a document of unique ID will be added in the collection. But the problem is, this document is not listed when I use .get() method...Please check what is the problem...
Here is my code:
import 'dart:async';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
import 'package:nebula_chat_app/backend/pics.dart';
import 'package:nebula_chat_app/main.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:nebula_chat_app/backend/FireBase.dart';
class InChat extends StatefulWidget {
final String secondUserId;
final String SeconduserName;
const InChat({Key key, this.secondUserId,this.SeconduserName}) : super(key: key);
#override
_InChatState createState() => _InChatState(secondUserId,SeconduserName);
}
class _InChatState extends State {
var messages;
String docu;
List ko;
Future> offlinemessage;
final String SecondUserId;
final String SeconduserName;
String typeMessage;
ScrollController _controller2;
TextEditingController controller2;
_InChatState(this.SecondUserId,this.SeconduserName);
#override
void initState() {
controller2 = TextEditingController();
addUser();
_controller2 = ScrollController();
database.collection("Chats").get().then((value) {
var usersinChat = value.docs.map((e) => e.id).toList();
print(usersinChat);
docu = usersinChat.singleWhere((element) => ((element == auth.currentUser.uid.toString() + SecondUserId) || (element == SecondUserId + auth.currentUser.uid.toString())),orElse: ()
=> auth.currentUser.uid.toString() + SecondUserId
);
}).then((value) {
messages = database.collection("Chats").doc(docu).collection("Messages").snapshots();
print("_________________$docu");
});
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
leading: IconButton(icon: Icon(Icons.arrow_back_ios_sharp,color: Colors.white,), onPressed: () => Navigator.pop(context)),
title: Text(SeconduserName,style: TextStyle(
fontWeight: FontWeight.w600,
fontSize: GFS(25, context),
color: Colors.white
),),
actions: [
IconButton(icon: Icon(Icons.search,color: Colors.white,), onPressed: null)
],
),
body: Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
color: Theme.of(context).primaryColorLight,
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(
height: MediaQuery.of(context).size.height*0.75,
width: MediaQuery.of(context).size.width,
child: StreamBuilder(
stream: messages,
builder: (context, snapshot){
if(!snapshot.hasData) return Center(child: CircularProgressIndicator(),);
else
return ListView.builder(
controller: _controller2,
itemCount: snapshot.data.docs.length,
itemBuilder: (context,int index) {
if (!snapshot.hasData) return SizedBox();
else {
if (snapshot.data.docs[index]["from"] == SecondUserId){
print("Second ======> $SecondUserId");
if(_keyboardIsVisible()){
SchedulerBinding.instance.addPostFrameCallback((timeStamp) {_controller2.animateTo(_controller2.position.maxScrollExtent,duration: Duration(milliseconds: 500), curve: Curves.fastOutSlowIn ); });
}
return ReceiveContainer(
text: snapshot.data.docs[index]["message"].toString());
}
else{
return SendContainer(
text: snapshot.data.docs[index]["message"].toString(), status: "seen",);
}
}
}
);
},
)
),
Container(
height: MediaQuery.of(context).size.height*0.1,
width: MediaQuery.of(context).size.width,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Container(
height: MediaQuery.of(context).size.height*0.07,
alignment: Alignment.center,
width: MediaQuery.of(context).size.width*0.75,
decoration: BoxDecoration(
color: Theme.of(context).cardColor,
boxShadow: [BoxShadow(color: Colors.black26,spreadRadius: 1.0,blurRadius: 3.0)],
borderRadius: BorderRadius.circular(40.0)
),
child: Padding(
padding: EdgeInsets.only(left:MediaQuery.of(context).size.width*0.07),
child: TextField(
controller: controller2,
style: TextStyle(
color: Colors.black,
),
decoration: InputDecoration(
focusColor: Colors.black,
hintText: 'Type here',
border: InputBorder.none,
focusedBorder: InputBorder.none,
focusedErrorBorder: InputBorder.none,
disabledBorder: InputBorder.none,
enabledBorder: InputBorder.none,
errorBorder: InputBorder.none,
hintStyle: TextStyle(
color: Colors.black26,
fontSize: GFS(20, context)
)
),
onSubmitted: (text) {
setState(() {
controller2.text = text;
});
},
),
),
),
Container(
height: MediaQuery.of(context).size.height*0.07,
width: MediaQuery.of(context).size.width*0.2,
alignment: Alignment.center,
decoration: BoxDecoration(
color: Theme.of(context).cardColor,
shape: BoxShape.circle,
boxShadow: [BoxShadow(color: Colors.black26,spreadRadius: 1.0,blurRadius: 3.0)],
),
child: InkWell(
onTap: () {
database.collection("Chats").doc(docu).collection("Messages").doc(Timestamp.now().millisecondsSinceEpoch.toString()).set(
{
"from":auth.currentUser.uid.toString(),
"message": controller2.text,
"timestamp" : Timestamp.now().millisecondsSinceEpoch
});
setState(() {
controller2.text = "";
});
SchedulerBinding.instance.addPostFrameCallback((timeStamp) {_controller2.animateTo(_controller2.position.maxScrollExtent,duration: Duration(milliseconds: 500), curve: Curves.fastOutSlowIn ); });
},
child: SizedBox(
width:MediaQuery.of(context).size.width*0.1,
height:MediaQuery.of(context).size.height*0.035,
child: SvgPicture.asset(sendIcon,fit: BoxFit.contain,)),
),
)
],
),
) ///Typing Container
],
),
),
),
);
}
bool _keyboardIsVisible() {
return !(MediaQuery.of(context).viewInsets.bottom == 0.0);
}
void checkCommon() {
}
}
class ReceiveContainer extends StatelessWidget {
final String text;
const ReceiveContainer({Key key, this.text}) : super(key: key);
#override
Widget build(BuildContext context) {
return Container(
width: MediaQuery.of(context).size.width,
alignment: Alignment.centerLeft,
constraints: BoxConstraints(
minHeight: MediaQuery.of(context).size.height*0.1,
),
child: Padding(
padding: EdgeInsets.symmetric(vertical: MediaQuery.of(context).size.height*0.02,horizontal:MediaQuery.of(context).size.width*0.05 ),
child: Container(
constraints: BoxConstraints(
minWidth: MediaQuery.of(context).size.width*0.1,
maxWidth: MediaQuery.of(context).size.width*0.5,
minHeight: MediaQuery.of(context).size.height*0.06,
),
decoration: BoxDecoration(
color:Theme.of(context).cardColor,
borderRadius: BorderRadius.circular(20.0),
boxShadow: [BoxShadow(color: Colors.black26,spreadRadius: 1.0,blurRadius: 2.0)]
),
child: Padding(
padding: EdgeInsets.all(MediaQuery.of(context).size.width*0.4*0.1),
child: Text(text,style: TextStyle(
fontWeight: FontWeight.w600,
fontSize: GFS(19, context),
color:Theme.of(context).textTheme.headline1.color
),),
),
),
),
);
}
}
class SendContainer extends StatelessWidget {
final String text;
final String status;
const SendContainer({Key key, this.text,this.status}) : super(key: key);
#override
Widget build(BuildContext context) {
return Container(
width: MediaQuery.of(context).size.width,
constraints: BoxConstraints(
minHeight: MediaQuery.of(context).size.height*0.1,
),
child: Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Container(
height: MediaQuery.of(context).size.height*0.03,
width: MediaQuery.of(context).size.width*0.1,
child: checkStatus(status)
),
Padding(
padding: EdgeInsets.only(top: MediaQuery.of(context).size.height*0.02,bottom: MediaQuery.of(context).size.height*0.02,left:MediaQuery.of(context).size.width*0.05 ,right:MediaQuery.of(context).size.width*0.02 ),
child: Container(
constraints: BoxConstraints(
minWidth: MediaQuery.of(context).size.width*0.1,
maxWidth: MediaQuery.of(context).size.width*0.5,
minHeight: MediaQuery.of(context).size.height*0.06,
),
decoration: BoxDecoration(
color:Theme.of(context).primaryColorDark,
borderRadius: BorderRadius.circular(20.0),
boxShadow: [BoxShadow(color: Colors.black26,spreadRadius: 1.0,blurRadius: 2.0)]
),
child: Padding(
padding: EdgeInsets.all(MediaQuery.of(context).size.width*0.4*0.1),
child: Text(text,style: TextStyle(
fontWeight: FontWeight.w600,
fontSize: GFS(19, context),
color: Colors.white
),),
),
),
),
],
),
),
);
}
checkStatus(statusss) {
{
if(statusss == 'delivered') return SvgPicture.asset(doubleCheckIcon,fit: BoxFit.contain,color: Colors.black,);
else if (statusss == 'Not delivered') return SvgPicture.asset(checkIcon,fit: BoxFit.contain,color: Colors.black,);
else if (statusss == 'seen') return SvgPicture.asset(doubleCheckIcon,fit: BoxFit.contain,color: Colors.green,);
}
}
}
I am currently developing an app which people can save their receipt in it, I shared home screen below,initial time It will be empty, as soon as user add new menu, it will get full with menu, After user added new menu, the should be able to click the menu container, and access to new screen for example, İn home screen I created container which called "CAKES", the cakes screen should be created, if I created another menu in my home screen It should also created too, I currently menu extanded screen as a statefull widget already, you can see below, but my question is How can I create this page for spesific menu's , How can I store them, in list, in map etc, Lastly, I dont want user information dissapear, I know I have to use database, but I want to use local database, How can I handle with that, Have a nice day...
import 'package:flutter/material.dart';
import 'package:lezzet_kitabi/add_menu_screen.dart';
import 'package:lezzet_kitabi/constants.dart';
import 'package:lezzet_kitabi/widgets.dart';
class HomeScreen extends StatefulWidget {
HomeScreen({this.newMenuName,this.imagePath});
final imagePath;
final newMenuName;
static String id="homeScreen";
#override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
Widget buildBottomSheet(BuildContext context)=>AddMenuScreen(buttonText: "Menü Ekle",route: HomeScreen,);
void initState(){
super.initState();
if (widget.newMenuName!=null && widget.imagePath!=null){
Widget newMenu=MenuCard(newMenuName: widget.newMenuName,imagePath: widget.imagePath);
menuCards.insert(0,newMenu);
}
}
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
backgroundColor: kColorTheme1,
appBar: AppBar(
centerTitle: true,
automaticallyImplyLeading: false,
elevation: 5,
backgroundColor: Color(0xFFF2C3D4).withOpacity(1),
title:TitleBorderedText(title:"SEVIMLI YEMEKLER", textColor: Color(0xFFFFFB00)),
actions: [
CircleAvatar(
radius: 27,
backgroundColor: Colors.transparent,
backgroundImage: AssetImage(kCuttedLogoPath),
),
],
),
body: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage(kBGWithLogoOpacity),
fit: BoxFit.cover,
),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Expanded(
child: GridView.count(
crossAxisCount: 2,
children:menuCards,
),
),
Column(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Padding(
padding: EdgeInsets.all(10),
child: Container(
decoration: BoxDecoration(
boxShadow:[
BoxShadow(
color: Colors.black.withOpacity(1),
spreadRadius: 2,
blurRadius: 7,
offset: Offset(0,4),
),
],
color: kColorTheme7,
borderRadius: BorderRadius.circular(40),
),
child: FlatButton(
onPressed: (){
showModalBottomSheet(
context: context,
builder: (BuildContext context)=> AddMenuScreen(buttonText: "Menü Ekle",route: "homeScreen",),
);
},
child: TitleBorderedText(title: "LEZZET GRUBU EKLE",textColor: Colors.white,)
),
),
),
],
)
],
),
),
),
);
}
}
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:lezzet_kitabi/screens/home_screen.dart';
import 'package:lezzet_kitabi/widgets.dart';
import 'constants.dart';
import 'dart:math';
class AddMenuScreen extends StatefulWidget {
AddMenuScreen({#required this.buttonText, #required this.route});
final route;
final String buttonText;
static String id="addMenuScreen";
#override
_AddMenuScreenState createState() => _AddMenuScreenState();
}
class _AddMenuScreenState extends State<AddMenuScreen> {
int selectedIndex=-1;
Color _containerForStickersInactiveColor=Colors.white;
Color _containerForStickersActiveColor=Colors.black12;
final stickerList= List<String>.generate(23, (index) => "images/sticker$index");
String chosenImagePath;
String menuName;
int addScreenImageNum;
void initState(){
super.initState();
createAddScreenImageNum();
}
void createAddScreenImageNum(){
Random random =Random();
addScreenImageNum = random.nextInt(3)+1;
}
#override
Widget build(BuildContext context) {
return Material(
child: Container(
color: kColorTheme9,
child: Container(
height: 400,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(topRight: Radius.circular(40),topLeft: Radius.circular(40)),
),
child:Padding(
padding:EdgeInsets.all(20.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Container(
decoration: BoxDecoration(
color: kColorTheme2,
borderRadius: BorderRadius.circular(90)
),
child: TextField(
style: TextStyle(
color: Colors.black,
fontFamily:"Graduate",
fontSize: 20,
),
textAlign: TextAlign.center,
onChanged: (value){
menuName=value;
},
decoration: InputDecoration(
border:OutlineInputBorder(
borderRadius: BorderRadius.circular(90),
borderSide: BorderSide(
color: Colors.teal,
),
),
hintText: "Menü ismi belirleyin",
hintStyle: TextStyle(
color: Colors.black.withOpacity(0.2),
fontFamily: "Graduate",
),
),
),
),
SizedBox(height: 20,),
Text(" yana kadırarak menünüz icin bir resim secin",textAlign: TextAlign.center,
style: TextStyle(fontFamily: "Graduate", fontSize: 12),),
SizedBox(height: 20,),
Expanded(
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: stickerList.length,
itemBuilder: (context,index){
return Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(30),
color: index == selectedIndex ?
_containerForStickersActiveColor :
_containerForStickersInactiveColor,
),
child:FlatButton(
child: Image(
image: AssetImage("images/sticker$index.png"),
),
onPressed: (){
setState(() {
selectedIndex = index;
});
},
),
);
}
),
),
SizedBox(height: 20,),
Container(
decoration: BoxDecoration(
border: Border.all(style: BorderStyle.solid),
color: kColorTheme7,
borderRadius: BorderRadius.circular(90),
),
child: FlatButton(
onPressed: (){
widget.route=="homeScreen"?Navigator.push(context, MaterialPageRoute(builder: (context)=>HomeScreen(newMenuName: menuName,imagePath: "images/sticker$selectedIndex.png")))
:Navigator.push(context, MaterialPageRoute(builder: (context)=>MenuExtension(menuExtensionName: menuName)),
);
},
child: Text(widget.buttonText, style: TextStyle(fontSize: 20, color: Colors.white,
fontFamily: "Graduate", fontWeight: FontWeight.bold),),
),
),
],
),
),
),
),
);
}
}
import 'package:flutter/material.dart';
import 'dart:math';
import 'add_menu_screen.dart';
import 'package:bordered_text/bordered_text.dart';
import 'package:lezzet_kitabi/screens/meal_screen.dart';
import 'constants.dart';
List<Widget> menuExtensionCards=[EmptyMenu()];
List<Widget> menuCards=[EmptyMenu()];
class MenuCard extends StatelessWidget {
MenuCard({this.newMenuName, this.imagePath});
final newMenuName;
final imagePath;
#override
Widget build(BuildContext context) {
return Padding(
padding: EdgeInsets.only(top:15.0),
child: FlatButton(
onPressed: (){
Navigator.push(context, MaterialPageRoute(builder: (context)=>MenuExtension(menuExtensionName: newMenuName,)));
},
child: Container(
height: 180,
width: 180,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(30),
color: Color((Random().nextDouble() * 0xFFFFFF).toInt()).withOpacity(0.5),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SizedBox(height: 10,),
Container(
decoration: BoxDecoration(
color: Colors.white.withOpacity(0.5),
borderRadius: BorderRadius.circular(90),
),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
newMenuName,
style: TextStyle(
color: Colors.black,
fontSize: 20,
fontFamily: 'Graduate',
fontWeight: FontWeight.bold),
),
),
),
Expanded(
child: Padding(
padding:EdgeInsets.all(5),
child: Image(
image: AssetImage(
imagePath
),
),
),
),
],
),
),
),
);
}
}
class EmptyMenu extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Padding(
padding: EdgeInsets.only(top:15.0),
child: FlatButton(
onPressed: (){
showModalBottomSheet(
context: context,
builder: (BuildContext context)=> AddMenuScreen(buttonText: "Menü Ekle",route:"homeScreen"),
);
},
child: Container(
height: 180,
width: 180,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(30),
color: Colors.black12.withOpacity(0.1),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Icon(Icons.add_circle_outline_outlined,size: 100,color: Colors.grey.shade400,),
],
),
),
),
);
}
}
class MenuExtension extends StatefulWidget {
MenuExtension({this.menuExtensionName});
final String menuExtensionName;
#override
_MenuExtensionState createState() => _MenuExtensionState();
}
class _MenuExtensionState extends State<MenuExtension> {
Widget buildBottomSheet(BuildContext context)=>AddMenuScreen(buttonText: "Tarif Ekle",route: MealScreen,);
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
appBar: AppBar(
centerTitle: true,
automaticallyImplyLeading: false,
elevation: 5,
backgroundColor: Color(0xFFF2C3D4).withOpacity(1),
title:BorderedText(
child:Text(
widget.menuExtensionName,
style: TextStyle(
color: Color(0XFFFFFB00),
fontSize: 30,
fontFamily: "Graduate"
),
),
strokeWidth: 5,
strokeColor: Colors.black,
),
actions: [
CircleAvatar(
radius: 27,
backgroundColor: Colors.transparent,
backgroundImage: AssetImage("images/cuttedlogo.PNG"),
),
],
),
body: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage("images/logoBGopacity.png"),
fit: BoxFit.cover,
),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Expanded(
child: GridView.count(
crossAxisCount: 2,
children:menuExtensionCards,
),
),
Column(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Padding(
padding: EdgeInsets.all(10),
child: Container(
decoration: BoxDecoration(
boxShadow:[
BoxShadow(
color: Colors.black.withOpacity(1),
spreadRadius: 2,
blurRadius: 7,
offset: Offset(0,4),
),
],
color: kColorTheme7,
borderRadius: BorderRadius.circular(40),
),
child: FlatButton(
onPressed: (){
showModalBottomSheet(
context: context,
builder: (BuildContext context)=> AddMenuScreen(buttonText: "Tarif Ekle", route:"mealScreen"),
);
},
child: BorderedText(
strokeWidth: 5,
strokeColor: Colors.black,
child:Text("Tarif Ekle",style: TextStyle(
color: Colors.white,
fontFamily:'Graduate',
fontSize:30,
),
),
),
),
),
),
],
)
],
),
),
),
);
}
}
class TitleBorderedText extends StatelessWidget {
TitleBorderedText({this.title, this.textColor});
final Color textColor;
final String title;
#override
Widget build(BuildContext context) {
return BorderedText(
strokeWidth: 5,
strokeColor: Colors.black,
child:Text(title,style: TextStyle(
color: textColor,
fontFamily:'Graduate',
fontSize:30,
),
),
);
}
}
I'm new to flutter and I'm following this tutorial but I'm currently getting this error
error: The operator '[]' isn't defined for the type 'Map<String, dynamic> Function()'. (undefined_operator at [chat_app_tutorial] lib\views\search.dart:33)
Please I've been having this bug for over 2days now. I've checked here and I've been researching online but I've not seen anything that has worked so far. This is the line of code I'm getting the error from.
I'm not sure what part of my code is needed to be able to help me so I'll just put everything.
import 'package:chat_app_tutorial/widgets/widget.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
class SearchScreen extends StatefulWidget {
#override
_SearchScreenState createState() => _SearchScreenState();
}
class _SearchScreenState extends State<SearchScreen> {
DatabaseMethods databaseMethods = new DatabaseMethods();
TextEditingController searchTextEditingController = new TextEditingController();
QuerySnapshot searchSnapshot;
initiateSearch(){
databaseMethods.getUserByUsername(searchTextEditingController.text).then((val){
setState(() {
searchSnapshot = val;
});
});
}
Widget searchList(){
return searchSnapshot != null ? ListView.builder(
itemCount: searchSnapshot.docs.length,
shrinkWrap: true,
itemBuilder: (context, index){
return SearchTile(
userName: searchSnapshot.docs[0].data["name"],
userEmail: searchSnapshot.docs[0].data["email"],
);
}
) : Container();
}
#override
void initState() {
initiateSearch();
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: appBarMain(context),
body: SingleChildScrollView(
child: Container(
child: Column(
children: [
Container(
color: Color(0x54ffffff),
padding: EdgeInsets.symmetric(horizontal: 24, vertical: 16),
child: Row(
children: [
Expanded(
child: TextField(
controller: searchTextEditingController,
style: TextStyle(
color: Colors.white
),
decoration: InputDecoration(
hintText: "Search username",
hintStyle: TextStyle(
color: Colors.white54
),
border: InputBorder.none
),
),
),
GestureDetector(
onTap: (){
initiateSearch();
},
child: Container(
height: 40,
width: 40,
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [
const Color(0x36ffffff),
const Color(0x0fffffff)
]
),
borderRadius: BorderRadius.circular(40)
),
padding: EdgeInsets.all(12),
child: Image.asset("assets/images/search_white.png")
),
)
],
),
),
searchList()
],
),
),
),
);
}
}
class SearchTile extends StatelessWidget {
final String userName;
final String userEmail;
SearchTile({this.userName, this.userEmail});
#override
Widget build(BuildContext context) {
return Container(
child: Row(
children: [
Column(
children: [
Text(userName, style: simpleTextStyle(),),
Text(userEmail, style: simpleTextStyle(),)
],
),
Spacer(),
Container(
decoration: BoxDecoration(
color: Colors.blue,
borderRadius: BorderRadius.circular(30)
),
padding: EdgeInsets.symmetric(horizontal: 16, vertical: 8),
child: Text("Message"),
)
],
),
);
}
}```
The error is complaining about:
return SearchTile(
userName: searchSnapshot.docs[0].data["name"],
userEmail: searchSnapshot.docs[0].data["email"],
);
searchSnapshot.docs[0].data is a function that returns a Map. You need to call that function first.
You probably want searchSnapshot.docs[0].data()['name'] and searchSnapshot.docs[0].data()['email'].
Even better would be to avoid calling data() multiple times:
var data = searchSnapshot.docs[0].data();
return SearchTile(userName: data['name'], userEmail: data['email']);