Flutter GridView计数更新给出错误的滚动位置

时间:2018-12-18 12:23:07

标签: gridview scroll dart flutter

我是Flutter的新手,正在尝试实现网格列表。

我用GridView来做到这一点。

我希望我的GridView默认在每行显示2个项目

,当用户单击AppBar上的按钮时,

我想更改我的GridView的数量

,以便每行只能显示一项。

要实现此行为,

我创建了MyApp_GridCountButtonMainList

MyApp是保存StatefulWidget的{​​{1}}。

_gridCount_GridCountButton,从StatelessWidget接收侦听器,并在按下时调用侦听器。

MyApp是保存MainList的那个。

count: 2 count: 1

如您所见,更改网格是可行的,

但是GridView的滚动位置不是我想要的。

似乎保持了滚动的绝对值。

如何保持屏幕上的第一项相同?

2 个答案:

答案 0 :(得分:0)

我大致解决了我的问题,因此在其他情况下此解决方案可能不起作用。

可能是最佳解决方案

最好的解决方案可能是使用ScrollController收听并移至使用项height计算出的特定偏移量。

要获取项目的height,我在initState()回调中找到了一种方法,但是我将列表StatelessWidget设为了{{1} }。

我做了什么

我的案子

所以我只是使用项目大小的比例来获得适当的偏移量。

就我而言,我必须每行显示1或2个项目,分别为initState()grid1

因此,我存储了grid2grid1grid2offset的偏移量。

然后offset2offset1之间的关系为offset2,因为offset1 = offset2*4只能显示1个项目,而grid1可以显示4个相同的项目空间。

为什么不只是grid2

我尝试仅使用一个offset变量来存储offset的偏移量。

调用滚动事件时,我计算出grid1始终保持offset的偏移量。

但是,没有滚动时,滚动事件不会被调用。

所以当我

  1. grid1切换到grid1
  2. 不做任何滚动,
  3. grid2切换到grid2

grid1的值保持不变,并被识别为offset的偏移量。

所以我将grid2offset1分开,以确保哪些偏移量与哪个网格相匹配。

使用offset2offset1

现在,我有了可以正确更新的正确值,现在可以设置此值以设置适当的偏移量。

当我致电offset2切换网格时,我添加了以下几行。

setState

成功了!

答案 1 :(得分:0)

请检查我对这个问题的尝试。当点击项目时,gridview 从双网格变为单网格,反之亦然。欢迎任何建议或更改。

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Flutter TabBar',
      home: new Home(),
      theme: new ThemeData(primaryColor: Colors.black),
    );
  }
}

class Home extends StatefulWidget {
  @override
  _HomeState createState() => new _HomeState();
}

class _HomeState extends State<Home> {
  ScrollController _scrollController;
  double _offset;
  double _doubleGridItemHeight = 100.0;
  double _singleGridItemHeight = 200.0;
  int _gridCount = 2;

  @override
  void initState() {
    super.initState();
    _scrollController = ScrollController()
      ..addListener(() {
        print("offset = ${_scrollController.offset}");
        setState(() {
          _offset = _scrollController.offset;
        });
      });
  }

  @override
  Widget build(BuildContext context) {
    return GridView.builder(
        controller: _scrollController,
        itemCount: 40,
        gridDelegate: new SliverGridDelegateWithFixedCrossAxisCount(
            crossAxisCount: _gridCount),
        itemBuilder: (BuildContext context, int index) {
          return new GestureDetector(
            child: Container(
              height: _gridCount == 1
                  ? _doubleGridItemHeight
                  : _singleGridItemHeight,
              child: new Card(
                elevation: 5.0,
                child: new Container(
                  alignment: Alignment.center,
                  child: new Text('Item $index'),
                ),
              ),
            ),
            onTap: () {
              setState(() {
                if (_gridCount == 2) {
                  _gridCount = 1;
                  // scrolling with animation
                  _scrollController.animateTo(
                      _offset +
                          ((index) *
                              (_doubleGridItemHeight + _singleGridItemHeight)),
                      curve: Curves.linear,
                      duration: Duration(milliseconds: 500));
                } else {
                  _gridCount = 2;
                  // scrolling without animation
                  _scrollController.jumpTo(_offset -
                      ((index) *
                          (_doubleGridItemHeight + _singleGridItemHeight)));
                }
              });
            },
          );
        });
  }
}