Flutter - Managing CarouselSlider to match the width of it's parent and making right and left edges transparent - flutter

I am using CarouselSlider in Flutter to get the output as below (Special Event section):
But getting result as below :
The Issue is It should be with same width as top and bottom widget vertically (you can see in first image), In result Image, there is little more width between right and left transparent area and middle portion. So, middle portion width and the transparency of left and right edge is concern here.
How can I get the same result?
I have done so far as below:
Container(
child: CarouselSlider(
options: CarouselOptions(
enlargeCenterPage: true,
disableCenter: false,
scrollDirection: Axis.horizontal,
onPageChanged: (index, reason) {
setState(() {
activeSpecialEventPage = index;
});
}),
items: <Widget>[
for (var i = 0; i < special_events.length; i++)
GestureDetector(
onTap: () async {
await getCurrentLocation();
if (getDouble(prefCurrLat) != null &&
getDouble(prefCurrLong) != null) {
NavigationUtils.push(context, routeDetailScreen,
arguments: {
argDetailScreenTitle:
Localization.of(context).labelExhibitions,
argCurrentLat: getDouble(prefCurrLat),
argCurrentLong: getDouble(prefCurrLong),
argEventObj: special_events[i]
});
}
},
child: Container(
width: MediaQuery.of(context).size.width,
child: Stack(
children: [
ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(10.w),
topRight: Radius.circular(10.h),
bottomRight: Radius.circular(10.w),
bottomLeft: Radius.circular(10.h)),
child: Image.network(
special_events[i].image.toString(),
errorBuilder: (context, url, error) => Center(
child: SizedBox(
width: 160.w,
height: 160.h,
child: Image.asset(imgPlaceHolder))),
loadingBuilder: (BuildContext context,
Widget child,
ImageChunkEvent? loadingProgress) {
if (loadingProgress == null) {
return child;
}
return Center(
child: Image.asset(imgPlaceHolder,
width: 160.w,
height: 160.h,
fit: BoxFit.cover),
);
},
width: 327.w,
height: 200.h,
fit: BoxFit.cover)),
Positioned(
bottom: 16.h,
left: 20.w,
child: Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
color: blackColorOP11,
width: 300.w,
child: Text(
special_events[i].name.toString(),
style: TextStyle(
fontWeight: FontWeight.w600,
fontFamily: "Poppins",
fontSize: 24.sp,
color: Colors.white),
softWrap: false,
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
),
special_events[i].dateText != null &&
special_events[i]
.dateText
.toString()
.length >
0
? Container(
color: blackColorOP11,
child: Text(
getFormatedDateForSpecialEvent(
special_events[i]
.dateText
.toString()),
style: TextStyle(
fontWeight: FontWeight.w400,
fontFamily: "Poppins",
fontSize: 12.sp,
color: Colors.white),
softWrap: false,
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
)
: Container(),
],
),
),
)
],
),
),
)
],
),
)
: buildNoDataWidget(Localization.of(context).labelNoSpecialEvents);

