How to add Future builder along with card constructor? - flutter

I want to add the code below to my existing card constructor but I am unable to do so
child: Container(
height: 50,
width: 100,
child: FutureBuilder<Uri>(
future: createDynamicLink(), //return link
builder: (context, snapshot) {
if (snapshot.hasData) {
Uri? uri = snapshot.data;
return FlatButton(
color: Colors.amber,
onPressed: () => FlutterShare.share(title: 'Example share',
text: 'Example share text',
linkUrl: uri.toString(),
chooserTitle: 'Example Chooser Title'),
child: Text('Share'),
);
}
}),
),
And this is the card widget with which I want to add the future function
child: Container(
margin: const EdgeInsets.only(top: 120.0),
child: GridView(
physics: BouncingScrollPhysics(),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
children: events.map((title){
return Scaffold(body:
Container(decoration: BoxDecoration(
image:DecorationImage(
image: AssetImage("assets/bg.png"), fit: BoxFit.cover),),
return GestureDetector(
child: Card(
margin: const EdgeInsets.all(14.0),
),
onDoubleTap: () {
Fluttertoast.showToast(msg: "msg");
},
);
}).toList(),
),
I want to be able to use the future function along with the flutterShare functionality when I click on one of the grid card
The event list used above:
List<String> events = [
"Emergency SMS",
"Call",
"Navigation"
];
Truly appreciate any help!

Related

what is the best way to use MaterialPageRoute in list view

I have this ListView and I want to add a MaterialPageRoute. How can I do it that it opens a diverent page when I click on anoter item from the ListView.
(I dont want to want to send selected item data to next screen)
Example:
I click on ExamplePage it shod Navigate to ExamplePage() when I click on TestPage it shod Navigate to TestPage()
Expanded(
child: ListView.builder(
itemCount: categories.length,
itemBuilder: (BuildContext ctx, int index) {
return GestureDetector(
onTap: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (BuildContext context) {
return ExamplePage();
},
),
);
},
child: Container(
margin: const EdgeInsets.all(20),
height: 150,
child: Stack(
children: [
Positioned.fill(
child: ClipRRect(
borderRadius: BorderRadius.circular(20),
child: Image.asset(
'images/${categories[index].imgName}.png',
fit: BoxFit.cover),
),
),
Positioned(
bottom: 0,
child: Padding(
padding: const EdgeInsets.all(10.0),
Text(
categories[index].name,
style: const TextStyle(fontSize: 25),
)
),
)
],
),
),
);
},
),
)

Adjusting the grid layout

I have been trying to add the code below within the card grid view. The text widget is just for testing purposes. When I tap on the card I want to perform the action that is written for the iconButton onPressed method.
Expanded(
child: StreamBuilder(
stream:
FirebaseFirestore.instance.collection('location').snapshots(),
builder: (context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (!snapshot.hasData) {
return Center(child: CircularProgressIndicator());
}
return ListView.builder(
itemCount: snapshot.data?.docs.length,
itemBuilder: (context, index) {
return ListTile(
title:
Text(snapshot.data!.docs[index]['name'].toString()),
subtitle: Row(
children: [
Text(snapshot.data!.docs[index]['latitude']
.toString()),
SizedBox(
width: 20,
),
Text(snapshot.data!.docs[index]['longitude']
.toString()),
],
),
trailing: IconButton(
icon: Icon(Icons.directions),
onPressed: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) =>
MyMap(snapshot.data!.docs[index].id)));
},
),
);
});
},
)),
Here is the card grid
return Scaffold(body: Container(decoration: BoxDecoration(
image:DecorationImage(
image: AssetImage("assets/background.jpg"), fit: BoxFit.cover),),child: Container(
margin: const EdgeInsets.only(top: 120.0),
child: GridView(
physics: BouncingScrollPhysics(),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
children: events.map((title){
return GestureDetector(
child: Card(
elevation: 0,
color: Colors.transparent,
margin: const EdgeInsets.all(13.0),
child: getCardByTile(title)
),
onTap: () {
Fluttertoast.showToast(msg: title);
},
);
}).toList(),
),
),));
Here is the CardByTile() method used above.
getCardByTile(String title) {
String img = "";
if(title == "Navigation") {
img = "assets/navi.png";
}
if(title == "Current location") {
img = "assets/currentloc.png";
}
if(title == "Enable live location") {
img = "assets/track.png";
}
if(title == "Stop live location") {
img = "assets/stoplive.png";
}
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Center(
child: new Stack(
children: <Widget>[
new Image.asset(
img,
fit: BoxFit.contain,
//width: 80.0,
//height: 80.0,
)
],
),
)
]
);
}
and the event list.
List<String> events = [
"Navigation",
"Current location",
"Enable live location",
"Stop live location"
];

