Hi I am creating a flutter screen as follow.
I want to add name under image. If I add column, image is shrink.
May I know how I can add the artist name under image.
Here is the code that I have created for following screen
Widget buidArtistScreen(BuildContext context, List<Artist> artists) =>
GridView.builder(
itemCount: artists.length,
itemBuilder: (context, index) => buidImageCard(index, artists[index]),
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
mainAxisSpacing: 8,
crossAxisSpacing: 8,
),
);
Widget buidImageCard(int index, Artist artist) => Card(
margin: EdgeInsets.zero,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
child: Container(
margin: const EdgeInsets.all(8),
child: ClipRRect(
borderRadius: BorderRadius.circular(8),
child: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage(artist.profilePicture),
fit: BoxFit.cover,
),
),
child: Align(
alignment: Alignment.bottomRight,
child: Container(
margin: const EdgeInsets.all(4),
padding: const EdgeInsets.all(10),
decoration: BoxDecoration(
color: Theme.of(context).primaryColor,
borderRadius: BorderRadius.circular(100)),
child: const Icon(
Icons.play_arrow,
color: Colors.white,
),
),
),
),
),
),
);
Here is the code with artist name
Widget buidImageCard(int index, Artist artist) => Card(
margin: EdgeInsets.zero,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
child: Container(
margin: const EdgeInsets.all(8),
child: Column(
children: [
ClipRRect(
borderRadius: BorderRadius.circular(8),
child: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage(artist.profilePicture),
fit: BoxFit.cover,
),
),
child: Align(
alignment: Alignment.bottomRight,
child: Container(
margin: const EdgeInsets.all(4),
padding: const EdgeInsets.all(10),
decoration: BoxDecoration(
color: Theme.of(context).primaryColor,
borderRadius: BorderRadius.circular(100)),
child: const Icon(
Icons.play_arrow,
color: Colors.white,
),
),
),
),
),
const SizedBox(height: 20,),
Text(artist.name)
],
),
),
);
}
This is how I achieved. Added Expanded.
Widget buildImageCard(int index, Artist artist) => Card(
clipBehavior: Clip.antiAlias,
margin: EdgeInsets.zero,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
child: GestureDetector(
onTap: () => Navigator.push(
context,
MaterialPageRoute(
builder: (context) => AlbumScreen(artist: artist),
),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Expanded(
child: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage(artist.profilePicture),
fit: BoxFit.cover,
),
),
child: Align(
alignment: Alignment.bottomRight,
child: Container(
margin: const EdgeInsets.all(5),
//padding: const EdgeInsets.all(5),
decoration: BoxDecoration(
color: Theme.of(context).primaryColor,
borderRadius: BorderRadius.circular(100)),
child: const Icon(
Icons.play_arrow,
color: Colors.white,
),
),
),
),
),
Container(
padding: const EdgeInsets.all(8.0),
child: Text(artist.name),
)
]),
),
);
Related
I have a gridview builder like this and in this gridview builder im scrolling posts with page;
GridView.builder(
physics: ScrollPhysics(),
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
),
itemCount: listt.length,
itemBuilder: (context, index) {
return GestureDetector(
onTap: () =>
navigateToDetail(listt[index]),
child: Hero(
tag: (listt[index]["foto"] != null)
? NetworkImage(
listt[index]["foto"])
: AssetImage(
"assets/images/n_image.jpg"),
child: Container(
child: Column(
mainAxisAlignment:
MainAxisAlignment
.spaceBetween,
children: [
Expanded(
flex: 7,
child: Container(
child: Stack(
children: [
Align(
alignment: Alignment
.topCenter,
child: ClipRRect(
borderRadius:
BorderRadius
.only(
topLeft: Radius
.circular(
10),
topRight: Radius
.circular(
10),
),
child: (listt[index]
[
"foto"] !=
null)
? OptimizedCacheImage(
imageUrl:
listt[index]
[
"foto"],
imageBuilder:
(context, imageProvider) =>
Container(
height:
double.infinity,
width: double
.infinity,
decoration:
BoxDecoration(
image: DecorationImage(
image:
imageProvider,
fit: BoxFit
.cover,
)),
),
placeholder:
(context, url) =>
Container(
height:
double.infinity,
width: double
.infinity,
decoration:
BoxDecoration(
color:
Colors.grey[400],
),
),
)
: Image(
height: double
.infinity,
width: double
.infinity,
fit: BoxFit
.cover,
image: AssetImage(
"assets/images/n_image.jpg"),
),
),
),
],
),
decoration: BoxDecoration(
color: Colors.grey[400],
borderRadius:
BorderRadius.only(
topRight:
Radius.circular(
10.0),
topLeft:
Radius.circular(
10.0),
),
),
width: double.infinity,
),
),
Expanded(
flex: 5,
child: Container(
width: double.infinity,
decoration: BoxDecoration(
borderRadius:
BorderRadius.only(
bottomRight:
Radius.circular(
10.0),
bottomLeft:
Radius.circular(
10.0),
),
color: Colors.white),
child: Center(
child: AutoSizeText(
"${listt[index]["name"]}",
textAlign:
TextAlign.center,
style:
GoogleFonts.lora(
textStyle:
TextStyle(
color: Colors
.grey[700],
fontSize: 15,
fontWeight:
FontWeight
.w600,
),
),
maxLines: 2,
),
),
),
),
],
),
margin: EdgeInsets.all(5.0),
decoration: BoxDecoration(
color: Colors.white,
borderRadius:
BorderRadius.circular(10.0),
),
),
),
);
},
),
In this gridview builder I can scroll the page the way I want like this;
When I add controller: scrollController, in my Gridview builder to listen controller, scrolling change to this;
I have to add controller: scrollController, to my Gridview to listen controller for paginaiton so I cant remove controller, so how can I scroll page like first example with adding controller : scrollController,
Try changing the physics to
physics: const NeverScrollableScrollPhysics() in your GridView.builder().
I add controller to my NestedGridView in the body instead of GridView Builder and I solved my problem.
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->
I am trying to make the following design:
I am using Firebase as my backend as a service, and I am having trouble having my code work. There are no errors, but the UI visual looks funky.. I'm trying to create a GridView.builder() and display a grid of my UI (Designs provided below), but the image isn't working as it should be.. You'll see that the light blue is the background color, and the image should be covering the entire cell, even behind the container with the text widget. Check out the code:
return GridView.builder(
shrinkWrap: true,
itemCount: locations.length,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 4,
mainAxisSpacing: 37,
crossAxisSpacing: 37,
),
itemBuilder: (context, index) {
Location location = locations[index];
return MouseRegion(
cursor: SystemMouseCursors.click,
child: GestureDetector(
child: Container(
decoration: BoxDecoration(
color: blue100,
borderRadius: BorderRadius.circular(
20,
),
),
child: Stack(
children: [
ClipRRect(
child: Image.network(
location.image,
fit: BoxFit.cover,
),
borderRadius: BorderRadius.circular(20),
),
Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Container(
decoration: BoxDecoration(
color: isLight
? Color(0xFFF2F2F2)
: Colors.black,
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(
20,
),
bottomRight: Radius.circular(
20,
),
),
),
height: isSmall ? 44 : 67,
child: Center(
child: CustomText(
text: locations[index].street,
size: isSmall ? 12 : 15,
),
),
),
],
),
),
],
),
),
),
);
},
);
Here is what this code causes:
You can obviously see that the code is there, and the general thing is working, although the image doesn't want to cooperate and resizes itself differently.
Why is this? Is it something with the GridView..?
I have try this without Stack also, refer below code hope its help to you. add some changes in my code with your code like image and text add below design code inside GridView.builder()
Card(
elevation: 5,
shadowColor: Colors.grey,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(
20,
),
),
margin: EdgeInsets.all(5),
child: Container(
height: 200,
width: 200,
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Expanded(
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(
10,
),
topRight: Radius.circular(
10,
),
),
image: DecorationImage(
fit: BoxFit.fill,
image: NetworkImage(
'https://miro.medium.com/max/1400/1*-6WdIcd88w3pfphHOYln3Q.png',
),
),
),
),
),
Container(
alignment: Alignment.center,
padding: const EdgeInsets.all(8.0),
decoration: BoxDecoration(
color: Colors.grey.shade300,
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(20.0),
bottomRight: Radius.circular(20.0),
),
),
child: Text(
'300 E Mejor Dr.',
),
),
],
),
),
),
Result Screen->
we can use stack like this inside gridviewbuilder()
GridView.builder(
padding: const EdgeInsets.all(10),
itemCount: itemProvider.sitem.length,
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
childAspectRatio: 3 / 2,
crossAxisSpacing: 10,
mainAxisSpacing: 10),
itemBuilder: (context, index) => Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10)),
child: GestureDetector(
onTap: () {},
child: Stack(
children: [
Container(
child: Center(
child: Image.network(
itemProvider.sitem[index].imageURL.toString(),
fit: BoxFit.fill,
),
)),
Positioned(
top: 10,
left: 20,
child: Text('${itemProvider.sitem[index].name}'))
],
),
),
i post two images, first is looking good but when i am scrolling my data then my ui is getting messed up(second image)
I want it to go under the curve parts when I scroll.
HOW TO DO IT
This is my code
return Scaffold(
backgroundColor: appGreenColor,
appBar: new AppBar(
centerTitle: false,
backgroundColor: appGreenColor,
elevation: 0,
title: Padding(
padding: const EdgeInsets.only(left: 16.0),
child: Image.asset(
"lib/Assets/bellazIcon.png",
fit: BoxFit.fill,
height: 40,
width: 78,
),
),
actions: [
Padding(
padding: const EdgeInsets.only(right: 8.0),
child: IconButton(
icon: Image.asset(
"lib/Assets/notification1.png",
height: 22,
width: 22,
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => NotificationList()));
}),
)
],
),
body: Container(
height: MediaQuery.of(context).size.height - 70,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(30), topRight: Radius.circular(30))),
child: SingleChildScrollView(
child: Column(
children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 3),
child: Column(
children: [
locationView(),
imageSlider(),
genderView(),
categories(),
isMan == true
? maleTopBranches.length == 0
? Container()
: topRatedSalons(maleTopBranches)
: topRatedSalons(femaleTopBranches),
],
),
),
offerImage(),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 2.0),
child: Column(
children: [
services(),
nearByAppointment(),
],
),
),
infoImage()
],
),
),
),
);
this image looks fine till i am not scrolling
but when i scrolling image my data comes onto that curve
This answer work for me
adding : clipBehavior: Clip.hardEdge
Container(
clipBehavior: Clip.hardEdge,
height: MediaQuery.of(context).size.height - 70,
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(topLeft: Radius.circular(30),
topRight: Radius.circular(30))),
child: ...,
),)
try to add : clipBehavior: Clip.hardEdge
Container(
clipBehavior: Clip.hardEdge,
height: MediaQuery.of(context).size.height - 70,
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(topLeft: Radius.circular(30),
topRight: Radius.circular(30))),
child: ...,
),)
So im trying to build a page with lots of images in it, right now im using Stack widget to show the images,
this is my code:
import 'image_description.dart';
class Gallery extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomPadding: false,
appBar: AppBar(
automaticallyImplyLeading: false,
backgroundColor: Colors.white10,
elevation: 0,
leading: Container(
padding: EdgeInsets.fromLTRB(20, 20, 0, 0),
child: InkWell(
child: Hero(
tag: 'back',
child: Image.asset(
'assets/images/wp_back_button_icon.png',
height: 250,
),
),
onTap: () {
Navigator.pop(context);
},
),
),
actions: <Widget>[
Container(
padding: EdgeInsets.fromLTRB(0, 20, 20, 0),
child: Hero(
tag: 'logo',
child: Image.asset(
'assets/images/wp_logo.png',
height: 250,
),
),
),
],
),
body: SafeArea(
child: Column(
children: <Widget>[
Container(
child: Text(
'AR Gallery',
style: TextStyle(fontSize: 30),
),
),
Container(
child: Text("Let's educate in the fun way"),
),
Expanded(
child: SizedBox(
height: double.infinity,
child: GridView.count(
primary: false,
padding: const EdgeInsets.all(20),
crossAxisSpacing: 10,
mainAxisSpacing: 10,
crossAxisCount: 3,
children: <Widget>[
InkWell(
child: Stack(
children: <Widget>[
Container(
height: 120,
width: 200,
child: ClipRRect(
borderRadius: BorderRadius.circular(10),
child: Hero(
tag: 'Image1',
child: Image.asset(
"assets/images/gallery/Image1.jpg",
fit: BoxFit.fitHeight),
),
),
),
Container(
padding: const EdgeInsets.all(5),
child: ClipRRect(
borderRadius: BorderRadius.circular(10),
child: Text('Title',
style: TextStyle(
backgroundColor: Colors.deepOrange,
color: Colors.white)),
),
)
],
),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ImageDescription()));
},
),
Stack(
children: <Widget>[
Container(
height: double.infinity,
width: double.infinity,
child: ClipRRect(
borderRadius: BorderRadius.circular(10),
child: Hero(
tag: 'Image2',
child: Image.asset(
"assets/images/gallery/Image2.jpg",
fit: BoxFit.fitHeight),
),
),
),
Container(
padding: const EdgeInsets.all(5),
child: ClipRRect(
borderRadius: BorderRadius.circular(10),
child: Text('Title',
style: TextStyle(
backgroundColor: Colors.deepOrange,
color: Colors.white)),
),
)
],
),
Stack(
children: <Widget>[
Container(
height: double.infinity,
width: double.infinity,
child: ClipRRect(
borderRadius: BorderRadius.circular(10),
child: Hero(
tag: 'Image3',
child: Image.asset(
"assets/images/gallery/Image3.jpg",
fit: BoxFit.fitHeight),
),
),
),
Container(
padding: const EdgeInsets.all(5),
child: ClipRRect(
borderRadius: BorderRadius.circular(10),
child: Text('Title',
style: TextStyle(
backgroundColor: Colors.deepOrange,
color: Colors.white)),
),
)
],
),
Stack(
children: <Widget>[
Container(
height: double.infinity,
width: double.infinity,
child: ClipRRect(
borderRadius: BorderRadius.circular(10),
child: Hero(
tag: 'Image4',
child: Image.asset(
"assets/images/gallery/Image4.jpg",
fit: BoxFit.fitHeight),
),
),
),
Container(
padding: const EdgeInsets.all(5),
child: ClipRRect(
borderRadius: BorderRadius.circular(10),
child: Text('Title',
style: TextStyle(
backgroundColor: Colors.deepOrange,
color: Colors.white)),
),
)
],
),
Stack(
children: <Widget>[
Container(
height: double.infinity,
width: double.infinity,
child: ClipRRect(
borderRadius: BorderRadius.circular(10),
child: Hero(
tag: 'Image5',
child: Image.asset(
"assets/images/gallery/Image5.png",
fit: BoxFit.fitHeight),
),
),
),
Container(
padding: const EdgeInsets.all(5),
child: ClipRRect(
child: Text('Title',
style: TextStyle(
backgroundColor: Colors.deepOrange,
color: Colors.white)),
),
)
],
),
Stack(
children: <Widget>[
Container(
height: double.infinity,
width: double.infinity,
child: ClipRRect(
borderRadius: BorderRadius.circular(10),
child: Hero(
tag: 'Image6',
child: Image.asset(
"assets/images/gallery/Image6.jpg",
fit: BoxFit.fitHeight),
),
),
),
Container(
padding: const EdgeInsets.all(5),
child: ClipRRect(
borderRadius: BorderRadius.circular(10),
child: Text('Title',
style: TextStyle(
backgroundColor: Colors.deepOrange,
color: Colors.white)),
),
)
],
),
Stack(
children: <Widget>[
Container(
height: double.infinity,
width: double.infinity,
child: ClipRRect(
borderRadius: BorderRadius.circular(10),
child: Hero(
tag: 'Image7',
child: Image.asset(
"assets/images/gallery/Image7.jpg",
fit: BoxFit.fitHeight),
),
),
),
Container(
padding: const EdgeInsets.all(5),
child: ClipRRect(
borderRadius: BorderRadius.circular(10),
child: Text('Title',
style: TextStyle(
backgroundColor: Colors.deepOrange,
color: Colors.white)),
),
)
],
),
Stack(
children: <Widget>[
Container(
height: double.infinity,
width: double.infinity,
child: ClipRRect(
borderRadius: BorderRadius.circular(10),
child: Hero(
tag: 'Image8',
child: Image.asset(
"assets/images/gallery/Image8.jpg",
fit: BoxFit.fitHeight),
),
),
),
Container(
padding: const EdgeInsets.all(5),
child: ClipRRect(
borderRadius: BorderRadius.circular(10),
child: Text('Title',
style: TextStyle(
backgroundColor: Colors.deepOrange,
color: Colors.white)),
),
)
],
),
],
),
),
),
],
),
),
);
}
}
As you can see, i'm using a lot of repeated Stack widget manually.
Can I make that automated? like creating a Stack widget or something similar once, and then call it where it should be with different Title.
Regards, Slim
It is indeed possible, this is what we call a reusable widget.
You can create it in the same file or in a separate one. I would suggest creating a widgets folder containing a dart file (whatever you want to name it) that'll contain your reusable widget.
1- If you only want the title to be different each time it should be something like this:
class SpecialStack extends StatelessWidget{
final String title;
SpecialStack({this.title});
#override
Widget build(BuildContext context){
return Stack(
children: <Widget>[
Container(
height: double.infinity,
width: double.infinity,
child: ClipRRect(
borderRadius: BorderRadius.circular(10),
child: Hero(
tag: 'Image2',
child: Image.asset(
"assets/images/gallery/Image2.jpg",
fit: BoxFit.fitHeight),
),
),
),
Container(
padding: const EdgeInsets.all(5),
child: ClipRRect(
borderRadius: BorderRadius.circular(10),
child: Text(title,
style: TextStyle(
backgroundColor: Colors.deepOrange,
color: Colors.white)),
),
)
],
),
}
}
2- If you want the image to be different whenever you use your reusable widget, it should be something like this. (I provided this case because I saw you were using different image for each Stack):
class SpecialStack extends StatelessWidget{
final String title, image;
SpecialStack({this.title, this.image});
#override
Widget build(BuildContext context){
return Stack(
children: <Widget>[
Container(
height: double.infinity,
width: double.infinity,
child: ClipRRect(
borderRadius: BorderRadius.circular(10),
child: Hero(
tag: image,
child: Image.asset(
"assets/images/gallery/$image.jpg",
fit: BoxFit.fitHeight),
),
),
),
Container(
padding: const EdgeInsets.all(5),
child: ClipRRect(
borderRadius: BorderRadius.circular(10),
child: Text(title,
style: TextStyle(
backgroundColor: Colors.deepOrange,
color: Colors.white)),
),
)
],
),
}
}
For the first case (only title is different),
You can just replace wherever you're using the Stack by this:
SpecialStack(title: "Your desired title")
For the second case (image and title are different):
SpecialStack(title: "Your desired title", image: "your_image_name")
I hope this helps. I tried to be as clear as possible.
keep your images in a list then map the list. and inside map define a Stack widget. it will automatically create the stacks of your list of images.
You should write one function return widget type. Every time you want to show image you can call it.
Ex
Widget showImage(String url, String text){
return Stack(
children: <Widget>[
Container(
height: double.infinity,
width: double.infinity,
child: ClipRRect(
borderRadius: BorderRadius.circular(10),
child: Hero(
tag: 'Image8',
child: Image.asset(
"url,
fit: BoxFit.fitHeight),
),
),
),
Container(
padding: const EdgeInsets.all(5),
child: ClipRRect(
borderRadius: BorderRadius.circular(10),
child: Text(text,
style: TextStyle(
backgroundColor: Colors.deepOrange,
color: Colors.white)),
),
)
],
),
}