How can I use flutter hero with firebase? - flutter

return Padding(
padding: const EdgeInsets.only(top: 0.0),
child: Scaffold(
appBar: AppBar(title: const Text("Announcements")),
backgroundColor: Colors.blueGrey.shade100,
body: StreamBuilder<QuerySnapshot>(
stream: FirebaseFirestore.instance.collection('announcement').snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return const Center(
child: CircularProgressIndicator(),
);
}
return ListView(
children: snapshot.data!.docs.map((DocumentSnapshot document) {
var docData = document.data() as Map;
return Stack(
children: [
Image.network(
docData['announcementURL'],
),
const SizedBox(
height: 20.0,
),
Text(
docData['description'],
style: const TextStyle(
fontSize: 15.0,
),
),
],
);
}).toList(),
);
},
),
),
);
I don't want to do it with the ListTile(). When i clicking on the image requires an explanation line to appear. I made my old project with the Hero() function. But I couldn't do this code. How can I do that?

Related

Passing data from page to page firebase flutter

I am trying to pass firebase snapshot data from first page to second page in flutter using GET. I'm able to pass data from one screen to another in debug mode but not in release mode.
I have used a streambuilder on the page and a Future on second . Please where am i going wrong ?
here is code..
first page:
Container(
child: Expanded(
child: StreamBuilder(
stream: FirebaseFirestore.instance
.collection('Songs')
.snapshots(),
builder: (BuildContext context,
AsyncSnapshot<QuerySnapshot> snapshot) {
if (!snapshot.hasData) {
return Center(
child: CircularProgressIndicator(),
);
}
return Container(
color: Colors.white24,
padding: EdgeInsets.all(10),
child: ListView(
children: snapshot.data!.docs.map((document) {
return Container(
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(25),
side: BorderSide(
color: Colors.purple, width: 2)),
elevation: 4,
child: ListTile(
title: Text(document['title'],
style: TextStyle(fontSize: 16)),
subtitle: Text(
document['artist'],
style: TextStyle(color: Colors.purple),
),
onTap: () {
Get.to(() => DetailsPage(
piss: document,
post: document.id,
));
},
contentPadding: EdgeInsets.all(20),
leading: Image.asset('assets/logo.png'),
trailing: document['isNew'] == true
? Image.asset(
'assets/new.gif',
)
: null),
),
);
}).toList(),
),
);
}),
),
),
_banner == null
? Container()
: Container(
margin: const EdgeInsets.only(bottom: 12),
height: 52,
child: AdWidget(
ad: _banner!,
),
),
],
),
),
);
}
}
second page
FutureBuilder(
future: getData(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(
child: CircularProgressIndicator(),
);
} else {
return Expanded(
child: ListView.builder(
itemCount: widget.piss['tileHeaders'].length,
itemBuilder: (context, index) {
return GestureDetector(
onTap: () {
setState(() {
_index = index;
counter = counter + 1;
print('COUNTER: $counter');
if (counter == 3) {
_showRewardedAd();
_controller.play();
print("Counter is $counter");
counter = 0;
_createRewardedAd();
}
});
index > 0
? playIt(index)
: _controller
.load(widget.piss['videos'][index]);
},
child: Card(
elevation: 5,
child: Column(
children: [
Container(
height: 100,
child: Row(
children: [
Center(
child: Padding(
padding: EdgeInsets.all(10),
child: Expanded(
child: Image.asset(
"assets/logo.png"),
flex: 2,
// flex: 2,),
),
)),
Expanded(
child: Container(
alignment:
Alignment.topLeft,
child: Column(
children: [
Expanded(
flex: 5,
child: ListTile(
title: Text(
widget.piss[
'tileHeaders']
[index],
style: TextStyle(
fontSize:
26)),
),
),
Expanded(
flex: 5,
child: Row(
mainAxisAlignment:
MainAxisAlignment
.end,
children: [
Container(
child: widget
.piss[
'videos']
[
index]
.toString()
.contains(
'PL')
? Center(
child:
Container(child: playlist()),
)
: Center(
child:
Container(
child:
notPlaylist(),
),
),
),
],
))
],
)),
)
],
))
],
)),
);
}),
);
}
})
Please help

I am trying to create a layout where i need to fetch data from two collections parallel from firestore

