颤动:GridView 未正确显示
Posted
技术标签:
【中文标题】颤动:GridView 未正确显示【英文标题】:flutter: GridView not showing properly 【发布时间】:2021-12-12 18:50:21 【问题描述】:我正在尝试用颤振语言创建一个餐厅菜单应用程序,我想在 json 文件中以 gridView 的形式查看我保存的数据,但遗憾的是我在运行应用程序时遇到了错误。但是,我尝试更改gridView 到 listView 及其显示良好.. 那么有没有办法将它们显示为gridView? 提前谢谢
[
"placeImage": "assets/images/wood.jpg",
"placeName": "The Hawkers",
"placeItems": ["Burgers","Chinese","Fast Food","Italian","Juice"],
"minOrder": 20
,
"placeImage": "assets/images/wood.jpg",
"placeName": "Flipping Noodles",
"placeItems": ["Burgers","Chinese","Fast Food","Italian","Juice"],
"minOrder": 50
,
"placeImage": "assets/images/wood.jpg",
"placeName": "Pizza Hut",
"placeItems": ["Pizza","Chinese","Fast Food","Italian","Juice"],
"minOrder": 20
,
"placeImage": "assets/images/wood.jpg",
"placeName": "Blue Hill",
"placeItems": ["Burgers","Chinese","Fast Food","Italian","Juice"],
"minOrder": 40
,
"placeImage": "imagess/bluehill.jpg",
"placeName": "Blue Hill",
"placeItems": ["Burgers","Chinese","Fast Food","Italian","Juice"],
"minOrder": 40
]
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
void main() => runApp(Breakfast());
class Breakfast extends StatelessWidget
// This widget is the root of your application.
@override
Widget build(BuildContext context)
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
var bannerItems = ["Burger", "Cheese Chilly", "Noodles", "Pizza"];
var bannerImage = [
"images/burger.jpg",
"images/cheesechilly.jpg",
"images/noodles.jpg",
"images/pizza.jpg"
];
class MyHomePage extends StatelessWidget
@override
Widget build(BuildContext context)
var screenHeight = MediaQuery.of(context).size.height;
var screenWidth = MediaQuery.of(context).size.width;
Future<List<Widget>> createList() async
List<Widget> items = new List<Widget>();
String dataString =
await DefaultAssetBundle.of(context).loadString("assets/data.json");
List<dynamic> dataJSON = jsonDecode(dataString);
dataJSON.forEach((object)
String finalString = "";
List<dynamic> dataList = object["placeItems"];
dataList.forEach((item)
finalString = finalString + item + " | ";
);
items.add(Padding(
padding: EdgeInsets.all(2.0),
child: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(10.0)),
boxShadow: [
BoxShadow(
color: Colors.black12,
spreadRadius: 2.0,
blurRadius: 5.0),
]),
margin: EdgeInsets.all(5.0),
child: Row(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(10.0),
bottomLeft: Radius.circular(10.0)),
child: Image.asset(
object["placeImage"],
width: 80,
height: 80,
fit: BoxFit.cover,
),
),
SizedBox(
width: 250,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(object["placeName"]),
Padding(
padding: const EdgeInsets.only(top: 2.0, bottom: 2.0),
child: Text(
finalString,
overflow: TextOverflow.ellipsis,
style: TextStyle(
fontSize: 12.0,
color: Colors.black54,
),
maxLines: 1,
),
),
Text(
"Min. Order: $object["minOrder"]",
style:
TextStyle(fontSize: 12.0, color: Colors.black54),
)
],
),
),
)
],
),
),
));
);
return items;
return Scaffold(
body: Container(
height: screenHeight,
width: screenWidth,
child: SafeArea(
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Padding(
padding: const EdgeInsets.fromLTRB(10, 5, 10, 5),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
IconButton(icon: Icon(Icons.menu), onPressed: () ),
Text(
"Foodies",
style: TextStyle(fontSize: 50, fontFamily: "Samantha"),
),
IconButton(icon: Icon(Icons.person), onPressed: () )
],
),
),
BannerWidgetArea(),
Container(
child: FutureBuilder(
initialData: <Widget>[Text("")],
future: createList(),
builder: (context, snapshot)
if (snapshot.hasData)
return Padding(
padding: EdgeInsets.all(8.0),
child: GridView.count(
crossAxisCount: 3,
crossAxisSpacing: 4.0,
mainAxisSpacing: 2.0,
children: snapshot.data,
),
);
else
return CircularProgressIndicator();
),
)
],
),
)),
),
floatingActionButton: FloatingActionButton(
onPressed: () ,
backgroundColor: Colors.black,
child: Icon(
MdiIcons.food,
color: Colors.white,
)),
);
class BannerWidgetArea extends StatelessWidget
@override
Widget build(BuildContext context)
var screenWidth = MediaQuery.of(context).size.width;
PageController controller =
PageController(viewportFraction: 0.8, initialPage: 1);
List<Widget> banners = new List<Widget>();
for (int x = 0; x < bannerItems.length; x++)
var bannerView = Padding(
padding: EdgeInsets.all(10.0),
child: Container(
child: Stack(
fit: StackFit.expand,
children: <Widget>[
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(20.0)),
boxShadow: [
BoxShadow(
color: Colors.black38,
offset: Offset(2.0, 2.0),
blurRadius: 5.0,
spreadRadius: 1.0)
]),
),
ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(20.0)),
child: Image.asset(
bannerImage[x],
fit: BoxFit.cover,
),
),
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(20.0)),
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [Colors.transparent, Colors.black])),
),
Padding(
padding: EdgeInsets.all(10.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
bannerItems[x],
style: TextStyle(fontSize: 25.0, color: Colors.white),
),
Text(
"More than 40% Off",
style: TextStyle(fontSize: 12.0, color: Colors.white),
)
],
),
)
],
),
),
);
banners.add(bannerView);
return Container(
width: screenWidth,
height: screenWidth * 9 / 16,
child: PageView(
controller: controller,
scrollDirection: Axis.horizontal,
children: banners,
),
);
【问题讨论】:
您可以加入json
进行测试吗?
@YeasinSheikh 我添加了它
【参考方案1】:
首先,我更喜欢来自Future
而不是<Widget>
的数据,并且将避免使用forEach
方法来处理复杂和更大的计算。
让我们使用当前的代码结构条件进行处理。根据您的问题,主要问题是使用ListView
/GridView
。
当SingleChildScrollView
处理滚动时,使用GridView.count
或ListView
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
关于***栏
body: SafeArea(
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.min, // set min
children: <Widget>[
为了检查错误,定义FutureBuilder
的状态
child: FutureBuilder<List<Widget>>(
initialData: [Text("")],
future: createList(context),
builder: (context, snapshot)
if (snapshot.connectionState == ConnectionState.waiting)
return Text("Loading");
if (snapshot.hasError)
return Text("Error $snapshot.error");
if (snapshot.hasData)
return Padding(
padding: EdgeInsets.all(8.0),
child: GridView.count(
childAspectRatio: 1 // items' width/height
crossAxisCount: 3,
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
children: [
...snapshot.data!,
],
),
为了加载 JSON,我使用了 String dataString = await rootBundle.loadString("json/data.json");
要处理项目大小,请使用childAspectRatio
。
假设您在加载图像/BannerWidgetArea()
小部件时没有问题。
解决问题了吗?
【讨论】:
确实谢谢!! :D以上是关于颤动:GridView 未正确显示的主要内容,如果未能解决你的问题,请参考以下文章
如何阻止 Gridview.builder 的滚动条在颤动中显示
如何在颤动中计算 GridView.builder 的 childAspectRatio
如何在颤动中直接将数据从 StreamBuilder 获取到 GridView 中?