flutter - Flutter中各种小部件的滚动问题

标签 flutter dart

我正在尝试制作一个特定的 View ,其中我在屏幕上有超过 1 个“大”小部件。这个想法是同时显示一个 GridView(shrinkwrapped),最多包含 4 张关闭事件卡,以及一个 ListView(也是 shrinkwrapped),最多可以容纳几十个乐队。
这两件事都可以在单独的 View 上,但在主视图中显示这些短网格 + 列表是必需的。它看起来也更好,IMO。但是 Flutter 给我带来了滚动问题。
看看它目前的样子:
enter image description here
至于现在,我能够同时显示 GridView 和 ListView,但滚动效果非常非常糟糕。就目前而言,这两个小部件都包装在一个 SingleChildScrollView 中,我想这不是一个好的解决方案,因为它没有一个 child 。如果我将手指放在该父小部件的一部分(就像标题或黑色背景)中,它能够工作,但如果我将它放在任何小部件(gridview 或 scrollview)上,它就不能工作。
我的目标是将滚动功能委托(delegate)给父小部件,因此无论我 Handlebars 指放在哪里,我都可以滚动整个 View ,而不仅仅是滚动一个 subview ,就像目前发生的那样。
这是我的主页代码:

return Scaffold(
        appBar: AppBar(
          // Here we take the value from the MyHomePage object that was created by
          // the App.build method, and use it to set our appbar title.
          title: Text(widget.title),
          backgroundColor: Colors.indigo,
        ),
        body: SingleChildScrollView(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.start,
            children: <Widget>[
              Padding(padding: EdgeInsets.only(top: 30)),
              Text(
                '¡Bienvenido a Sonorio!',
                style: TextStyle(fontSize: 24),
              ),
              Padding(padding: EdgeInsets.only(top: 25)),
              EventsList(key: new Key('test')),
              ListView(
                shrinkWrap: true,
                padding: const EdgeInsets.all(8),
                children: <Widget>[
                  Container(
                    height: 100,
                    color: Colors.amber[600],
                    child: const Center(child: Text('Entry A')),
                  ),
                  Container(
                    height: 50,
                    color: Colors.amber[500],
                    child: const Center(child: Text('Entry B')),
                  ),
                  Container(
                    height: 50,
                    color: Colors.amber[100],
                    child: const Center(child: Text('Entry C')),
                  ),
                ],
              )
            ],
          ),
        ));
EventsList 小部件只是一个具有 shrinkWrap 的 GridView:
  Widget build(BuildContext context) {
    return FutureBuilder<List<Event>>(
        future: new EventsService().getEventsForCoords(),
        builder: (context, AsyncSnapshot<List<Event>> snapshot) {
          if (snapshot.hasData) {
            return Column(children: [
              Text('Eventos musicales en tu zona: ',
                  style: TextStyle(
                      shadows: [
                        Shadow(
                            blurRadius: 2,
                            color: Colors.indigo[300],
                            offset: Offset.fromDirection(1, 1))
                      ],
                      fontSize: 18,
                      fontFamily: "Roboto",
                      color: Colors.indigo[200],
                      fontWeight: FontWeight.bold)),
              Padding(padding: EdgeInsets.only(bottom: 8)),
              GridView.count(
                  crossAxisCount: 2,
                  shrinkWrap: true,
                  children: generateProximityEventCards(snapshot.data)),
            ]);
          } else {
            return CircularProgressIndicator();
          }
        });
  }
我怎样才能让这个工作,或者至少将子小部件滚动功能委托(delegate)给父级?
谢谢!

最佳答案

根据我看到的要求,您不希望子滚动,否则您只希望滚动发生在布局上,即 ParentWidget
在查看您的代码后,我建议进行某些更改:

  • 使用Column()代替ListView()
  • 使用NeverScrollableScrollPhysics class ,它会禁用 Widget 的滚动

  • 有一些东西,我在代码里改了,看结果,再修改。
  • 您的 GridView使用我的假人 Container()小部件代替您的小部件 generateProximityEventCards(snapshot.data))
  • 没有使用 FutureBuilder ,因为,我使用的是静态数据。所以,就用了Column()部分向您展示最终结果

  • 让我们直接跳入代码
    class _MyHomePageState extends State<MyHomePage> {
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text(widget.title),
          ),
          body: SingleChildScrollView(
              child: Column(
                mainAxisAlignment: MainAxisAlignment.start,
                children: <Widget>[
                  Padding(padding: EdgeInsets.only(top: 30)),
                  Text(
                    '¡Bienvenido a Sonorio!',
                    style: TextStyle(fontSize: 24),
                  ),
                  Padding(padding: EdgeInsets.only(top: 25)),
                  EventsList(),
                  // Used column with padding for ListView
                  Padding(
                    padding: EdgeInsets.all(8.0),
                    child: Column(
                      children: <Widget>[
                        Container(
                          height: 100,
                          color: Colors.amber[600],
                          child: const Center(child: Text('Entry A')),
                        ),
                        Container(
                          height: 50,
                          color: Colors.amber[500],
                          child: const Center(child: Text('Entry B')),
                        ),
                        Container(
                          height: 50,
                          color: Colors.amber[100],
                          child: const Center(child: Text('Entry C')),
                        ),
                      ],
                    )
                  )
                ]
              )
            )
        );
      }
    }
    
    // cusomt eventlist widget, you can make the changes eventually
    class EventsList extends StatelessWidget{
      Widget get myWidget => Container(
        height: 50.0,
        width: 50.0,
        margin: EdgeInsets.only(right: 18.0, left: 18.0, bottom: 18.0),
        decoration: BoxDecoration(
          color: Colors.greenAccent,
          borderRadius: BorderRadius.circular(12.0)
        )
      );
      
      Widget build(BuildContext context) {
        return Column(children: [
          Text('Eventos musicales en tu zona: ',
              style: TextStyle(
                  shadows: [
                    Shadow(
                        blurRadius: 2,
                        color: Colors.indigo[300],
                        offset: Offset.fromDirection(1, 1))
                  ],
                  fontSize: 18,
                  fontFamily: "Roboto",
                  color: Colors.indigo[200],
                  fontWeight: FontWeight.bold)),
          Padding(padding: EdgeInsets.only(bottom: 8)),
          GridView.count(
              crossAxisCount: 2,
              shrinkWrap: true,
              physics: NeverScrollableScrollPhysics(), //diables the scrolling
              children: [
                // my widget which I created
                myWidget,
                myWidget,
                myWidget,
                myWidget
              ]
          ),
        ]);
      }
    }
    
    结果
    End Reuslt Gif

    关于flutter - Flutter中各种小部件的滚动问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63189679/

    相关文章:

    flutter - 返回类型 'FutureOr<Database>' 是 Fl​​utter 中潜在的不可空类型

    android - 示例 Hello world flutter 应用程序构建失败 : Execution failed for task ':app:mergeDebugResources'

    flutter - Flutter如何动态获取页面和Listview.Builder的高度?

    dart - 有没有办法在Dart中捕获JavaScript异常?

    debugging - Flutter 应用程序不会在 VScode 中调试

    带有本地通知和警报的 Flutter- FCM

    flutter - Flutter中的dio软件包是否使用隔离来解码json?

    firebase - 尝试从Firestore获取数据时出错

    dart - 你如何在 Dart 中将变量传递给 main?

    dart - Dart,noSuchMethod如何与mixins一起使用?