I am trying to create a layout where i need to fetch data from two collections parallel. I mean one after the other and than again from first collection. I'm trying using listview and listview.builder but its not working as one of the snapshot is repeating.
I'm providing code and screenshot of output 1. Anyone please help me.As you can see 'proposal2' is repeating twise but i want it in this sequence. 'proposal1,proposal2,proposal1,proposal2' and so on
Here is the source code as well.
View output
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
class proposal1 extends StatefulWidget {
const proposal1({super.key});
#override
State<proposal1> createState() => _proposal1State();
}
class _proposal1State extends State<proposal1> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Convenor Portal"),
),
body: SafeArea(
child: StreamBuilder(
stream: FirebaseFirestore.instance
.collection('Convenor')
.doc('classes')
.collection('BS Information Technology')
.doc('groups')
.collection('projects')
.doc('proposals')
.collection('proposal1')
.snapshots(),
builder: (BuildContext context,
AsyncSnapshot<QuerySnapshot> snapshot) {
if (!snapshot.hasData) {
return const Center(
child: CircularProgressIndicator(),
);
}
return Card(
child: Column(children: [
ListView(
shrinkWrap: true,
children: snapshot.data!.docs.map((document) {
return Column(
children: [
Row(
children: [
const Text('Proposal 1'),
const SizedBox(
width: 20,
),
Text(
document["project-title"],
style: const TextStyle(
fontSize: 24,
fontWeight: FontWeight.bold),
),
],
),
method2(),
const SizedBox(
height: 30,
),
],
);
}).toList(),
),
]),
);
}),
));
}
}
method2() {
return SafeArea(
child: StreamBuilder(
stream: FirebaseFirestore.instance
.collection('Convenor')
.doc('classes')
.collection('BS Information Technology')
.doc('groups')
.collection('projects')
.doc('proposals')
.collection('proposal2')
.snapshots(),
builder:
(BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (!snapshot.hasData) {
return const Center(
child: CircularProgressIndicator(),
);
}
return Card(
child: ListView(
shrinkWrap: true,
children: snapshot.data!.docs.map((document) {
return Row(
children: [
const Text('Proposal 2'),
const SizedBox(
width: 20,
),
Text(
document["project-title"],
style: const TextStyle(
fontSize: 24, fontWeight: FontWeight.bold),
),
],
);
// method2(),
}).toList()),
);
}));
}

How to code dynamic FlipCard List with FutureBuilder in Flutter

I am very new at flutter and I tried writing "body: new ListView.builder....." but it does not work, I am getting always red underline. Can you help me to fix this. I am getting the data to the flipcards from json albüm so I think I must use future builder
This is what it looks like, I want multiple cards according to the elements from json:
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
resizeToAvoidBottomInset: false,
appBar: AppBar(
title: const Center(
child: Text(
"Main",
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 22.0),
),
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(25.0),
),
backgroundColor: Colors.green[600],
),
body: Center(
child: FutureBuilder<Album>(
future: futureAlbum,
builder: (context, snapshot) {
if (snapshot.hasData) {
return ListView(
children: [
const SizedBox(height: 10),
Container(
margin: const EdgeInsets.all(15.0),
height: 200,
width: 350,
child: FlipCard(
direction: FlipDirection.HORIZONTAL,
front: Container(
....................
),
back: Container(
.......................
),
),
),
],
);
} else if (snapshot.hasError) {
return ListView(
children: [
SizedBox(height: 10),
Container(
margin: const EdgeInsets.all(15.0),
height: 200,
width: 350,
child: FlipCard(
direction: FlipDirection.HORIZONTAL,
front: Container(
back: Container(
),
),
),
],
);
}
},
),
),
),
);
}

I want to get a download URL from firebase Storage

here is my build code for getting the URL from firebase storage and showing the image. The image name is save on my firestore as array. So i need to get the list of the image name and turn it into list of URL from firestorage.
#override
Widget build(BuildContext context){
return Container(
child: Stack(
children: [
FutureBuilder<QuerySnapshot>(
future: ref.get(),
builder: (context, snapshot) {
if(snapshot.hasError){
return Scaffold(
body: Center(
child: Text("Error: ${snapshot.error}"),
),
);
}
if(snapshot.connectionState == ConnectionState.done){
return Scaffold(
appBar: AppBar(title: Text("Home"),
centerTitle: true,
),
body: GridView(gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 200,
childAspectRatio: 2/3,
crossAxisSpacing: 15,
mainAxisSpacing: 15),
children: snapshot.data!.docs.map((document){
DateTime dt = (document['endDateTime'] as Timestamp).toDate();
List im = DownloadURL(document['imageURL']);// this are the call method
return Card(
clipBehavior: Clip.antiAlias,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15),
),
child:Column(
children: [
Stack(
alignment: Alignment.center,
children: [
Ink.image(
image: NetworkImage(im[0]),
child: InkWell(
onTap: (){
Navigator.of(context).push(MaterialPageRoute(builder: (context)=>DetailScreen(productId: document.id,)));
},
),
height: 170,
fit: BoxFit.cover,
),
],
),
Expanded(
child: Container(
alignment: Alignment.center,
child: Padding(padding: EdgeInsets.all(4).copyWith(bottom: 0),
child: Text("${document['nameP']}",
style: TextStyle(fontSize: 16),
),
),
),
),
// SizedBox(height: 3),
Expanded(
child: Container(
alignment: Alignment.center,
child: Padding(padding: EdgeInsets.all(6).copyWith(bottom: 0),
child: Text("RM ${document['startPrice']}",
style: TextStyle(fontSize: 16),
),
),
),
),
SizedBox(height: 6),
Expanded(child: CountDownText(due: dt,
finishedText: "The Auction has End",
showLabel: true,
daysTextShort: "D ",
hoursTextShort: "H ",
minutesTextShort: "M ",
secondsTextShort: "S ",
style: TextStyle(fontSize: 16,color: Colors.deepPurpleAccent),
),
),
SizedBox(height: 2),
],
),
);
}).toList(),
),
);
}
//loading State
return Scaffold(
body: Center(
child: CircularProgressIndicator(),
),
);
}
),
],
),
);
}
and here is my method for getting the download URL from firebase storage
DownloadURL(List images) async{
List url = [];
for(int i = 0; i<images.length; i++){
url.add(await st.ref('products/${images[i]}').getDownloadURL());
}
return url;
}
it will show error, type 'Future' is not a subtype of type 'List' when run the code.
DownloadURL should return List.
Future<List<String>> DownloadURL(List images) async {
...
}
See Asynchronous programming