There are a number of variables you can play with here. I've assumed you've used the carousel_slider package.
In the CarouselOptions you can change the aspectRatio and viewportRatio and resolve your issue right away. For example a viewportFraction: 0.7 would work for your code sample.
However if you want your viewPort to remain the same, you would have to change the width and height of your Image.network AND the aspectRatio to something like:
- CarouselOptions
aspectRatio: 20 / 9
Image.network
width: 360,
height: 200
If there's a specific height or width you must strictly abide to you should play with these 3 values to ensure it work.
I've tested the below code, with some alterations, with dummy data and values and they work well together.
class SpecialEvents {
final String image;
final DateTime dateText;
final String name;
SpecialEvents(
{required this.image, required this.name, required this.dateText});
}
List<SpecialEvents> special_events = [
SpecialEvents(
name: "Road",
image:
"https://images.unsplash.com/photo-1666069810128-e7dfe3b0d653?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=692&q=80",
dateText: DateTime.now()),
SpecialEvents(
name: "NY",
image:
"https://images.unsplash.com/photo-1665806558925-930b7210d8bb?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=687&q=80",
dateText: DateTime.now())
];
CarouselSlider(
options: CarouselOptions(
enlargeCenterPage: true,
aspectRatio: 20 / 9,
// viewportFraction: 0.7,
// padEnds: false,
disableCenter: false,
scrollDirection: Axis.horizontal,
onPageChanged: (index, reason) {
setState(() {
activeSpecialEventPage = index;
});
}),
items: special_events
.map((SpecialEvents se) => GestureDetector(
onTap: () async {
debugPrint("tap function");
},
child: ClipRRect(
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(10),
topRight: Radius.circular(10),
bottomRight: Radius.circular(10),
bottomLeft: Radius.circular(10)),
child: Stack(
children: [
Image.network(se.image.toString(),
errorBuilder: (context, url, error) =>
Center(
child: SizedBox(
width: 160,
height: 160,
child: Image.asset(
"imgPlaceHolder"))),
loadingBuilder: (BuildContext context,
Widget child,
ImageChunkEvent?
loadingProgress) {
if (loadingProgress == null) {
return child;
}
return Center(
child: Image.asset(
"image place holder URL",
width: 160,
height: 160,
fit: BoxFit.cover),
);
},
width: 360,
height: 200,
fit: BoxFit.cover),
Column(
crossAxisAlignment:
CrossAxisAlignment.start,
mainAxisAlignment:
MainAxisAlignment.end,
children: [
Row(
children: [
Expanded(
child: Container(
color: Colors.black26,
width: 300,
child: Padding(
padding: const EdgeInsets
.symmetric(
vertical: 8.0,
horizontal: 20),
child: Column(
crossAxisAlignment:
CrossAxisAlignment
.start,
children: [
Text(
se.name.toString(),
style:
const TextStyle(
fontWeight:
FontWeight
.w600,
fontSize: 24,
color: Colors
.white),
softWrap: false,
maxLines: 1,
overflow: TextOverflow
.ellipsis,
),
Text(
se.dateText
.toString(),
style:
const TextStyle(
fontWeight:
FontWeight
.w400,
fontSize: 12,
color: Colors
.white),
softWrap: false,
maxLines: 1,
overflow: TextOverflow
.ellipsis,
)
],
),
),
),
),
],
),
],
)
],
)),
))
.toList())
Hope that helps explain it.

There is a property on CarouselSlider, onPageChanged.
you need to maintain a int, e.g. currentPageIndex as below,
...
onPageChanged: (index, _) {
setState(
() {
currentPageIndex = index;
}
);
}
...
And then inside itemBuilder do like this,
...
itemBuilder: (context, index, _) {
return Opacity(
opacity: index == currentPageIndex ? 1.0 : 0.2,
child: Your_Widget(),
);
}
...

Related

images not taking full width in carousel

