我目前有一个 SingleChildScrollView 作为父控件,一个 GridView 作为子控件之一。一切正常,但是当 GridView 完成滚动时,滚动不会传递给父 ScrollView。在横向模式下,GridView 占据了整个屏幕,因此用户只能滚动 GridView。我怎样才能传递卷轴?
SingleChildScrollView(
controller: _hideButtonController,
child: Container(
padding: EdgeInsets.only(bottom: 80.0), //padding for fab
child: Column(
children: <Widget>[
_previousWidgets(),
_gridWidget(),
],
),
),
);
在你的 GridView 中像这样设置物理,你很高兴:
physics: NeverScrollableScrollPhysics()
编辑:
这样做可能会占用大量资源,因为它一次性生成所有项目,而不是在滚动时膨胀/生成项目,因此请确保您的网格或列表中没有大量数据。
你应该使用
CustomScrollView
而不是 SingleChildScrollView
.
CustomScrollView
是一个滚动视图,可以组合多种类型的内容。例如列表、网格或普通小部件。
CustomScrollView(
slivers: <Widget>[
SliverToBoxAdapter(
child: Container(
height: 50.0,
width: double.infinity,
color: Colors.yellow,
),
),
SliverGrid(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
childAspectRatio: 1.0,
mainAxisSpacing: 10.0,
crossAxisSpacing: 10.0),
delegate: SliverChildBuilderDelegate(
(context, index) {
return Container(
color: Colors.red,
);
},
childCount: 10,
),
),
SliverPadding(
padding: const EdgeInsets.only(bottom: 80.0),
)
],
),
我在这里回答了一个类似的问题: https://stackoverflow.com/a/76192690/11976596
你可以在下面找到相同的-
我有一个类似的问题,我在
GridView.builder
里面有一个SingleChildScrollView
。现在的问题是你不能在 GridView
里面创建一个 SingleChildScrollView
因为两者都会尝试占用尽可能多的可用空间,这使得高度无限/无限。
所以解决方案是用
GridView
包裹SizedBox
,我总是喜欢使用GridView.Builder
。
现在真正的问题是,“当列表是动态的时,我怎么知道
SizedBox
的大小?”
所以我写了这段代码,根据
SizedBox
的
childAspectRatio
属性动态计算
GridView
的高度
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return const MaterialApp(title: 'Dynamic GridView', home: Home());
}
}
class Home extends StatelessWidget {
const Home({super.key});
@override
Widget build(BuildContext context) {
final double width = MediaQuery.of(context).size.width;
final double height = MediaQuery.of(context).size.height;
return Scaffold(
body: SingleChildScrollView(
child: Column(
children: [
itemGrid(width),
],
),
),
);
}
Widget itemGrid(double width) {
const int count = 16;
const int itemsPerRow = 2;
const double ratio = 1 / 1;
const double horizontalPadding = 0;
final double calcHeight = ((width / itemsPerRow) - (horizontalPadding)) *
(count / itemsPerRow).ceil() *
(1 / ratio);
return SizedBox(
width: width,
height: calcHeight,
child: GridView.builder(
padding: const EdgeInsets.symmetric(horizontal: horizontalPadding),
itemCount: count,
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
mainAxisSpacing: 0,
crossAxisSpacing: 0,
crossAxisCount: itemsPerRow,
childAspectRatio: ratio),
itemBuilder: (context, index) {
return SizedBox(
child: Card(
clipBehavior: Clip.hardEdge,
child: Column(
children: [
Expanded(
child: Image.network(
"https://picsum.photos/200?${DateTime.now().millisecondsSinceEpoch.toString()}")),
const Padding(
padding: EdgeInsets.symmetric(horizontal: 4.0),
child: Text(
"Lorem Ipsum is a dummy text, lorem ipsum",
maxLines: 3,
overflow: TextOverflow.ellipsis,
style:
TextStyle(fontSize: 10, fontWeight: FontWeight.bold),
textAlign: TextAlign.start,
),
),
],
),
),
);
},
),
);
}
}
链接到 Dart 要点 - https://dartpad.dev/?id=05ba8804b19a2978a087c68622000a01
说明
count
是项目总数或itemCount
.itemsPerRow
是连续的项目数或 crossAxisCount
.ratio
是 childAspectRatio
的 GridView
属性,通常用于设置网格内项目的大小。 ratio
计算为宽度/高度。horizontalPadding
是给GridView
的水平填充(在垂直列表的情况下)calcHeight
是 SizedBox
的计算高度,因此您不需要在动态列表的情况下给出固定高度。