Reputation: 1235
i've been searching for a way to achieve this design but i am not sure what is the best way to do so , i'd like to know how to layout these lists using listview and gridview(which can be changed to a listview on icon press) , thanks
Upvotes: 0
Views: 554
Reputation: 1280
you can use slivers to include all of the grids and lists in one scroll view.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget{
@override
State<StatefulWidget> createState() {
return _MyAppState();
}
}
class _MyAppState extends State<MyApp> {
bool isGrid = true;
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('demo'),),
body: Padding(
child: CustomScrollView(
slivers: <Widget>[
SliverToBoxAdapter(
child: Container(
height: 100.0,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: 10,
itemBuilder: (context, index) {
return Container(
width: 100.0,
child: Card(
child: Text('data'),
),
);
},
),
),
),
SliverToBoxAdapter(
child: Row(
children: <Widget>[
Text('choose view method'),
Row(
children: <Widget>[
IconButton(icon: Icon(Icons.list), onPressed: (){
setState(() {
isGrid = false;
});
}, ),
IconButton(icon: Icon(Icons.grid_on), onPressed: (){
setState(() {
isGrid = true;
});
}, ),
],
)
],
),
),
ProductsWidget(
isGrid: isGrid,
),
],
), padding: EdgeInsets.all(20),
),
),
);
}
}
class ProductsWidget extends StatelessWidget {
final bool isGrid;
const ProductsWidget({Key key, this.isGrid = true}) : super(key: key);
@override
Widget build(BuildContext context) {
return isGrid ? SliverGrid(
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 200.0,
mainAxisSpacing: 10.0,
crossAxisSpacing: 10.0,
childAspectRatio: 4.0,
),
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
return Container(
width: 100.0,
child: Card(
child: Text('data'),
),
);
},
childCount: 50,
),
) : SliverList(
delegate: SliverChildListDelegate(
[
Card(child: Text('data'),),
Card(child: Text('data'),),
Card(child: Text('data'),),
Card(child: Text('data'),),
],
), ) ;
}
}
Upvotes: 1
Reputation: 2264
I think going with just a gridview for the bottom list and changing the up the delegate's childAspectRatio
(since grid items don't go by explicit height apparently) and crossAxisCount
would do it.
import 'package:flutter/material.dart';
class Tires extends StatefulWidget {
@override
_TiresState createState() => _TiresState();
}
class _TiresState extends State<Tires> {
var _crossAxisCount = 1;
var _childAspectRatio = 2.0;
@override
Widget build(BuildContext context) {
final mediaQuery = MediaQuery.of(context);
final titleStyle = TextStyle(fontWeight: FontWeight.bold);
return ListView(
children: <Widget>[
Padding(
padding: EdgeInsets.symmetric(horizontal: 16.0),
child: Text('Hot offer', style: titleStyle),
),
SizedBox(height: 8),
Container(
height: mediaQuery.size.height / 4,
child: ListView.separated(
shrinkWrap: true,
padding: EdgeInsets.symmetric(horizontal: 16.0),
scrollDirection: Axis.horizontal,
itemCount: 10,
separatorBuilder: (_, __) => SizedBox(width: 10),
itemBuilder: (_, __) => SizedBox(
width: mediaQuery.size.width / 3,
child: Card(),
),
),
),
SizedBox(height: 8),
Padding(
padding: EdgeInsets.symmetric(horizontal: 16.0),
child: Row(
children: <Widget>[
Text('Hot offer', style: titleStyle),
Spacer(),
IconButton(
icon: Icon(Icons.list),
onPressed: () => setState(() {
_crossAxisCount = _crossAxisCount = 1;
_childAspectRatio = _childAspectRatio = 2.0;
}),
),
IconButton(
icon: Icon(Icons.grid_on),
onPressed: () => setState(() {
_crossAxisCount = _crossAxisCount = 2;
_childAspectRatio = _childAspectRatio = 1.0;
}),
),
],
),
),
SizedBox(height: 8),
GridView.builder(
primary: false,
shrinkWrap: true,
padding: EdgeInsets.symmetric(horizontal: 16.0),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
childAspectRatio: _childAspectRatio,
crossAxisSpacing: 16,
mainAxisSpacing: 16,
crossAxisCount: _crossAxisCount,
),
itemCount: 15,
itemBuilder: (_, __) => Card(),
)
],
);
}
}
Upvotes: 1