Flutter中GridView仅显示一列:如何实现数据左右填充排列?
解决Flutter中JSON数据仅单列显示,实现网格左右填充的问题
你当前的问题根源在于用ListView.builder包裹了每个单独的GridView——这相当于每一条数据都生成了一个只有2列的小网格,自然会变成单列排列。正确的做法是直接用GridView.builder来替代ListView,让整个列表本身就是网格布局,这样数据就会从左到右自动填充了。
修改步骤:
- 移除
_getListViewWidget里的ListView,换成GridView.builder - 配置GridView的
crossAxisCount(你想要的列数,比如2),以及其他布局参数 - 调整
_buildLostItems方法,直接返回Card即可,不需要再嵌套GridView
修正后的完整代码:
import 'dart:async'; import 'package:flutter/material.dart'; import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:elegal_dart/models/items.dart'; import 'package:elegal_dart/services/api.dart'; class LostPage extends StatefulWidget { @override _LostPage createState() => new _LostPage(); } class _LostPage extends State<LostPage> { List<Item> _items = []; @override void initState() { super.initState(); _loadLostItems(); } _loadLostItems() async { String fileData = await DefaultAssetBundle.of(context).loadString("assets/items.json"); setState(() { _items = ItemApi.allItemsFromJson(fileData); }); print(_items.toString()); } Widget _buildLostItems(BuildContext context, int index) { Item item = _items[index]; // 直接返回Card,不再嵌套GridView return Card( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Expanded( child: Stack( fit: StackFit.expand, children: <Widget>[ Container( height: MediaQuery.of(context).size.height / 4, width: MediaQuery.of(context).size.height / 2.5, child: DecoratedBox( decoration: BoxDecoration( image: DecorationImage( image: NetworkImage(item.item_DispPic), fit: BoxFit.cover), ), ), ), Padding( padding: const EdgeInsets.all(8.0), child: Align( alignment: FractionalOffset.topLeft, child: CircleAvatar( backgroundColor: Colors.redAccent, radius: 15.0, child: Text( "NEW", textScaleFactor: 0.5, ), ), ), ), Align( alignment: FractionalOffset.topRight, child: Container( color: Colors.blueAccent, height: 35.0, width: 35.0, child: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Icon(Icons.account_circle), Text( "1P", textScaleFactor: 0.5, ), ], ), ), ), ), ], ), ), Center( child: Container( padding: const EdgeInsets.all(8.0), alignment: FractionalOffset.bottomCenter, child: Text( "MEGADISH", style: TextStyle( fontWeight: FontWeight.w700, ), ), ), ), Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: <Widget>[ FlatButton( child: Text( "Add To Cart", style: TextStyle(color: Colors.grey[500]), ), onPressed: () => null, ), Text( "\$5", style: TextStyle(color: Colors.grey[500]), ) ], ) ], ), ); } Widget _getAppTitleWidget() { return new Text( 'Lost Items', style: new TextStyle( color: Colors.white, fontWeight: FontWeight.bold, fontSize: 32.0, ), ); } Widget _buildBody() { return new Container( margin: const EdgeInsets.fromLTRB( 8.0, 56.0, 8.0, 0.0 ), child: new Column( children: <Widget>[ //_getAppTitleWidget(), _getGridViewWidget() // 替换成网格组件 ], ), ); } Future<Null> refresh() { _loadLostItems(); return new Future<Null>.value(); } Widget _getGridViewWidget() { return new Flexible( child: new RefreshIndicator( onRefresh: refresh, // 用GridView.builder替代ListView child: new GridView.builder( physics: const AlwaysScrollableScrollPhysics(), itemCount: _items.length, gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 2, // 设置列数为2 crossAxisSpacing: 8.0, // 列之间的间距 mainAxisSpacing: 8.0, // 行之间的间距 ), itemBuilder: _buildLostItems ) ) ); } @override Widget build(BuildContext context) { return new Scaffold( backgroundColor: Colors.blue, body: _buildBody(), ); } }
关键修改说明:
- 把原来的
_getListViewWidget改成_getGridViewWidget,使用GridView.builder来构建网格布局 - 通过
SliverGridDelegateWithFixedCrossAxisCount设置列数、行列间距,精准控制网格的排列样式 _buildLostItems方法不再返回嵌套的GridView,直接返回单个Card组件,由GridView统一负责这些Card的左右填充排列
这样修改后,你的JSON数据就会按照2列的布局从左到右依次填充了,完美解决单列显示的问题。
内容的提问来源于stack exchange,提问作者JackyBoi
相关产品推荐
相关产品推荐

