Flutter Firebase fetch a nested data - flutter

So my app suggest a list of tourist places and the data is fetched from firebase.
So, I have added a search bar where the user can search that tourist place and it will be shown.
Now the problem is that it is not showing the searched place in the listView.
Here is the firebase ScreenShot:
Example -> I want to search and show "India Gate" in the ListView , so how should I do it.
enter image description here
Here is my Code
Padding(
padding: const EdgeInsets.only(top: 25, left: 0, right: 0),
child: StreamBuilder(
stream: FirebaseFirestore.instance
.collection('States')
.snapshots(),
builder: (context, snapshot) {
var docs = snapshot.data.docs[widget.stateIndex];
if (snapshot.hasData) {
/// MediaQuery.removePadding is used to remove the blank space which appears on the top of ListView.
return MediaQuery.removePadding(
context: context,
removeTop: true,
/// Here ClipRRect is wrapped on ListView to make the Scrolling border rounded.
child: ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(45),
topRight: Radius.circular(45)),
child: ListView.builder(
physics: BouncingScrollPhysics(),
itemBuilder: (context, index) {
print(
"Value: ${widget.stateIndex} + ${docs['places'].length}");
print(docs.data());
print("Hello-----------------");
print(docs['places'][index]["location"]);
return Container(
height: deviceSize.height * .225,
child: Card(
elevation: 10,
margin: EdgeInsets.all(10),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(20))),
child: Stack(
children: [
/// Background Place Image.
ClipRRect(
child: Image.network(
docs['places'][index]["img"],
fit: BoxFit.cover,
width: deviceSize.width,
),
borderRadius: BorderRadius.all(Radius.circular(20))),
/// Text Widget.
Positioned(
bottom: 4,
left: 10,
child: Container(
height: 25,
width: 185,
padding: EdgeInsets.only(left: 10),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(10)),
color: SecondPrimaryColor,
),
child: Row(
children: [
Image.asset(
"assets/icon.png",
color: Colors.white,
height: 18,
filterQuality:
FilterQuality.high),
SizedBox(width: 10),
AutoSizeText(
docs['places'][index]["venue"],
style: TextStyle(
color: Colors.white,fontWeight: FontWeight.w600),
maxFontSize: 22,
minFontSize: 14,
),
],
),
)),
// Positioned(
// right: 30,
// bottom: 6,
// child: Container(
// height: 18,
// width: 50,
//
// decoration: BoxDecoration(
// borderRadius: BorderRadius.all(Radius.circular(10)),
// color: PrimaryColor,
// ),
// child: Icon(Icons.arrow_forward,color: SecondPrimaryColor,size: 18),
// ))
],
),
),
);
},
itemCount: docs['places'].length,
),
),
);
} else {
return Text("No Data");
}
}),
),

Use docs.data() to convert to Map<String, dynamic> and display your data instead of docs['places'];
Something like this:
StreamBuilder<QuerySnapshot<Map<String, dynamic>>>( // changes made
stream: FirebaseFirestore.instance.collection('States').snapshots(),
builder: (context, snapshot) {
// changes made
if (snapshot.hasData) {
QueryDocumentSnapshot<Map<String, dynamic>> doc =
snapshot.data.docs[widget.stateIndex];
Map<String, dynamic> data = doc.data(); // changes made
/// MediaQuery.removePadding is used to remove the blank space which appears on the top of ListView.
return MediaQuery.removePadding(
context: context,
removeTop: true,
/// Here ClipRRect is wrapped on ListView to make the Scrolling border rounded.
child: ClipRRect(
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(45),
topRight: Radius.circular(45),
),
child: ListView.builder(
physics: const BouncingScrollPhysics(),
itemBuilder: (context, index) {
print(data);
print(
"Value: ${widget.stateIndex} + ${data['places'].length}");
print('Hello-----------------');
// changes made
print(data['places'][index]['location']);
return Container(
height: deviceSize.height * .225,
child: Card(
elevation: 10,
margin: const EdgeInsets.all(10),
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(20)),
),
child: Stack(
children: [
/// Background Place Image.
ClipRRect(
child: Image.network(
data['places'][index]['img'],
fit: BoxFit.cover,
width: deviceSize.width,
),
borderRadius:
const BorderRadius.all(Radius.circular(20)),
),
/// Text Widget.
Positioned(
bottom: 4,
left: 10,
child: Container(
height: 25,
width: 185,
padding: const EdgeInsets.only(left: 10),
decoration: BoxDecoration(
borderRadius: const BorderRadius.all(
Radius.circular(10),
),
color: SecondPrimaryColor,
),
child: Row(
children: [
Image.asset(
'assets/icon.png',
color: Colors.white,
height: 18,
filterQuality: FilterQuality.high,
),
const SizedBox(width: 10),
AutoSizeText(
data['places'][index]['venue'],
style: const TextStyle(
color: Colors.white,
fontWeight: FontWeight.w600,
),
maxFontSize: 22,
minFontSize: 14,
),
],
),
),
),
],
),
),
);
},
itemCount: data['places'].length,
),
),
);
} else {
return const Text('No Data');
}
},
);

