【问题标题】:How to scroll a page, with image and gridView in flutter如何滚动页面,在颤动中使用图像和gridView
【发布时间】:2021-05-31 05:29:31
【问题描述】:

我的页面代码是这样的。我需要滚动应用栏下方的部分。

return Scaffold(
  backgroundColor: Theme.of(context).accentColor,
  appBar: AppBar(
    backgroundColor: Colors.transparent,
    elevation: 0.0,
    title: Text(campTitle,
      style: TextStyle(color: Theme.of(context).primaryColor,
        
        ),
      ),
  ),

  body: Column(children: [
            Padding(
                  padding: const EdgeInsets.only(left: 40, right: 40, top: 10),
                  child: ClipRRect(
                    borderRadius: BorderRadius.circular(28),
                    child: Image.asset('assets/images/Flyer-Kalabrien-2020.jpg',
                      //fit: BoxFit.fill
                      
                    ),
                  ),
                ),
          

               Expanded(
                 child: GridView(
                          padding: const EdgeInsets.all(25),
                  gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
                    maxCrossAxisExtent: 200,
                    childAspectRatio: 1,
                    crossAxisSpacing: 20,
                    mainAxisSpacing: 0
                    ),
                    children: [
                        CampItems(),
                        CampItems(),
                        CampItems(),
                        CampItems()

                      
                      

                    ],
                  ),
               ),
            
      ]
   ), 
  );

我需要使应用栏下方的部分可滚动。首先我有一个图像,然后在图像下方是一个 GridView。我尝试了 SingleChildScrollView 和其他小部件,但后来我只看到一个白屏,错误是:

_AssertionError._doThrowNew (dart:core-patch/errors_patch.dart:46:39)
#1      _AssertionError._throwNew (dart:core-patch/errors_patch.dart:36:5)
#2      RenderBox.size (package:flutter/src/rendering/box.dart:1785:12)
#3      RenderProxyBoxWithHitTestBehavior.hitTest (package:flutter/src/rendering/proxy_box.dart:168:9)
#4      RenderBoxContainerDefaultsMixin.defaultHitTestChildren.<anonymous closure> (package:flutter/src/rendering/box.dart:2596:25)
#5      BoxHitTestResult.addWithPaintOffset (package:flutter/src/rendering/box.dart:787:31)
#6      RenderBoxContainerDefaultsMixin.defaultHitTestChildren (package:flutter/src/rendering/box.dart:2591:33)
#7      RenderCustomMultiChildLayoutBox.hitTestChildren (package:flutter/src/rendering/custom_layout.dart:412:12)
#8      Rend<…>

【问题讨论】:

  • 看我的回答,有什么问题请告诉我!
  • 使用 ListView 代替 Column 作为脚手架的主体,这样可以帮助你滚动。

标签: flutter dart flutter-layout scrollview scrollable


【解决方案1】:

使用以下代码并进行相应替换:

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp 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(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('campTitle'),
      ),
      body: Column(mainAxisSize: MainAxisSize.min, children: [
        Padding(
          padding: const EdgeInsets.only(left: 40, right: 40, top: 10),
          child: ClipRRect(
            borderRadius: BorderRadius.circular(28),
            child: Placeholder(fallbackHeight: 100, fallbackWidth: 100),
          ),
        ),
        Flexible( // important to make it work
            child: GridView(
                physics: ScrollPhysics(), // also important to make your gridview scrollable
                shrinkWrap: true,
                padding: const EdgeInsets.all(25),
                gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
                    maxCrossAxisExtent: 200,
                    childAspectRatio: 1,
                    crossAxisSpacing: 20,
                    mainAxisSpacing: 0),
                children: [
              for (int i = 0; i < 30; i++) // i is the number of your CampItems()
                Placeholder(fallbackHeight: 30, fallbackWidth: 30), // replace with CampItems()

            ])),
      ]),
    );
  }
}

有关 GridView 属性的完整列表,请参阅documentation

物理 → ScrollPhysics 滚动视图应如何响应用户输入。 [...]

shrinkWrap → bool scrollDirection 中滚动视图的范围是否应由正在查看的内容决定。 [...]


您可能还想了解 FlexibleExpanded

关于灵活:

使用 Flexible 小部件可以让 Row、Column 或 Flex 的子级灵活地展开以填充主轴上的可用空间(例如,水平地用于行或垂直地用于列),但与展开不同的是,灵活不需要孩子填满可用空间。


另外最好用SafeArea包裹脚手架

通过足够的填充插入其子级的小部件以避免操作系统的入侵。

【讨论】:

    【解决方案2】:
    • SingleChildScrollView 包裹Column
    • 在列中,设置mainAxisSize: MainAxisSize.min
    • 删除Expanded 小部件
    • GridView 属性中,设置physics: NeverScrollableScrollPhysics()

    代码:

    class Home extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text('campTitle'),
          ),
          body: SingleChildScrollView(
            child: Column(mainAxisSize: MainAxisSize.min, children: [
              Padding(
                padding: const EdgeInsets.only(left: 40, right: 40, top: 10),
                child: ClipRRect(
                  borderRadius: BorderRadius.circular(28),
                  child: Placeholder(fallbackHeight: 100, fallbackWidth: 100),
                ),
              ),
              GridView(
                physics: NeverScrollableScrollPhysics(),
                shrinkWrap: true,
                padding: const EdgeInsets.all(25),
                gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
                    maxCrossAxisExtent: 200,
                    childAspectRatio: 1,
                    crossAxisSpacing: 20,
                    mainAxisSpacing: 0),
                children: [
                  Placeholder(fallbackHeight: 30, fallbackWidth: 30),
                  Placeholder(fallbackHeight: 30, fallbackWidth: 30),
                  Placeholder(fallbackHeight: 30, fallbackWidth: 30),
                  Placeholder(fallbackHeight: 30, fallbackWidth: 30),
                  Placeholder(fallbackHeight: 30, fallbackWidth: 30),
                  Placeholder(fallbackHeight: 30, fallbackWidth: 30),
                  Placeholder(fallbackHeight: 30, fallbackWidth: 30),
                  Placeholder(fallbackHeight: 30, fallbackWidth: 30),
                  Placeholder(fallbackHeight: 30, fallbackWidth: 30),
                  Placeholder(fallbackHeight: 30, fallbackWidth: 30),
                ],
              ),
            ]),
          ),
        );
      }
    

    【讨论】:

    • GridView 是可滚动的。我看不到将它包装在 SingleChildScrollView 中的意义?!
    • @YoBo 正确。实际上,它先用Column 包装,然后再用SingleChildScrollView 包装。我们用SingleChildScrollView 包装以允许其子级变得可滚动(不仅是GridView
    【解决方案3】:

    去掉展开,试试shrinkWrap: true, 物理:ScrollPhysics(),

    【讨论】:

      猜你喜欢
      • 2019-01-16
      • 2019-05-15
      • 2022-12-31
      • 2019-07-01
      • 2020-08-22
      • 1970-01-01
      • 2021-06-24
      • 1970-01-01
      • 2021-02-23
      相关资源
      最近更新 更多