some part of the positioned widget out of the screen - flutter

GridView.builder item:
class CouncileMemberWidget extends StatelessWidget {
const CouncileMemberWidget(
{Key? key, this.image, this.name, this.party, this.onTap})
: super(key: key);
final String? image, name, party;
final VoidCallback? onTap;
#override
Widget build(BuildContext context) {
return Padding(
padding: EdgeInsets.only(top: Adaptive.h(2), bottom: Adaptive.h(2)),
child: InkWell(
onTap: onTap,
child: Stack(
clipBehavior: Clip.none,
children: [
Positioned(
top: Adaptive.h(11),
left: Adaptive.w(2),
right: Adaptive.w(2),
child: Container(
alignment: Alignment.bottomCenter,
height: Adaptive.h(12),
width: Adaptive.w(40),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(7),
color: const Color.fromRGBO(1, 118, 136, 1),
),
child: Padding(
padding: EdgeInsets.only(bottom: Adaptive.h(0.3)),
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Text(
name!,
style: innerDetailsStyle,
),
],
),
),
),
),
Positioned(
child: Center(
child: Container(
height: Adaptive.h(20),
width: Adaptive.w(37),
decoration: BoxDecoration(
color: Colors.red,
borderRadius: BorderRadius.circular(10),
image: DecorationImage(
image: NetworkImage(image!), fit: BoxFit.fill)),
),
),
),
],
),
),
);
}
}
GridView.builder code
class CouncilMemberPage extends StatelessWidget {
CouncilMemberPage({Key? key}) : super(key: key);
GlobalKey<ScaffoldState> innerScaffoldKey = GlobalKey<ScaffoldState>();
#override
Widget build(BuildContext context) {
return Scaffold(
key: innerScaffoldKey,
drawer: const DrawerMenuWidget(),
body: ChangeNotifierProvider<CouncilMemberViewModel>(
create: (context) => CouncilMemberViewModel(),
builder: (context, child) => BackGroundWidget(
scaffoldkey: innerScaffoldKey,
pageHeader: "Meclis Üyeleri",
child: FutureBuilder<dynamic>(
future:
Provider.of<CouncilMemberViewModel>(context, listen: false)
.getCouncilMembers(),
builder: (context, snapshot) {
if (snapshot.hasData) {
List<CouncilMemberModel?> list = snapshot.data;
return SizedBox(
height: Adaptive.h(70),
child: GridView.builder(
itemCount: list.length,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
mainAxisSpacing: Adaptive.h(3),
//childAspectRatio: Adaptive.w(15) / Adaptive.h(4.5),
crossAxisCount: 2,
),
itemBuilder: (context, index) {
return CouncileMemberWidget(
image: list[index]!.photo!,
name: list[index]!.title,
party: list[index]!.party,
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
CouncilMemberDetailsPage(
name: list[index]!.title,
content: list[index]!.content,
image: list[index]!.photo,
party: list[index]!.party,
)));
},
);
}),
);
} else if (snapshot.hasError) {}
return const Center(child: CircularProgressIndicator());
}
),
),
),
);
}
}
When i list all items in the gridView.builder last item looks overflowed.You can see that in the picture below.Same error happens with the ListView.builder.Why this is happening what should i do solve this overflow.I used FractionalTransaction instead of Positioned but same error occured.

Related

Flutter wrong size of image in list view