i created a carousel containing three different images. the problem is these images are not taking the full length of my current screen. i have tried setting the width in the image and even setting the aspect ratio and viewport in carousel options but the outcome is still the same. help would be very much appreciated. here is the code.
final List<Widget> _images = [
Stack(
children: [
Image.asset('assets/images/image 10.png'),
Padding(
padding: const EdgeInsets.only(left: 55.0, top: 230),
child: Text(
'Luxury \n Fashion \n &Accessories'.toUpperCase(),
style: TextStyle(
fontFamily: 'Bodoni',
fontSize: 40,
fontWeight: FontWeight.w500,
color: Colors.grey.shade700
),
),
),
Padding(
padding: const EdgeInsets.only(top: 400.0),
child: Center(
child:SvgPicture.asset('assets/iconImages/Button.svg'),
),
),
],
),
Image.asset('assets/images/leeloo.jpeg', width: double.infinity,),
Image.asset('assets/images/ayaka.jpeg', width: double.infinity,),
];
#override
Widget build(BuildContext context) {
return DefaultTabController(
length: 5,
child: Column(
children: [
Stack(
children: [
CarouselSlider.builder(
options: CarouselOptions(
viewportFraction: 1,
aspectRatio: 16/9,
height: MediaQuery.of(context).size.height*0.78,
autoPlay: false,
initialPage: 0,
enableInfiniteScroll: false,
enlargeCenterPage: true,
onPageChanged: (index, reason){
setState(() {
_activeIndex = index;
});
}
),
itemCount: _images.length,
itemBuilder: (BuildContext context, int index, int realIndex) {
return GestureDetector(
onTap: (){
Navigator.of(context).pushNamedAndRemoveUntil(BlackScreen.routeName, (route) => false);
},
child: Align(
alignment: Alignment.bottomCenter,
child:Container(
child: _images[index]
),
),
);
},
),
Set fit to your image like this:
Image.asset('assets/images/leeloo.jpeg', width: double.infinity,fit: BoxFit.cover),
Please try this
FittedBox(
child: Image.asset('foo.png'),
fit: BoxFit.fill,
)

How to stack the items inside a "Listview.builder" on top of each other? flutter

I want to stack the items inside a Listview.builder but when I try to do so with the Align() class and set its heightfactor: , it gives padding to the top and bottom and I don't want that, does anyone have any idea how do I stack them properly?
My center SyncfusionLinearGauge:
//Center SyncfusionLinearGauge
Expanded(
child: ScrollablePositionedList.builder(
itemScrollController: itemController,
itemCount: _provider.loadedContestants.length,
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemBuilder: (context, index) {
final data = _provider.loadedContestants[index];
return Align(
heightFactor: 0.0001,
child: SfLinearGauge(
// showLabels: false,
// showTicks: false,
// showAxisTrack: false,
axisLabelStyle: TextStyle(color: Colors.white),
majorTickStyle: LinearTickStyle(
color: Colors.white, length: 10),
minorTickStyle:
LinearTickStyle(color: Colors.white),
axisTrackStyle:
LinearAxisTrackStyle(color: Colors.red),
orientation: LinearGaugeOrientation.vertical,
minimum: 0,
maximum: 100,
animationDuration: 500,
markerPointers: [
//User pointer
LinearWidgetPointer(
value: data.points,
position: LinearElementPosition.cross,
offset: 50.0,
animationDuration: 2000,
child: UserCardWidget(
data: data,
),
),
],
),
);
},
),
),
My user card:
class UserCardWidget extends StatelessWidget {
UserCardWidget({Key key, this.data}) : super(key: key);
DemoUserModel data;
#override
Widget build(BuildContext context) {
bool _isKevinTeam = data.team == 'Kevin';
return SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.only(left: 167.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
// mainAxisSize: MainAxisSize.min,
children: [
Container(
width: 15,
height: 15,
decoration: BoxDecoration(
color: const Color(0xff2da162),
borderRadius: BorderRadius.all(
Radius.circular(50),
),
),
),
Card(
child: Padding(
padding: const EdgeInsets.all(5.0),
child: Text(
'${data.firstName.toString()}M',
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.w700,
fontFamily: "SFProText",
fontStyle: FontStyle.normal,
fontSize: 13.0,
),
),
),
),
],
),
),
);
}
}
What I want:
What I have:
What I ended up doing was removing the listview.builder all together and mapped the list in the markerPointers:[], so this is the result.
My LinearGauge:
Expanded(
flex: 4,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(
child: SizedBox(
height: size.height * 0.57,
child: SfLinearGauge(
showLabels: false,
showTicks: false,
showAxisTrack: false,
orientation: LinearGaugeOrientation.vertical,
minimum: 0,
maximum: 100,
animationDuration: 500,
markerPointers: _sortedList
.asMap()
.map(
(i, data) {
return MapEntry(
i++,
LinearWidgetPointer(
value: data.points,
position: LinearElementPosition.cross,
animationDuration: 2000,
offset: 500,
child: UserCardWidget(
data: data,
index: i,
isExpandedMethod: _isExpanded,
),
),
);
},
)
.values
.toList(),
),
),
),
],
),
),
This is the result:

State of each widget in ListView.builder is affecting each other. How to differentiate widgets in ListView.builder?

I am building an app that has gmail type animation in which when the circular avatar button is clicked the List tile gets selected with a rotation animation.
The list of items are built using ListView.builder. But when the circle avatar of a list item is clicked it affects the whole list of items and rotates every circle avatar. From similar questions asked I changed Listtile into a separate stateful widget as every item could hold its own state. But this doesn't change the output.
I didn't get the output even after using keys(Unique and object). I am stuck here for a long time but couldn't figure what and how to do it. Is there any way to differentiate widgets in Listview.builder and maintain their states seperately?
Alternatively when I use checkbox/selectable icon its holding the state for each item induvidually.
class MailList extends StatefulWidget {
int index;
List<MailModel> account;
Animation rotationAnim;
AnimationController circleAvatarController;
OneShotAnimation riveAnimationController1;
OneShotAnimation riveAnimationController2;
List<int> selectedIndexes = [];
UniqueKey key;
MailList({
required this.index,
required this.account,
required this.rotationAnim,
required this.circleAvatarController,
required this.riveAnimationController1,
required this.riveAnimationController2,
required this.selectedIndexes,
required this.key
}):super(key: key);
#override
_MailListState createState() => _MailListState();
}
class _MailListState extends State<MailList> {
#override
Widget build(BuildContext context) {
return Listener(
key: UniqueKey(),
child: Dismissible(
key: ValueKey(widget.index),
child: GestureDetector(
key: ValueKey(widget.index),
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 15.0),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20.0),
shape: BoxShape.rectangle,
color: widget.account[widget.index].isSelected ? Colors.blue.withOpacity(0.2): null
),
height: 70,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Column(
children: [
GestureDetector(
child: AnimatedBuilder(
builder: (context, child){
return Transform(
alignment: Alignment.center,
child: CircleAvatar(
key: ValueKey(widget.index),
backgroundColor: widget.account[widget.index].isSelected ? widget.account[widget.index].defaultOnSelectedColor : widget.account[widget.index].senderInfo.profileColor.withOpacity(0.75),
child: TweenAnimationBuilder(
tween: Tween<double>(begin: 0, end: 1),
builder: (context, double anim, child){
return widget.rotationAnim.value > 90 && widget.account[widget.index].isSelected
? Opacity(
child: Icon(
widget.account[widget.index].defaultOnSelectedIcon,
color: Colors.white,
),
opacity: anim,
)
: Text(
widget.account[widget.index].senderInfo.senderName[0].toString(),
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 21.0,
color: Colors.white
));
},
duration: const Duration(seconds: 1),
),
),
transform: /*isSelected(widget.index) ? (Matrix4.identity()
..setEntry(3, 2, 0.001)
..rotateY((widget.rotationAnim.value) / 180 * math.pi))
: (Matrix4.identity()
..setEntry(3, 2, 0.001)
..rotateY(0 / 180 * math.pi))*/
Matrix4.identity()
..setEntry(3, 2, 0.001)
..rotateY((widget.rotationAnim.value) / 180 * math.pi),
);
},
animation: widget.circleAvatarController,
),
onTap: (){
selectUnSelect(widget.index);
widget.account[widget.index].isSelected = !widget.account[widget.index].isSelected;
widget.account[widget.index].isSelected ? widget.circleAvatarController.forward() : widget.circleAvatarController.reverse();
setState(() {
});
},
)
],
mainAxisAlignment: MainAxisAlignment.start,
),
const SizedBox(
width: 10.0,
),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
widget.account[widget.index].senderInfo.senderName,
style: TextStyle(
fontSize: 16.0,
fontWeight: widget.account[widget.index].isSeen
? FontWeight.normal
: FontWeight.bold
),
),
Text(
"10:00"
)
],
)
),
const SizedBox(
height: 5.0,
),
Text(
widget.account[widget.index].title,
overflow: TextOverflow.ellipsis,
style: TextStyle(
fontSize: 14.5,
fontWeight: widget.account[widget.index].isSeen
? FontWeight.normal
: FontWeight.bold
),
),
const SizedBox(
height: 5.0,
),
Expanded(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Expanded(
child: Text(
widget.account[widget.index].content,
overflow: TextOverflow.ellipsis,
),
),
GestureDetector(
child: Container(
child: widget.account[widget.index].starred ? Icon(
Icons.star,
color: Colors.orange[300],
):
Icon(
Icons.star_border
),
),
onTap: (){
setState(() {
widget.account[widget.index].starred = !widget.account[widget.index].starred;
});
},
)
],
),
),
const SizedBox(
height: 5.0,
),
],
),
)
],
),
),
),
onTap: (){
},
),
background: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: dragWidget(
left: 8.0,
controller: widget.riveAnimationController1
)),
],
),
secondaryBackground: Container(
alignment: Alignment.centerRight,
color: Colors.green,
child: Padding(
padding: EdgeInsets.only(
right: 8.0
),
child: SizedBox(
height: 50.0,
width: 50.0,
child: RiveAnimation.asset(
"assets/gmail_drag_anim.riv",
controllers: [
widget.riveAnimationController2
],
animations: [
"Animation 1"
],
fit: BoxFit.fill,
//antialiasing: false,
),
),
),
),
onDismissed: (direction){
widget.account.removeAt(widget.index);
},
),
);
}
bool isSelected(int index){
return widget.selectedIndexes.contains(index);
}
selectUnSelect(int index){
if(isSelected(index)){
widget.circleAvatarController.reverse();
Future.delayed(Duration(milliseconds: 320), (){
widget.selectedIndexes.remove(index);
setState(() {
});
});
}else{
widget.selectedIndexes.add(index);
}
}
Widget dragWidget({
double? left,
double? right,
required OneShotAnimation controller
}){
return Container(
alignment: right != null ? Alignment.centerRight : Alignment.centerLeft,
color: Colors.green,
child: Padding(
padding: EdgeInsets.only(
left: left != null ? left : 0.0,
right: right != null ? right: 0.0
),
child: SizedBox(
height: 50.0,
width: 50.0,
child: RiveAnimation.asset(
"assets/gmail_drag_anim.riv",
controllers: [
controller
],
animations: [
"Animation 1"
],
fit: BoxFit.fill,
//antialiasing: false,
),
),
),
);
}
} ```
// ListView.builder:
SliverList(
delegate: SliverChildBuilderDelegate(
(context, index){
return MailList(
key: GlobalKey<_MailListState>(),
index: index,
account: account1_mail_data,
rotationAnim: rotationAnim,
circleAvatarController: circleAvatarController,
riveAnimationController1: _riveAnimationController1,
riveAnimationController2: _riveAnimationController2,
selectedIndexes: selectedIndexes
);
},
childCount: account1_mail_data.length
),
)

Flutter UI List Item

I am using the below code but not able to achieve the desired result, I am new to the flutter world so let me know where to improve to get the desired result. Here is the source code of what I have done.
return Expanded(
child: GridView.builder(
controller: _scrollController,
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
itemCount: albumList.length,
itemBuilder: (BuildContext context, int index) {
return buildRow(index);
},
),
);
Widget buildRow(int index) {
return AlbumTile(
index: index,
albumList: albumList,
deleteAlbum: _deleteAlbum,
);
}
This the Album Tile
class AlbumTile extends StatelessWidget {
AlbumTile(
{Key key,
#required this.index,
#required this.albumList,
#required this.deleteAlbum})
: super(key: key);
final int index;
final List<Album> albumList;
final Function deleteAlbum;
#override
build(BuildContext context) {
String thumb;
if (albumList.elementAt(index).thumbUrl != "") {
thumb = WEBSERVICE_IMAGES +
albumList.elementAt(index).userId.toString() +
'/' +
albumList.elementAt(index).id.toString() +
'/' +
albumList.elementAt(index).thumbUrl;
} else {
thumb = "https://cdn.pixabay.com/photo/2015/12/01/20/28/road-1072823__340.jpg";
}
return GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
new AlbumPage(tabIndex: index, albumList: albumList),
),
);
},
child: Container(
// height of the card which contains full item
height: MediaQuery.of(context).size.height * 0.4,
width: MediaQuery.of(context).size.width * 0.28,
// this is the background image code
decoration: BoxDecoration(
image: DecorationImage(
fit: BoxFit.cover,
// url is my own public image url
image: NetworkImage(thumb),
),
borderRadius: BorderRadius.circular(12.0)),
// this is the item which is at the bottom
child: Align(
// aligment is required for this
alignment: Alignment.bottomLeft,
// items height should be there, else it will take whole height
// of the parent container
child: Container(
padding: EdgeInsets.only(left: 10.0, right: 0.0),
height: MediaQuery.of(context).size.height * 0.1,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
// Text() using hard coded text right now
Text(albumList.elementAt(index).name,
style: TextStyle(
fontSize: 18.5,
color: Colors.white,
fontWeight: FontWeight.w500)),
SizedBox(height: 3.0),
Text(albumList.elementAt(index).photos.toString() +' photos',
style: TextStyle(
fontSize: 12.5,
color: Colors.white,
fontWeight: FontWeight.w500))
],
),
),
// pop-up item
PopupMenuButton(
icon: Icon(Icons.more_vert, color: Colors.white),
itemBuilder: (_) => <PopupMenuItem<String>>[
new PopupMenuItem<String>(
child: Row(
children: <Widget>[
Icon(Icons.delete),
Text(
'Delete Album',
),
],
),
value: 'Delete',
),
],
onSelected: (value) {
deleteAlbum(albumList.elementAt(index).id, index);
},
),
],
),
),
),
),
);
GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
new AlbumPage(tabIndex: index, albumList: albumList),
),
);
},
child: Padding(
padding: const EdgeInsets.all(12.0),
child: Stack(
fit: StackFit.loose,
children: <Widget>[
ClipRRect(
borderRadius: new BorderRadius.circular(8.0),
child: FadeInImage.assetNetwork(
height: 1000,
placeholder: kPlaceHolderImage,
image: thumb,
fit: BoxFit.cover,
),
),
Align(
alignment: Alignment.bottomLeft,
child: Row(
children: [
Expanded(
child: Padding(
padding: const EdgeInsets.fromLTRB(8, 0, 0, 0),
child: Text(
albumList.elementAt(index).name,
style: TextStyle(
color: Colors.white,
fontSize: 18.5,
),
textAlign: TextAlign.left,
),
),
),
PopupMenuButton(
icon: ImageIcon(
AssetImage("graphics/horizontal_dots.png"),
color: Colors.white,
),
itemBuilder: (_) => <PopupMenuItem<String>>[
new PopupMenuItem<String>(
child: Row(
children: <Widget>[
Icon(Icons.delete),
Text(
'Delete Album',
),
],
),
value: 'Delete',
),
],
onSelected: (value) {
deleteAlbum(albumList.elementAt(index).id, index);
}),
],
),
),
],
),
),
);
}
}
Thank you in advance.
Welcome to the flutter. Amazing platform to start you career on building cross-platform mobile applications.
My code will look a bit different to you, but trust me, this will work out for you.
Please note: You need to change some parts, like changing the image url for NetworkImage(), onTap function, Text() content etc. But not much changes in the Whole Widget code. So please look for those, and make changes accordingly. You will get there :)
GestureDetector(
onTap: () => print('Works!'), // <-- onTap change, I have used print()
child: Container(
// height of the card which contains full item
height: MediaQuery.of(context).size.height * 0.4,
width: MediaQuery.of(context).size.width * 0.28,
// this is the background image code
decoration: BoxDecoration(
image: DecorationImage(
fit: BoxFit.cover,
// url is my own public image url
image: NetworkImage('https://cdn.pixabay.com/photo/2015/12/01/20/28/road-1072823__340.jpg')
),
borderRadius: BorderRadius.circular(12.0)
),
// this is the item which is at the bottom
child: Align(
// aligment is required for this
alignment: Alignment.bottomLeft,
// items height should be there, else it will take whole height
// of the parent container
child: Container(
padding: EdgeInsets.only(left: 10.0, right: 0.0),
height: MediaQuery.of(context).size.height * 0.1,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
// Text() using hard coded text right now
Text('Potraits', style: TextStyle(fontSize: 20.0, color: Colors.white, fontWeight: FontWeight.w500)),
SizedBox(height: 3.0),
Text('150 photos', style: TextStyle(fontSize: 17.0, color: Colors.white, fontWeight: FontWeight.w500))
]
)
),
// pop-up item
PopupMenuButton(
icon: Icon(Icons.more_vert, color: Colors.white),
itemBuilder: (_) => <PopupMenuItem<String>>[
new PopupMenuItem<String>(
child: Row(
children: <Widget>[
Icon(Icons.delete),
Text(
'Delete Album',
),
],
),
value: 'Delete',
),
],
onSelected: (value) {
//your function
}
)
]
)
)
)
)
)
Result
EDITS FOR WHOLE UI
So, the change required is in your buildRow Widget. You just need to give some paddings on your sides, and you are pretty much solid. Let me know
Widget buildRow(int index) {
return Padding(
padding: EdgeInsets.all(10.0),
child: AlbumTile(
index: index,
albumList: albumList,
deleteAlbum: _deleteAlbum,
)
);
}
And if you are unsatisfied with the spacings, just keep playing with the EdgeInsets painting class. I hope that helps. Please let me know. :)

Images not loading correctly on Carousel Slider in Flutter

I do not know what is wrong with this image loading inside the slider , also I thought this has something to do with the debug but the release version has the same problem, overall all the pictures load slowly and have some delay but this problem is worse.
Container(
margin: EdgeInsets.only(top: Platform.isAndroid ? 85.0 : 115.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
CarouselSlider(
aspectRatio: 1.1,
viewportFraction: 0.6,
initialPage: 0,
enlargeCenterPage: true,
reverse: false,
autoPlay: false,
enableInfiniteScroll: false,
scrollDirection: Axis.horizontal,
onPageChanged: (index) {
if (!mounted) return;
setState(() {
_current = index;
SystemChrome.setEnabledSystemUIOverlays(
[SystemUiOverlay.bottom]);
});
},
items: [
slides("words", "assets/images/Academic_Words.jpg", "Academic\n Words", MyAppWords()),
slides("writing", "assets/images/writing.jpg", "Academic\n Writing", MyAppWriting()),
slides("conference", "assets/images/conference.jpg", "Academic\nConference", EnterPhone()),
slides("conversation", "assets/images/conversations.jpg", "Academic\nConversations", null),
slides("correspondence", "assets/images/correspondence.jpg", "Academic\nCorrespondence", MyAppCorrespondence()),
].map((imgUrl) {
return Builder(
builder: (BuildContext context) {
return Container(
width: MediaQuery.of(context).size.width,
alignment: Alignment.center,
margin: EdgeInsets.symmetric(
vertical: 20.0, horizontal: 9.0),
decoration: BoxDecoration(
borderRadius:
BorderRadius.circular(48.0),
boxShadow: [
BoxShadow(
color:
Color.fromRGBO(50, 50, 50, 1),
blurRadius: 5.0,
// has the effect of softening the shadow
spreadRadius: 5.0,
// has the effect of extending the shadow
offset: Offset(
-1.0,
// horizontal, move right 10
8.0, //
// vertical, move down 10
),
)
]),
child: ClipRRect(
borderRadius: BorderRadius.circular(48.0),
child: imgUrl,
));
},
);
}).toList()),
]),
decoration: BoxDecoration(
borderRadius:
BorderRadius.vertical(top: Radius.circular(48.0)),
color: Color.fromRGBO(237, 237, 237, 1),
),
),
]);
},
));
}
slides(String _tag,String _asset, String _title, Widget myF ){
return GestureDetector(
child: Stack(
fit: StackFit.expand,
alignment: Alignment.center,
children: <Widget>[
Hero(
tag: _tag,
child: Image.asset(
_asset,
fit: BoxFit.cover,
),
),
Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [
Colors.black45,
Colors.black54
],
begin: Alignment.topLeft,
end: Alignment.bottomRight
),
),
),
Container(
alignment: Alignment.center,
child: Text(
_title,
style: TextStyle(
fontSize: 20,
color: Colors.white,
fontWeight: FontWeight.w400,
fontFamily: "Raleway"),
),
)
],
),
onTap: () => Navigator.push(context,
MaterialPageRoute(
builder: (BuildContext context) {
return myF;
})),
);
}
here is a demonstration of my problem=> http://uupload.ir/view/k2ub_video_2019-10-22_10-14-47.mp4/
The behavior seems to be caused by the scaling of the large image. Since carousel_slider: 2.0.0, it's recommended to pass CarouselOptions to options - wherein you can define either the height or aspect ratio for the carousel items.