如何在Flutter中使用SingleChildScrollView和GridView实现连续滚动

sr4lhrrt  于 2023-05-08  发布在  Flutter
关注(0)|答案(3)|浏览(259)

我目前有一个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(),
      ],
    ),
  ),
);
x8diyxa7

x8diyxa71#

在你的GridView中,像这样设置物理学,你可以开始了:

physics: NeverScrollableScrollPhysics()

编辑:

这样做可能是资源密集型的,因为它在一次运行中生成所有项目,而不是在滚动时膨胀/生成项目,因此请确保您的网格或列表中没有大量数据。

5t7ly7z5

5t7ly7z52#

您应该使用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),
    )
  ],
),
9ceoxa92

9ceoxa923#

我在这里回答了一个类似的问题:https://stackoverflow.com/a/76192690/11976596
你可以在下面找到相同的-
我有一个类似的问题,我有一个GridView.builder在一个SingleChildScrollView。现在的问题是,你不能在SingleChildScrollView内部创建一个GridView,因为两者都会试图占用尽可能多的可用空间,这使得高度无限/无限。
所以解决方案是用SizedBox Package GridView,我总是喜欢使用GridView.Builder
现在实际的问题是,“当列表是动态的时,我如何知道SizedBox的大小?“
因此,我编写了这段代码,其中包含根据GridViewchildAspectRatio属性动态计算SizedBox高度的逻辑

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
  • ratioGridViewchildAspectRatio属性,通常用于设置网格内项目的大小。ratio计算为宽度/高度。
  • horizontalPadding是给GridView的水平填充(在垂直列表的情况下)
  • calcHeightSizedBox的计算高度,这样在动态列表的情况下就不需要给予固定的高度。

相关问题