Related

How to create a screen with a condition in flutter dart

I need a little help with flutter. I want to make a screen with a condition. The condition is if we have data show that data from firebase but if we don't have data show a button that says add data. The codes below show data from firebase but when we have no data that shows nothing.
Here are my codes that show a black screen.
#override
Widget build(BuildContext context) {
return GetBuilder<MapLogic>(
builder: (mapLogic) => Scaffold(
// backgroundColor: Colors.red,
body: StreamBuilder<QuerySnapshot>(
stream:
FirebaseFirestore.instance.collection('collection').snapshots(),
builder: (context, snapshot) {
if (snapshot.hasData) {
if (snapshot.data!.docs.isEmpty) {
return Padding(
padding: const EdgeInsets.only(top: 30),
child: InkWell(
onTap: () async {
generalController.focusOut(context);
Get.to(const AddNewVehicle());
},
child: Container(
height: 55,
width: MediaQuery.of(context).size.width,
decoration: BoxDecoration(
color: Styles.primaryColor,
borderRadius: BorderRadius.circular(30),
boxShadow: [
BoxShadow(
color: Styles.primaryColor.withOpacity(0.19),
blurRadius: 40,
spreadRadius: 0,
offset: const Offset(
0, 22), // changes position of shadow
),
],
),
child: const Center(
child: Text(
"Add A Vehicle",
// style: state.buttonTextStyle
),
),
),
),
);
} else {
return FadedSlideAnimation(
child: Wrap(
children:
List.generate(snapshot.data!.docs.length, (index) {
if (snapshot.data!.docs[index].get('driver_id') ==
mapLogic.currentDriverData?.get('id')) {
return Padding(
padding: const EdgeInsets.fromLTRB(15, 30, 15, 0),
child: InkWell(
onTap: () {},
child: Container(
width: MediaQuery.of(context).size.width,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(19),
boxShadow: [
BoxShadow(
color: customThemeColor.withOpacity(0.19),
blurRadius: 40,
spreadRadius: 0,
offset: const Offset(
0, 22), // changes position of shadow
),
],
),
child: Padding(
padding: const EdgeInsets.all(20.0),
child: Row(
children: [
///---image
Hero(
tag:
'${snapshot.data!.docs[index].get('image')}',
child: Material(
child: Container(
height: 80,
width: 80,
decoration: const BoxDecoration(
color: Colors.grey,
shape: BoxShape.circle),
child: ClipRRect(
borderRadius:
BorderRadius.circular(40),
child: Image.network(
'${snapshot.data!.docs[index].get('image')}',
fit: BoxFit.cover,
),
),
),
),
),
///---price
Expanded(
child: Align(
alignment:
Alignment.center,
child: Container(
width: 70,
decoration: BoxDecoration(
borderRadius:
BorderRadius
.circular(
19),
color:
customThemeColor),
child: Padding(
padding:
const EdgeInsets
.fromLTRB(
0, 2, 0, 2),
child: Center(
child: Text(
'\$${snapshot.data!.docs[index].get('dis_price')}',
style: state
.priceTextStyle!
.copyWith(
color: Colors
.white)),
),
),
),
),
),
],
),
],
),
),
))
],
),
),
),
),
);
} else {
return const SizedBox();
}
}),
),
beginOffset: const Offset(0, 0.3),
endOffset: const Offset(0, 0),
slideCurve: Curves.linearToEaseOut,
);
}
} else {
return Text(
'Record not found',
textAlign: TextAlign.center,
style: GoogleFonts.poppins(
fontSize: 20,
color: Colors.black,
fontWeight: FontWeight.w600),
);
}
}),
),
);
}
You can follow this pattern but I will suggest following docs' one
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done &&
!snapshot.hasData) {
return Text("could not find any data");
}
if (snapshot.hasData) {...}
if (snapshot.hasError) return Text("error");
return CircularProgressIndicator();
}

how to remove the gridView extra space it give between widgets - Flutter