I have created a list view with images in flutter. it works but the images is wrong size. It looks like this:
But what I want is this:
This is the code I am using:
SizedBox(
height: 300,
child: ListView.builder(
shrinkWrap: true,
scrollDirection: Axis.horizontal,
itemBuilder: (BuildContext ctx, int index) {
return SizedBox(
width: MediaQuery.of(context).size.width * 0.5,
child: Card(
child: ClipRRect(
borderRadius: BorderRadius.circular(10),
child: Image.file(
File(_imageFileListM[index].path),
fit: BoxFit.fitWidth,
),
),
margin: const EdgeInsets.all(10),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0),
),
));
},
itemCount: _imageFileListM.length,
))
What am I doing wrong?
try this:
SizedBox(
height: 300,
child: ListView.builder(
shrinkWrap: true,
scrollDirection: Axis.horizontal,
itemBuilder: (BuildContext ctx, int index) {
return SizedBox(
width: MediaQuery.of(context).size.width * 0.5,
child: Card(
elevation: 0,
color: Colors.transparent,
surfaceTintColor: Colors.transparent,
child: Align(
alignment: Alignment.center,
child: Container(
clipBehavior: Clip.antiAlias,
decoration: BoxDecoration(
color: Colors.transparent,
borderRadius: BorderRadius.circular(10),
),
child: Image.file(
File(_imageFileListM[index].path),
fit: BoxFit.contain,
),
),
),
margin: const EdgeInsets.all(10),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0),
),
));
},
itemCount: _imageFileListM.length,
)),
use container widget Box decoration property
like this may help you
Container(
height: 200.h,
width: double.infinity,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage("Enter your path")
),
color: baseColor2,
borderRadius: BorderRadius.only(
bottomLeft:Radius.circular(20.r),
bottomRight:Radius.circular(20.r))),
),
Just wrap your list element with FittedBox like this:
SizedBox(
height: 300,
child: ListView.builder(
shrinkWrap: true,
scrollDirection: Axis.horizontal,
itemBuilder: (BuildContext ctx, int index) {
return SizedBox(
width: MediaQuery.of(context).size.width * 0.5,
child: FittedBox(
child: Card(
child: ClipRRect(
borderRadius: BorderRadius.circular(20),
child: Image.file(
File(_imageFileListM[index].path),
fit: BoxFit.fitWidth,
),
),
margin: const EdgeInsets.all(10),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0),
),
),
));
},
itemCount: _imageFileListM.length,
)))
A simple way to achieve this is to use Stack and position.
Stack allows widgets to overlap each other.
Positioned allows you to render its child at a specific location within the stack.
The stack is pretty much like a column but the widgets are rendered on top of each other therefore you need to specify how they should render.
This would be your main Image Widget:
The image is wrapped in an expanded-sized box to cover the whole space.
positioned is set to bottom 0 will stick the widget to the bottom.
left and right are specified to be 0 so the widget also expands horizontally.
class ImageWidget extends StatelessWidget {
final String url;
const ImageWidget({super.key, required this.url});
#override
Widget build(BuildContext context) {
return ClipRRect(
borderRadius: BorderRadius.circular(16),
child: Stack(
children: [
SizedBox.expand(
child: Image.network(
url,
fit: BoxFit.contain,
),
),
const Positioned(
left: 0,
right: 0,
bottom: 0,
child: ImageChildWidget(),
),
],
),
);
}
}
This would be the bottom part. you can replace this with anything you'd like.
class ImageChildWidget extends StatelessWidget {
const ImageChildWidget({super.key});
#override
Widget build(BuildContext context) {
return const ColoredBox(
color: Color.fromARGB(155, 0, 0, 0),
child: Padding(
padding: EdgeInsets.all(8),
child: Text(
'Some Long Text',
style: TextStyle(
color: Colors.white,
fontSize: 16,
),
),
),
);
}
}
You also have a grid view, it's easy with gridDelegate
crossAxisCount: 2, says that you want 2 elements per row
mainAxisSpacing: 16, says that you want a padding of 16 vertically
crossAxisSpacing: 16, says that you want a padding of 16 horizontally
class GridExample extends StatefulWidget {
const GridExample({super.key});
#override
State<GridExample> createState() => GridExampleState();
}
class GridExampleState extends State<GridExample> {
// Generate a random list of images
List<String> urls = List.generate(
10,
(_) {
int random = Random().nextInt(500) + 250; // 250-500
return 'https://picsum.photos/$random/$random';
},
);
#override
Widget build(BuildContext context) {
return GridView.builder(
key: widget.key,
itemCount: urls.length,
padding: const EdgeInsets.all(16),
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
mainAxisSpacing: 16,
crossAxisSpacing: 16,
),
itemBuilder: (context, index) {
return ImageWidget(
key: ValueKey(urls[index]),
url: urls[index],
);
},
);
}
}
Full code sample.
import 'dart:math';
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
#override
Widget build(BuildContext context) {
return const MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Center(
child: GridExample(
key: ValueKey('grid'),
),
),
),
);
}
}
class GridExample extends StatefulWidget {
const GridExample({super.key});
#override
State<GridExample> createState() => GridExampleState();
}
class GridExampleState extends State<GridExample> {
// Generate a random list of images
List<String> urls = List.generate(
10,
(_) {
int random = Random().nextInt(500) + 250; // 250-500
return 'https://picsum.photos/$random/$random';
},
);
#override
Widget build(BuildContext context) {
return GridView.builder(
key: widget.key,
itemCount: urls.length,
padding: const EdgeInsets.all(16),
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
mainAxisSpacing: 16,
crossAxisSpacing: 16,
),
itemBuilder: (context, index) {
return ImageWidget(
key: ValueKey(urls[index]),
url: urls[index],
);
},
);
}
}
class ImageWidget extends StatelessWidget {
final String url;
const ImageWidget({super.key, required this.url});
#override
Widget build(BuildContext context) {
return ClipRRect(
borderRadius: BorderRadius.circular(16),
child: Stack(
children: [
SizedBox.expand(
child: Image.network(
url,
fit: BoxFit.contain,
),
),
const Positioned(
left: 0,
right: 0,
bottom: 0,
child: ImageChildWidget(),
),
],
),
);
}
}
class ImageChildWidget extends StatelessWidget {
const ImageChildWidget({super.key});
#override
Widget build(BuildContext context) {
return const ColoredBox(
color: Color.fromARGB(155, 0, 0, 0),
child: Padding(
padding: EdgeInsets.all(8),
child: Text(
'Some Long Text',
style: TextStyle(
color: Colors.white,
fontSize: 16,
),
),
),
);
}
}
End result:

