I'd like to build design like Ios app store like image below. What I'm trying to achieve is there are 5 top category and each category has grid that shows images. And I tried like this.
return new Scaffold( backgroundColor: Colors.white, appBar: buildBar(context), // wrap in gesture to dismiss keyboard body: new GestureDetector( behavior: HitTestBehavior.opaque, onPanDown: (detail) { FocusScope.of(context).requestFocus(new FocusNode()); }, child: new ListView( shrinkWrap: true, children: <Widget>[ new Container( decoration: new BoxDecoration(color: Colors.grey[400]), child: new Column( children: <Widget>[ new SizedBox(height: 15.0), new Row( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ new Icon(Icons.invert_colors, color: Colors.red, size: 45.0), new Text('Top 5', style: new TextStyle( color: Colors.white, fontSize: 25.0, fontWeight: FontWeight.bold)), ], ), new SizedBox(height: 15.0), ], ), ), new SizedBox(height: 30.0), new ListView.builder( shrinkWrap: true, itemCount: 5, itemBuilder: (BuildContext context, int index) { return new Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ new Container( decoration: new BoxDecoration(color: Colors.lightBlue[200]), child: new Row( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ new Icon(icons[index], size: 30.0), new Padding( padding: const EdgeInsets.only(right: 5.0)), new Text('Category', style: new TextStyle( fontSize: 23.0, fontWeight: FontWeight.bold)), ], ), ), new SizedBox(height: 5.0), new GridView.builder( shrinkWrap: true, scrollDirection: Axis.horizontal, itemCount: 10, gridDelegate: new SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 4), itemBuilder: (BuildContext context, int index) { return new GestureDetector( child: new Card( elevation: 5.0, child: new Container( padding: new EdgeInsets.only( bottom: 2.0, right: 3.0), decoration: new BoxDecoration( image: new DecorationImage( fit: BoxFit.cover, image: NetworkImage( 'https://images.unsplash.com/photo-1505535162959-9bbcb4ab22d6?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=0891a99609bf6fdc48842101bef90d67&auto=format&fit=crop&w=500&q=60'), ), ), ), ), onTap: () { print('tapped'); }); }, ), new SizedBox(height: 20.0), ], ); }, ), ], ), ), );
But grid view doesn't appear and if I commented out grid view then shows list that doesn't have images just category names. I tried to wrap expanded
, set shrinkWrap
to true but did not working. I've been searching through but still can't figure it out. Anyone know how to fix it?
EDIT:
return new Scaffold( backgroundColor: Colors.white, appBar: new AppBar( title: new Text('Search'), ), body: new GestureDetector( behavior: HitTestBehavior.opaque, onPanDown: (detail) { print(detail); FocusScope.of(context).requestFocus(new FocusNode()); }, child: new ListView( shrinkWrap: true, children: <Widget>[ new SizedBox(height: 20.0), new Container( height: 60.0, color: Colors.blue, child: new Row( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ new Icon(Icons.hourglass_empty, color: Colors.white, size: 30.0), new Padding(padding: const EdgeInsets.only(right: 5.0)), new Text('TOP5', style: new TextStyle(color: Colors.white, fontSize: 23.0)), ], ), ), new SizedBox(height: 20.0), new Container( child: new ListView.builder( shrinkWrap: true, itemCount: 5, itemBuilder: (context, index) { return new Column( children: <Widget>[ new Container( height: 50.0, color: Colors.green, child: new Row( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ new Icon(Icons.format_list_numbered, color: Colors.white), new Padding( padding: const EdgeInsets.only(right: 5.0)), new Text(arr[index], style: new TextStyle( fontSize: 20.0, color: Colors.white)), ], ), ), new Container( height: 150.0, child: new ListView.builder( shrinkWrap: true, scrollDirection: Axis.horizontal, itemCount: 10, itemBuilder: (context, index) { return new GestureDetector( child: new Card( elevation: 5.0, child: new Container( height: MediaQuery.of(context).size.width / 3, width: MediaQuery.of(context).size.width / 3, alignment: Alignment.center, child: new Text('Item $index'), ), ), onTap: () { print(123); }, ); }, ), ), new SizedBox(height: 20.0), ], ); }, ), ), ], ), ), );
You just need to put your GridView Widget into the Expanded Widget, for example: body: new Column( children: <Widget>[ new Expanded( child: GridView. count( // Create a grid with 2 columns. If you change the scrollDirection to // horizontal, this would produce 2 rows.
Basically, we can use the Widgets such as SizededBox or Expanded or simply the shrinkWrap property to include ListView inside Column.
You may want to change the scroll direction when the GridView is displayed in landscape mode. Setting scrollDirection to Axis. horizontal will do just that.
I have used a flutter GridView
inside a ListView
, both are vertical scrolling:
body: ListView( children: <Widget>[ GridView.count( crossAxisCount: 3, physics: NeverScrollableScrollPhysics(), // to disable GridView's scrolling shrinkWrap: true, // You won't see infinite size error children: <Widget>[ Container( height: 24, color: Colors.green, ), Container( height: 24, color: Colors.blue, ), ], ), // ...... other list children. ], ),
You can use same approach for flutter horizontal ListView
/GridView
inside another ListView
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With