i am working on this flutter app where i need to show the children in a grid view, so i used a column widget in side GridView.builder like shown below, i want to remove the sapcing where its marked in the red, and leave it to be responsive somehow...
GridView widget:
GridView.builder(
gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent(
crossAxisSpacing: 10,
mainAxisSpacing: 10,
maxCrossAxisExtent: 450,
),
primary: false,
shrinkWrap: true,
padding: const EdgeInsets.only(
right: 25,
left: 25,
top: 20,
),
itemCount: data.length,
itemBuilder: (ctx, index) {
return VideoWidget(
oneVideoData: data[index],
);
},
),
VideoWidget:
Container(
color: Colors.red,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Container(
width: double.infinity,
decoration: BoxDecoration(
...
),
child: Row(
children: [
...
],
),
),
Stack(
alignment: AlignmentDirectional.center,
children: [
_videoPlayerControllerFFrame.value.isInitialized
? AspectRatio(
aspectRatio:
_videoPlayerControllerFFrame.value.aspectRatio,
child: VideoPlayer(
_videoPlayerControllerFFrame,
),
)
: Container(
height: 250,
),
_isVideoLoading
? const CircularProgressIndicator(
color: Colors.yellow,
)
: IconButton(
onPressed: () {
showDialog(
context: context,
builder: (context) {
return VideoPlayerWidget(
oneVideoData: widget.oneVideoData,
videoController: _videoPlayerController,
);
});
},
icon: Icon(
Icons.play_arrow,
color: Theme.of(context).colorScheme.tertiary,
size: 50,
),
),
],
),
Container(
width: double.infinity,
padding: const EdgeInsets.symmetric(
horizontal: 10,
),
...
),
),
],
),
);
this a screen shot of the output:
i want to get rid of the red space in the bottom.
Thanks in advance
Try below code hope its help to you.
GridView.builder(
shrinkWrap: true,
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
),
itemCount: 6,
itemBuilder: (BuildContext context, int index) {
return Card(
elevation: 5,
shadowColor: Colors.grey,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(
10,
),
),
margin: EdgeInsets.all(5),
child: Container(
height: 200,
width: 200,
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Padding(
padding: EdgeInsets.all(2),
child: Row(
children: [
Container(
decoration: BoxDecoration(
shape: BoxShape.circle,
border: Border.all(
color: Colors.black,
width: 1.0,
),
),
child: CircleAvatar(
radius: 20,
backgroundImage: NetworkImage(
'https://miro.medium.com/max/1400/1*-6WdIcd88w3pfphHOYln3Q.png',
),
),
),
SizedBox(
width: 10,
),
Text('Person ${index.toString()}'),
],
),
),
Expanded(
child: Container(
decoration: BoxDecoration(
image: DecorationImage(
fit: BoxFit.fill,
image: NetworkImage(
'https://miro.medium.com/max/1400/1*-6WdIcd88w3pfphHOYln3Q.png',
),
),
),
),
),
Container(
padding: const EdgeInsets.all(8.0),
decoration: BoxDecoration(
color: Colors.yellow,
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(10.0),
bottomRight: Radius.circular(10.0),
),
),
child: Text(
'Awesome Product From Person ${index.toString()}',
),
),
],
),
),
);
},
),
Result Screen->

Remove container from ListView Builder when clicked to remove

The ListView Builder generates containers. Inside the container, it has another container to remove the first one container.
I already tried with Dismissible, but it didn't work... this question is quite similar, but I couldn't applly for my code:
removing item from ListView.builder Flutter
Hope someone can help :)))
Here is the code:
ListView.builder(
scrollDirection: Axis.horizontal,
shrinkWrap: true,
padding: EdgeInsets.only(bottom: 10),
itemCount:
snapshot.data != null ? snapshot.data.length : 0,
itemBuilder: (BuildContext context, int index) {
OrdersModel orderItem = snapshot.data[index];
return InkWell(
//onTap
child: Container(
padding: EdgeInsets.only(
bottom: 10, top: 10, left: 5, right: 5),
margin: EdgeInsets.only(left: 5, right: 15),
width: 187,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(
Radius.circular(20),
),
color: Colors.white,
boxShadow: [
BoxShadow(
color: Colors.grey,
blurRadius: 0.5,
),
],
),
child: Column(
children: [
Container(
child: Material(
borderRadius: BorderRadius.all(
Radius.circular(10),
),
color: Color(0xffeb5c68),
child: InkWell(
splashColor: Color(0xffda1b2b),
borderRadius: BorderRadius.all(
Radius.circular(10),
),
child: SizedBox(
width: 220,
height: 40,
child: Row(
mainAxisAlignment:
MainAxisAlignment.center,
children: [
Text(
"REMOVE ${orderItem.number}",
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
),
),
],
),
),
onLongPress: () async {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
OrderDetailsPage(),
),
);
},
),
),
),
],
),
),
onTap: () {},
);
},
);
U probably can just call a snapshot.data.removeAt(index) inside your list item, like that:
ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
final item = items[index];
return ListTile(title: Text('$item --- Click to remove me'),onTap:(){
setState(() {
items.removeAt(index);
});
});
},
),
You ca use Dismissible https://flutter.dev/docs/cookbook/gestures/dismissible for your solution

Flutter How to get value from a custom widget