How to show container in listview using wrap

I'm trying to show title in box, and i want two box in a row, but it is not working, i'm using ListView.builder
here is the code
Widget build(BuildContext context) {
return SafeArea(
child: SingleChildScrollView(
child: Container(
color: Color(int.parse(bodycolor)),
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
child: Padding(
padding: EdgeInsets.all(16.0),
child: SingleChildScrollView(
child: Column(
children: [
SizedBox40(),
Align(
alignment: Alignment.center,
child: Text("Choose any one Business", style: GoogleFonts.montserrat(fontSize:20)),
),
ListView.builder(
shrinkWrap: true,
itemCount: books.length,
itemBuilder: (context, index) {
final book = books[index];
return Wrap(
spacing: 20.0,
runSpacing: 40.0,
children:[
InkWell( child: Container(
height: MediaQuery.of(context).size.height*0.15,
width: MediaQuery.of(context).size.width*0.4,
decoration: BoxDecoration(
color: Colors.red,
borderRadius: BorderRadius.all(
Radius.circular(10),
), ),
child:Text(book.title))),
SizedBox20(),
]
);
}),
SizedBox20(),
],
),
),
here is the snap
it shows in vertically, i want them 2 in row. please help if anyone know how to do this.
instead of Listview.builder, you can use GridView.builder
GridView.builder(
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2 // don't forget to use cross count
childAspectRatio: 3 / 2,
crossAxisSpacing: 20,
mainAxisSpacing: 20),
itemCount: myProducts.length,
itemBuilder: (BuildContext ctx, index) {
return Container(
alignment: Alignment.center,
child: Text(myProducts[index]["name"]),
decoration: BoxDecoration(
color: Colors.amber,
borderRadius: BorderRadius.circular(15)),
);
}),
Complete source code:
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
// Hide the debug banner
debugShowCheckedModeBanner: false,
title: 'Kindacode.com',
home: HomeScreen(),
);
}
}
class HomeScreen extends StatelessWidget {
HomeScreen({Key key}) : super(key: key);
final List<Map> myProducts =
List.generate(100000, (index) => {"id": index, "name": "Product $index"})
.toList();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Flutter test'),
),
body: Padding(
padding: const EdgeInsets.all(8.0),
child: GridView.builder(
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
childAspectRatio: 3 / 2,
crossAxisSpacing: 20,
mainAxisSpacing: 20),
itemCount: myProducts.length,
itemBuilder: (BuildContext ctx, index) {
return Container(
alignment: Alignment.center,
child: Text(myProducts[index]["name"]),
decoration: BoxDecoration(
color: Colors.amber,
borderRadius: BorderRadius.circular(15)),
);
}),
),
);
}
}
Output:
N.B: Don't forget to use crossAxisCount
You can use GridView.
GridView.builder(
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
itemBuilder: (context, index) {
final book = books[index];
return InkWell(
child: Container(
height: MediaQuery.of(context).size.height * 0.15,
width: MediaQuery.of(context).size.width * 0.4,
decoration: const BoxDecoration(
color: Colors.red,
borderRadius: BorderRadius.all(
Radius.circular(10),
),
),
child: Text(book.title),
),
);
},
)

thrown during paint(): 'package:flutter/src/rendering/sliver_multi_box_adaptor.dart': Failed assertion: line 544 pos 12: 'child.hasSize': is not true

I want to build a Carousel Slider that shows Product Images of a List I've made earlier, with an onPressed function that Navigates to another Route that shows the details of the tapped product, My product list is of name List< Productz >.
When I call the Carousel Slider method in my Home_Page Route I need "itemBuilder: (context, index)", so I wrapped it in a ListView.builder and wrapped that into a Container with defined height and width to avoid the error above, but on running the app nothing shows in the place where the Carousel Slider is supposed to be.. Am I doing this right?
My Carousel Slider code:
class CustomCarouselHomePage extends StatefulWidget {
final List<String> Productzz;
final Function press;
final Productz productz;
CustomCarouselHomePage(
{required this.Productzz, required this.press, required this.productz});
#override
_CustomCarouselHomePageState createState() => _CustomCarouselHomePageState();
}
class _CustomCarouselHomePageState extends State<CustomCarouselHomePage> {
int activeIndex = 0;
late final Function press;
late final Productz productz;
setActiveDot(index) {
setState(() {
activeIndex = index;
});
}
#override
Widget build(BuildContext context) {
return Stack(
clipBehavior: Clip.none,
children: <Widget>[
Container(
width: MediaQuery.of(context).size.width,
child: CarouselSlider(
options: CarouselOptions(
autoPlayInterval: Duration(seconds: 4),
autoPlayCurve: Curves.fastLinearToSlowEaseIn,
autoPlayAnimationDuration: Duration(seconds: 2),
viewportFraction: 1.0,
onPageChanged: (index,reason) {
setActiveDot(index);
},
),
items: widget.Productzz.map((productzz) {
return Builder(
builder: (BuildContext context) {
return GestureDetector(
onTap: () => press (),
child: Stack(
// crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
width: MediaQuery.of(context).size.width,
child: Hero(
tag: "${productz.id}",
child: Image.asset(productz.item_image),
),
),
Container(
width: MediaQuery.of(context).size.width,
color: Colors.black.withOpacity(0.2),
),
],
), );
},
);
}).toList(),
),
),
Positioned(
left: 0,
right: 0,
bottom: 10,
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: List.generate(widget.Productzz.length, (idx) {
return activeIndex == idx ? ActiveDot() : InactiveDot();
})),
)
],
);
}
}
class ActiveDot extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.only(right: 8.0),
child: Container(
width: 25,
height: 8,
decoration: BoxDecoration(
color: white,
borderRadius: BorderRadius.circular(5),
),
),
);
}
}
class InactiveDot extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.only(right: 8.0),
child: Container(
width: 8,
height: 8,
decoration: BoxDecoration(
color: grey,
borderRadius: BorderRadius.circular(5),
),
),
);
}
}
My code for when I call the Carousel Slider method in Home_Page Route:
Container(
height:MediaQuery.of(context).size.height,
child: ListView.builder(
itemBuilder: (context, index) => CustomCarouselHomePage(
Productzz: [],
productz: productz[index],
press: () => Navigator.push(
context,
MaterialPageRoute(
builder: (context) => DetailsScreen(
productz: productz[index],
),
)),
),
),),

Flutter hero animation not working, same tag but still not animating in new screen

I have memory image in my downloads screen as grid tile and when clicked, it will animated to next full image view page where whole body is imageview so i want to animated to new screen with hero animation but it is not working.
I even provided the same tag but still not animating.
The problem is that it work with Navigator.push method but here i am using Get.toNamed() method as i am passing arguments to next screen controller class , but with this navigation it is not animating. how to do hero animation with Getx navigation?
dowloads.dart
class Downloads extends StatelessWidget {
final photos = DatabaseProvider.db.getPictures();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: brandName('Down', 'loads'),
elevation: 0.0,
),
body: FutureBuilder<List<Picture>>(
future: photos,
builder: (BuildContext context, AsyncSnapshot<List<Picture>> snapshot) {
if (snapshot.hasData) {
if (snapshot.data.length == 0) {
return Center(
child: Text(
'No data available for downloads',
textAlign: TextAlign.center,
style: TextStyle(fontWeight: FontWeight.w300, fontSize: 18),
));
} else {
return AnimationLimiter(
child: GridView.count(
shrinkWrap: true,
padding: EdgeInsets.symmetric(horizontal: 20, vertical: 24),
physics: BouncingScrollPhysics(
parent: AlwaysScrollableScrollPhysics()),
crossAxisCount: 2,
childAspectRatio: 0.6,
mainAxisSpacing: 10.0,
crossAxisSpacing: 10.0,
children: snapshot.data.map((wallpaper) {
return AnimationConfiguration.staggeredGrid(
position: 2,
duration: Duration(milliseconds: 500),
columnCount: 3,
child: ScaleAnimation(
duration: Duration(milliseconds: 900),
curve: Curves.fastLinearToSlowEaseIn,
scale: 1.5,
child: FadeInAnimation(
child: GridTile(
child: GestureDetector(
onTap: () {
Get.toNamed(
'/image_view',
arguments: [
wallpapers[index].src.portrait,
wallpapers[index].photographer,
wallpapers[index].photographerUrl
],
);
},
child: Container(
child: ClipRRect(
borderRadius: BorderRadius.circular(16),
child: Hero(
tag: 'picture:${wallpaper.imageUrl}',
child: Image.memory(
wallpaper.picture,
fit: BoxFit.cover,
),
),
),
),
),
),
),
),
);
}).toList(),
),
);
}
} else {
return Center(child: CircularProgressIndicator());
}
},
),
);
}
}
imageVeiw.dart
class LocalImageView extends StatelessWidget {
final Uint8List pictureBytes;
final String imageUrl;
final String title;
LocalImageView({this.pictureBytes, this.imageUrl, this.title});
#override
Widget build(BuildContext context) {
print(imageUrl);
return Container(
child: LayoutBuilder(
builder: (context, constraints) => SingleChildScrollView(
reverse: true,
scrollDirection: Axis.horizontal,
child: SizedBox(
height: constraints.biggest.height,
child: Hero(
tag: 'picture:$imageUrl',
child: Image.memory(
pictureBytes,
fit: BoxFit.cover,
),
),
),
),
),
);
}
}

How to create multiple horizontal `GridView` in the same screen using flutter

Is there's a way to create a lists of GridViews as the below image in one screen...
I have a some Screen as the below one:
class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin {
var _showOnlyFavorites = false;
AnimationController animationController;
bool multiple = true;
#override
void initState() {
animationController = AnimationController(
duration: const Duration(milliseconds: 2000), vsync: this);
super.initState();
}
Future<bool> getData() async {
await Future<dynamic>.delayed(const Duration(milliseconds: 0));
return true;
}
#override
void dispose() {
animationController.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: AppTheme.white,
body: FutureBuilder<bool>(
future: getData(),
builder: (BuildContext context, AsyncSnapshot<bool> snapshot) {
if (!snapshot.hasData) {
return const SizedBox();
} else {
return Padding(
padding: EdgeInsets.only(top: MediaQuery.of(context).padding.top),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
appBar(),
Expanded(
child: FutureBuilder<bool>(
future: getData(),
builder:
(BuildContext context, AsyncSnapshot<bool> snapshot) {
if (!snapshot.hasData) {
return const SizedBox();
} else {
return PropertiesGrid(_showOnlyFavorites);
}
},
),
),
],
),
);
}
},
),
);
}
Widget appBar() {
return SizedBox(
height: AppBar().preferredSize.height,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(top: 8, left: 8),
child: Container(
width: AppBar().preferredSize.height - 8,
height: AppBar().preferredSize.height - 8,
),
),
Expanded(
child: Center(
child: Padding(
padding: const EdgeInsets.only(top: 4),
child:
Image.asset('assets/images/logo.png', fit: BoxFit.contain),
),
),
),
Padding(
padding: const EdgeInsets.only(top: 8, right: 8),
child: Container(
width: AppBar().preferredSize.height - 8,
height: AppBar().preferredSize.height - 8,
color: Colors.white,
child: Material(
color: Colors.transparent,
child: InkWell(
borderRadius:
BorderRadius.circular(AppBar().preferredSize.height),
child: Icon(
multiple ? Icons.dashboard : Icons.view_agenda,
color: AppTheme.dark_grey,
),
onTap: () {
setState(() {
multiple = !multiple;
});
},
),
),
),
),
],
),
);
}
}
as I have a widget which have the GridView.builder as the below code:
import 'package:aradi_online_vtwo/providers/properties.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../providers/properties.dart';
import './property_item.dart';
class PropertiesGrid extends StatelessWidget {
final bool showFavs;
PropertiesGrid(this.showFavs);
#override
Widget build(BuildContext context) {
final productsData = Provider.of<Properties>(context);
final products = showFavs ? productsData.favoriteItems : productsData.items;
return GridView.builder(
padding: const EdgeInsets.all(10.0),
itemCount: products.length,
itemBuilder: (ctx, i) => ChangeNotifierProvider.value(
// builder: (c) => products[i],
value: products[i],
child: PropertyItem(
// products[i].id,
// products[i].title,
// products[i].imageUrl,
),
),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 1,
childAspectRatio: 3 / 2,
crossAxisSpacing: 10,
mainAxisSpacing: 10,
), scrollDirection: Axis.horizontal,
);
}
}
I tried to set the height of the grid by wrapping it with a Container and set the height of it as to add more grids but it doesn't work.
and here's my Grid Item widget code:
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../providers/property.dart';
class PropertyItem extends StatelessWidget {
#override
Widget build(BuildContext context) {
final property = Provider.of<Property>(context, listen: false);
return InkWell(
onTap: () => {},
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15),
),
elevation: 7,
margin: EdgeInsets.all(2),
child: Stack(
children: <Widget>[
ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(15),
topRight: Radius.circular(15),
),
// color: Colors.transparent,
child: Image.asset(
property.image,
fit: BoxFit.fill,
),
),
Positioned(
top: 8,
right: 8,
child: Consumer<Property>(
builder: (ctx, property, _) => IconButton(
icon: Icon(
property.isFavorite ? Icons.favorite : Icons.favorite_border,
),
color: Colors.red,
onPressed: () {
property.toggleFavoriteStatus();
},
),
),
),
Positioned(
right: 20,
top: 100,
child: Container(
width: 300,
color: Colors.black54,
padding: EdgeInsets.symmetric(
vertical: 5,
horizontal: 20,
),
child: Text(
property.title,
style: TextStyle(
fontSize: 20,
color: Colors.white,
),
softWrap: true,
overflow: TextOverflow.fade,
),
),
)
],
),
),
);
}
}
You'll need a column where each ListView or GridView is wrapped inside a SizedBox (if you have a specific height) and you also can use Expanded to take whatever available space (like the last one in the given example):
You can post the code below in dartpad.dev and see how it works:
import 'package:flutter/material.dart';
void main() {
runApp(MaterialApp(
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyApp(),
));
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Column(
children: [
SizedBox(
height: 100,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: 10,
itemBuilder: (c, i) {
return Card(
child: Container(
height: 100,
width: 100,
child: Center(child: Text("$i")),
),
);
},
),
),
Padding(
padding: const EdgeInsets.all(16.0),
child: Align(
child: Text("The Second List"),
alignment: Alignment.centerRight,
),
),
SizedBox(
height: 100,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: 10,
itemBuilder: (c, i) {
return Card(
child: Container(
height: 100,
width: 100,
child: Center(child: Text("$i")),
),
);
},
),
),
Padding(
padding: const EdgeInsets.all(16.0),
child: Align(
child: Text("The Third List"),
alignment: Alignment.centerRight,
),
),
Expanded(
//height: 200,
child: GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
childAspectRatio: 3 / 2,
crossAxisSpacing: 10,
mainAxisSpacing: 10,
),
scrollDirection: Axis.vertical,
itemCount: 20,
itemBuilder: (c, i) {
return Card(
child: Container(
height: 100,
width: 100,
child: Center(child: Text("$i")),
),
);
},
),
),
],
),
);
}
}