Grid view.builder ontap functionality not working

I tried putting inkwell and also gesture detector widgets but onTap() doesn't seem to work in any scenario.
I am dynamically adding data to gridView using futureBuilder and I am adding on tap functionality using InkWell and also tried GestureDetector but it seems gridView does not accept any taps!
FutureBuilder(
future: getAllFriends(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return Container(
padding: const EdgeInsets.all(8),
height: MediaQuery.of(context).size.height,
decoration: const BoxDecoration(color: Color(0xFFDBE2E7)),
child: GridView.builder(
padding: EdgeInsets.zero,
gridDelegate:
const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 4,
childAspectRatio: 0.8,
),
itemCount: friendsList.length,
itemBuilder: (context, index) {
return InkWell(
onTap: () {
print('object');
},
child: Container(
color: Colors.amber.shade100,
child: friendCircle(
friendsList[index].friendPoint,
friendsList[index].friendPic,
friendsList[index].friendName,
),
),
);
},
),
);
} else {
return const SizedBox(
width: 300,
height: 300,
child: IgnorePointer(
child: Center(
child: CircularProgressIndicator(),
),
));
}
}),

Adding Json Image to ListTile

I have a simple json parser and listing the news and their categories
now I am trying to do some optimisations on ListTile because I would like to use the news Images bigger and put the news title under but ListTile provide only trailing which it is unusable for me. But I can't add any styling in whole code (new child, Row, etc gives error.) Is it possible to do that in this structure or should I make a customListTile on another page and link the current mechanism to new page?
any help would be really nice
body: Container(
padding: const EdgeInsets.all(
10.0,
),
child: FutureBuilder<Articles>(
future: _futureArticles,
builder: (BuildContext context, AsyncSnapshot<Articles> snapshot) {
if (snapshot.hasData) {
final articles = snapshot.data?.data;
return ListView.builder(
padding: const EdgeInsets.all(
10.0,
),
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemCount: articles!.length,
itemBuilder: (BuildContext context, int index) {
return Card(
elevation: 4.0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
child: ListTile(
title: Text(
'Title: ${articles[index].title}',
),
subtitle:
Text('Category: ${articles[index].category?.name}'),
trailing: Image.network(articles[index].imageUrl!),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => NewsViewDetail(
id: articles[index].id!,
),
fullscreenDialog: true,
),
);
},
),
);
},
);
} else if (snapshot.hasError) {
return NewsError(
errorMessage: '${snapshot.hasError}',
);
} else {
return const NewsLoading(
text: 'Loading...',
);
}
},
),
),
);
}
}
Try below answer hope its help to you ,use GridView.builder() instead of ListView.builder()
Container(
padding: EdgeInsets.all(10),
child: GridView.builder(
itemCount: 5,//use your length here(articles!.length)
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 1),
itemBuilder: (context, index) {
return Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.grey.shade200),
),
margin: EdgeInsets.all(5),
padding: EdgeInsets.all(5),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Expanded(
child: Image.network(
'your network image here',
fit: BoxFit.fill,
),
),
SizedBox(
height: 15,
),
Text(
'Your headline here',
style: TextStyle(
fontSize: 15,
fontWeight: FontWeight.bold,
),
),
],
),
);
},
),
);
your screen look like ->

How to Navigate to next page without clearing current page data

I am facing a problem with displaying image in the grid view in Flutter.
1) I am fetching 25 images from Firestore but these images are not loaded from top to bottom. these images are loaded asynchronously. I want to load all the images one by one from top to bottom so, the other images which are not on the screen should be loaded when they are scrolled.
2) When I tap any of the Image it is taken to FullScreen Page. I have used navigator. push to navigate from one page to another. But, when I again tap back button in FullScreen Page, all the Images get loaded from the beginning. I want all the images not to be loaded again.
This is the code Where Images are loaded.
class CategoryGrid extends StatefulWidget {
#override
_CategoryGridState createState() =>
_CategoryGridState();
}
class _CategoryGridState extends State<CategoryGrid> {
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
body: StreamBuilder(
stream: Firestore.instance.collection(label).snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return Container(
child: Center(
child: CircularProgressIndicator(
valueColor: new AlwaysStoppedAnimation<Color>(Colors.black54),
),
),
);
} else {
return SingleChildScrollView(
child: Container(
child: Column(
children: <Widget>[
Container(
height: 50.0,
margin: EdgeInsets.only(top: 45.0),
child: Text(
displayText,
style: GoogleFonts.poppins(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 25.0,
),
),
),
GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
childAspectRatio: 0.6,
crossAxisSpacing: 5.0,
mainAxisSpacing: 5.0,
),
padding: EdgeInsets.all(10.0),
physics: ClampingScrollPhysics(),
shrinkWrap: true,
itemCount: snapshot.data.documents.length,
itemBuilder: (context, index) {
DocumentSnapshot imgUrl =
snapshot.data.documents[index];
if (imgUrl == null) {
return CircularProgressIndicator();
} else {
return GestureDetector(
onTap: () {
Navigator.push(context,
MaterialPageRoute(builder: (context) {
return FullScreenPage(
image: "${imgUrl['image']}");
}));
},
child: Container(
child: ClipRRect(
borderRadius:
BorderRadius.all(Radius.circular(5.0)),
child: FadeInImage(
image: NetworkImage(
"${imgUrl['image']}",
),
fit: BoxFit.fill,
placeholder: AssetImage(
'images/Loadinghorizontal.jpg'),
),
),
),
);
}
},
),
],
),
),
);
}
},
),
);
}
}
This is the code which is pushed to another screen while tapped
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.black54,
body: SafeArea(
child: Stack(
children: <Widget>[
Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
child: Image.network(
image,
fit: BoxFit.cover,
loadingBuilder: (BuildContext context, Widget child,
ImageChunkEvent loadingProgress) {
if (loadingProgress == null) return child;
return Center(
child: CircularProgressIndicator(),
);
},
),
),
Positioned(
top: 12.0,
left: 12.0,
child: GestureDetector(
onTap: () {
Navigator.pop(context);
},
),
),
),
],
),
),
);
Use the cached_network_image package, it is perfect because it allows you to put the images you have downloaded in the cache memory of the phone, so here is how you are going to do it :
- You will update your pubspec.yaml file
By adding this in the dependencies cached_network_image: ^2.2.0+1
You do flutter pub get and voila
- Small Example
CachedNetworkImage(
imageUrl: "http://via.placeholder.com/200x150",
imageBuilder: (context, imageProvider) => Container(
decoration: BoxDecoration(
image: DecorationImage(
image: imageProvider,
fit: BoxFit.cover,
colorFilter:
ColorFilter.mode(Colors.red, BlendMode.colorBurn)),
),
),
placeholder: (context, url) => CircularProgressIndicator(),
errorWidget: (context, url, error) => Icon(Icons.error),
),