I have a container that color can change using a color list. I want to get the selected color of the container from the main page. When the container clicked, a list of colors appears and we can select the color for the container. I want to do is to get the color value from that container when I press a button
Widget build(BuildContext context) {
return Container(
height: 80,
width: 40,
padding: EdgeInsets.all(5),
child: InkWell(
onTap: () {
showDialog(
context: context,
child: Dialog(
backgroundColor: Colors.white,
// insetPadding: EdgeInsets.all(100),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20)),
child: Column(
children: [
Container(
color: Colors.red,
height: 50,
alignment: Alignment(0, 0),
child: Text(
'Select the Color',
style: TextStyle(
fontWeight: FontWeight.bold, fontSize: 20),
),
),
ListView.builder(
shrinkWrap: true,
itemCount: colors.length,
itemBuilder: (context, index) {
return GestureDetector(
child: Container(
decoration: BoxDecoration(
//border: Border.all(),
),
padding: EdgeInsets.all(5),
child: Row(
children: <Widget>[
SizedBox(
width: 20,
),
Container(
decoration: BoxDecoration(
boxShadow: <BoxShadow>[
BoxShadow(blurRadius: 10)
],
border: Border.all(),
borderRadius:
BorderRadius.circular(100),
color: color[index]),
padding: EdgeInsets.all(5),
//color: color[index],
height: 45,
width: 45,
),
Padding(
padding: EdgeInsets.all(10),
),
Text(
colors[index],
style: TextStyle(
fontFamily:
GoogleFonts.inter().fontFamily,
color: color[index],
fontSize: 20.0,
shadows: [
Shadow(
// bottomLeft
offset: Offset(0, 1.5),
blurRadius: 5,
color: Colors.black),
],
),
),
],
),
),
onTap: () {
Navigator.pop(context);
setState(() {
selectedColor = color[index];
print(index);
});
},
);
})
],
)),
);
},
child: Container(
padding: EdgeInsets.all(10),
width: 20,
height: 60,
decoration: BoxDecoration(
color: selectedColor,
borderRadius: BorderRadius.circular(10),
),
),
),
);
}
You can pass the value to parent when you call Navigator.pop().
https://flutter.dev/docs/cookbook/navigation/returning-data
onTap: () {
Navigator.pop(context, color[index]);
setState(() {
selectedColor = color[index];
print(index);
});
},
In this case, you need to wait for result after call Navigator push method.
final result = await Navigator.push(
...

How to fix cropped shadow in a AnimatedList?

I use AnimatedList but a use shadow in item, my item like code below, I need some help!!!
class TextSentMessage extends StatelessWidget {
final String textMessage;
final Widget buildStatus;
TextSentMessage({this.textMessage, this.buildStatus});
#override
Widget build(BuildContext context) {
print('message 4 : ' + textMessage);
return Row(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
Stack(
overflow: Overflow.visible,
children: <Widget>[
Container(
padding: EdgeInsets.only(
top: 10.0, bottom: 10.0, left: 20.0, right: 15.0),
margin: EdgeInsets.all(5.0),
constraints: BoxConstraints(
maxWidth: 0.7 * MediaQuery.of(context).size.width,
minWidth: 50.0),
decoration: BoxDecoration(
color: Color.fromARGB(255, 0, 117, 255),
boxShadow: [
BoxShadow(
color: black_7, blurRadius: 64, offset: Offset(0, 7))
],
borderRadius: BorderRadius.only(
topLeft: Radius.circular(20),
topRight: Radius.circular(20),
bottomRight: Radius.circular(6),
bottomLeft: Radius.circular(20)),
),
child: Text(textMessage,
textAlign: TextAlign.right,
style: TextStyle(
fontFamily: 'UTM Avo',
fontSize: 15.0,
color: Colors.white))),
],
),
buildStatus
],
);
}
}
This is I use ListView.builder : https://i.imgur.com/4LVXOOw.jpg
This is I use AnimatedList : https://i.imgur.com/bQ3ocL1.jpg
I am not able to replicate your issue #quyen.
This is the test I did on iOS simulator & flutter 1.5.4-hotfix.2 (stable channel):
Animated List:
child: AnimatedList(
initialItemCount: msgs.length,
itemBuilder:
(BuildContext ctx, int index, Animation animation) {
return TextSentMessage(
buildStatus: Icon(
Icons.check_circle,
size: 18,
color: Color.fromARGB(255, 0, 117, 255),
),
textMessage: msgs[index],
);
},
),
ANIMATED demo image:
List View builder:
child: ListView.builder(
itemBuilder: (ctx, index) {
return TextSentMessage(
buildStatus: Icon(
Icons.check_circle,
size: 18,
color: Colors.green,
),
textMessage: 'This is a text message!',
);
},
itemCount: 6,
scrollDirection: Axis.vertical,
),
LIST VIEW demo image: