Reputation: 3130
I am trying to display a gridview that has variable number and width buttons like this:
But what I have ended up with when trying gridview is a fixed number of buttons and fixed widths like this:
Initially I thought this was a problem with the buttons having too much padding by default but that is not the issue, I was able to fix that and still have the same issue with the grid.
I have tried Gridview builder like this:
GridView.builder(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3, childAspectRatio: 3.5, mainAxisSpacing: 4, crossAxisSpacing: 4),
itemBuilder: (BuildContext context, int index) {
return InkWell(
onTap: () {
//Navigator.of(context).pushNamed(HomePageResultsScreen.id);
},
child: ButtonTheme(
minWidth: 16,
height: 30,
child: RaisedButton(
padding: EdgeInsets.all(8.0),
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
color: Colors.white,
child:
Center(
child: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
CachedNetworkImage(fit: BoxFit.contain,
height: 40,
width: 40,
placeholder: (context, url) => new CircularProgressIndicator(),
imageUrl: snapshot.data.documents[index]['icon'].toString(),
),
Text(snapshot.data.documents[index]['name'].toString(), textAlign: TextAlign.right, style: TextStyle(fontSize: 10, color: Colors.black,),),
],
),
),
onPressed: (){
},
),
),
);
},
itemCount: snapshot.data.documents.length,
);
I have also edited the attributes of the builder to haveSliverGridDelagateWithMaxCrossAxisExtent and other attributes. I know the buttons as they are if not placed inside the grid will shrink to minimum size but when in the grid they expand to fill up the whole column.
I have also tried numerous ways by replacing the gridview with a staggered gridview like this:
StaggeredGridView.countBuilder(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
crossAxisCount: 3,
staggeredTileBuilder: (int index) =>
new StaggeredTile.count(2, index.isEven ? 2 : 1),
itemBuilder: (BuildContext context, int index) {
return InkWell(
onTap: () {
//Navigator.of(context).pushNamed(HomePageResultsScreen.id);
},
child: ButtonTheme(
minWidth: 16,
height: 30,
child: RaisedButton(
padding: EdgeInsets.all(8.0),
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
color: Colors.white,
child:
Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
CachedNetworkImage(fit: BoxFit.contain,
height: 20,
width: 20,
placeholder: (context, url) => new CircularProgressIndicator(),
imageUrl: snapshot.data.documents[index]['icon'].toString(),
),
Text(snapshot.data.documents[index]['name'].toString(), textAlign: TextAlign.center, style: TextStyle(fontSize: 10, color: Colors.black,),),
],
),
onPressed: (){
},
),
),
);
},
itemCount: snapshot.data.documents.length,
),
I have tried both StaggeredGridView.countBuilder and StaggeredGridView.extent but both of these are even further from what I imagined. It just ends up with a single button per gridview row (looks like a listview).
I am not sure what I am doing wrong or if this is even possible with these widgets.
Thanks for your help
Upvotes: 5
Views: 4757
Reputation: 309
If these containers are not buttons (mean you don't need to click on each of them to do specific something) then you can use Wrap Widget
https://www.youtube.com/watch?v=z5iw2SeFx2M
https://medium.com/flutter-community/flutter-wrap-widget-e1ee0b005b16
Upvotes: 0
Reputation: 19514
you have to use StaggeredGridView
and you have to find logic to calculate an item width and set StaggeredTile.count
.
final List<String> testing = ['Baby Foods', 'Confectionery', 'Coffee', 'Packets & Units','Packets & Units unis', 'Processed Cheese', 'Factional Care', 'Sauce', 'Sauc'];
Container(
width: width,
child: StaggeredGridView.countBuilder(
itemCount: resting.length,
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
crossAxisCount: 8,
staggeredTileBuilder: (int index) {
if (testing[index].length < 5) {
return StaggeredTile.count(2, 1);
} else if (testing[index].length < 16) {
return StaggeredTile.count(3, 1);
} else {
return StaggeredTile.count(4, 1);
}
},
mainAxisSpacing: 12.0,
crossAxisSpacing: 10.0,
itemBuilder: (BuildContext context, int index) {
return TextButton(
child: Text(testing[index]),
onPressed: () {},
);
},
),
),
Upvotes: 1
Reputation: 1
# # Staggered View
# ScreenShot

# What is it?
A Flutter staggered grid view which supports multiple columns with rows of varying sizes.
It’s a grid layout where the cross axis is divided in multiple equally sized parts, and places elements in optimal position based on available main axis space.
You’ve probably came across some app or website design with staggered grid layout like Pinterest:
# For understand the code
To help you to understand the code, you can see that this grid of 10 tiles is divided into 4 columns:

# Let's Get Started
<H3>1 - Depend on it</h3>
<h6><b>Add it to your package's pubspec.yaml file</b></h6>
<pre>dependencies:
fl_chart: ^0.6.1</pre>
<H3>2 - Install it</h3>
<h6><b>Install packages from the command line</b></h6>
<pre>flutter packages get</pre>
<H3>2 - Getting Started</h3>
<h6><b>Import the package:</b></h6>
<pre>import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';</pre>
<pre>import 'package:flutter/material.dart';
import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
import 'package:ofsdp/pages/home.dart';
import 'package:ofsdp/util/appdrawer.dart';
class AdministrativeUvit extends StatefulWidget {
@override
_AdministrativeUvitState createState() => _AdministrativeUvitState();
}
class _AdministrativeUvitState extends State<AdministrativeUvit> {
var _scaffoldkey = GlobalKey<ScaffoldState>();
List<StaggeredTile> _staggeredTiles = const <StaggeredTile>[
const StaggeredTile.count(1, 1),
const StaggeredTile.count(1, 1),
const StaggeredTile.count(1, 1),
const StaggeredTile.count(1, 1),
const StaggeredTile.count(1, 1.5),
const StaggeredTile.count(1, 1.5),
];
List<Widget> _tiles = const <Widget>[
const _Example01Tile(Colors.green, Icons.widgets),
const _Example01Tile(Colors.lightBlue, Icons.wifi),
const _Example01Tile(Colors.amber, Icons.panorama_wide_angle),
const _Example01Tile(Colors.brown, Icons.map),
const _Example01Tile(Colors.deepOrange, Icons.send),
const _Example01Tile(Colors.indigo, Icons.airline_seat_flat),
const _Example01Tile(Colors.red, Icons.bluetooth),
const _Example01Tile(Colors.pink, Icons.battery_alert),
const _Example01Tile(Colors.purple, Icons.desktop_windows),
const _Example01Tile(Colors.blue, Icons.radio),
];
@override
Widget build(BuildContext context) {
return Stack(
children: <Widget>[
Image.asset(
"assets/images/footer.jpg",
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
fit: BoxFit.cover,
),
Scaffold(
backgroundColor: Colors.transparent,
appBar: AppBar(
backgroundColor: Color.fromRGBO(117, 80, 0, 1),
title: const Text("ADMINISTRATIVE UNIT"),
actions: <Widget>[
IconButton(
icon: Icon(Icons.home),
onPressed: () {
Navigator.of(context).pushReplacement(
MaterialPageRoute(
builder: (context) => HomePage(),
),
);
},
)
],
),
drawer: AppDrawer(),
key: _scaffoldkey,
body: new Padding(
padding: const EdgeInsets.only(top: 12.0),
child: new StaggeredGridView.count(
crossAxisCount: 2,
staggeredTiles: _staggeredTiles,
children: _tiles,
mainAxisSpacing: 4.0,
crossAxisSpacing: 4.0,
padding: const EdgeInsets.all(4.0),
)))
],
);
}
}
class _Example01Tile extends StatelessWidget {
const _Example01Tile(this.backgroundColor, this.iconData);
final Color backgroundColor;
final IconData iconData;
@override
Widget build(BuildContext context) {
return new Card(
color: backgroundColor,
child: new InkWell(
onTap: () {},
child: new Center(
child: new Padding(
padding: const EdgeInsets.all(4.0),
child: new Icon(
iconData,
color: Colors.white,
),
),
),
),
);
}
}</pre>
Upvotes: 0