How can I insert an initial element into Listview.builder

I want to show the defaultUserContainer() in case the stream is empty but also in case it's not, as an initial element of the list.
Currently. I can't seem to make either scenarios work. How can I design this better?
Column(
children: [
Row(
children: [
Padding(
padding: const EdgeInsets.only(left: 16.0, top: 8.0),
child: Padding(
padding: const EdgeInsets.only(bottom: 8.0),
child: Align(
alignment: Alignment.centerLeft,
child: Text(
"users",
style: TextStyle(fontSize: 20.0, color: Colors.black87),
)
),
),
),
],
),
SizedBox(
height: 120,
child: FutureBuilder(
builder: (context, snapshot) {
return StreamBuilder(
stream: _firestore.collection('ts').where('userid', isEqualTo: widget.user.id).snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
defaultUserContainer(); //If there's no users. tried returning it, or doing like it is here. never shows
return Text("");
} else {
return ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: snapshot.data.documents.length,
itemBuilder: (BuildContext context, int index) {
DocumentSnapshot userDoc = snapshot.data.documents[index];
if(index < snapshot.data.documents.length){
return Padding(
padding: const EdgeInsets.only(bottom: 8.0, left: 8.0, right: 8.0),
child: GestureDetector(
onTap: () => {},
child: Container(
child: FittedBox(
child: Material(
color: Colors.white,
elevation: 4.0,
borderRadius: BorderRadius.circular(8.0),
shadowColor: Colors.grey,
child: Row(
children: <Widget>[
Container(
child: myDetailsContainer(userDoc), //This guy works. it's just a more complicated defaultuserContainer()
),
],
),
)
)
),
),
);
}
return ListTile(leading:defaultuserContainer()); //Doesn't show when there's users users (my goal is to always have this as an initial item)
}
);
}
},
);
},
),
)
]
);
Widget defaultUserContainer() {
return ClipRRect(
borderRadius: BorderRadius.circular(8),
child: Container(
height: 120,
width: 120,
color: myColors.blue,
child: Center(
child: Icon(Icons.add, size: 65, color: Colors.white),
),
),
);
}
You can define it as the first/last element of your ListView/GridView/Column/etc.
Here is a simple example with a GridView:
Full source code
import 'dart:math' show Random;
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
void main() {
runApp(
MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Random Generator',
home: RandomGeneratorPage(),
),
);
}
class RandomGeneratorPage extends HookWidget {
final int max;
final random = Random();
RandomGeneratorPage({Key key, this.max = 20}) : super(key: key);
#override
Widget build(BuildContext context) {
final numbers = useState<List<int>>([]);
return Scaffold(
appBar: AppBar(title: Text('Random Generator')),
body: GridView.count(
crossAxisCount: 5,
childAspectRatio: 1,
children: [
InkWell(
onTap: () =>
numbers.value = [...numbers.value, random.nextInt(max)],
child: Card(
color: Colors.blue.shade100,
child: Icon(Icons.add),
),
),
...numbers.value
.map(
(number) => InkWell(
onTap: () => numbers.value =
numbers.value.where((x) => x != number).toList(),
child: Card(
child: Center(child: Text(number.toString())),
),
),
)
.toList(),
],
),
);
}
}
In your case:
For your particular case, it would probably look like this: [NOT TESTED]
FutureBuilder(
builder: (context, snapshot) {
return StreamBuilder(
stream: _firestore
.collection('ts')
.where('userid', isEqualTo: widget.user.id)
.snapshots(),
builder: (context, snapshot) => ListView(
scrollDirection: Axis.horizontal,
children: [
InkWell(
onTap: () {},
child: Card(
color: Colors.blue.shade100,
child: Icon(Icons.add),
),
),
...snapshot.data.documents.map(
(doc) => Padding(
padding:
const EdgeInsets.only(bottom: 8.0, left: 8.0, right: 8.0),
child: GestureDetector(
onTap: () => {},
child: Container(
child: FittedBox(
child: Material(
color: Colors.white,
elevation: 4.0,
borderRadius: BorderRadius.circular(8.0),
shadowColor: Colors.grey,
child: Row(
children: <Widget>[
Container(
child: myDetailsContainer(
doc), //This guy works. it's just a more complicated defaultuserContainer()
),
],
),
),
),
),
),
),
)
],
),
);
},
)