Scroll/JumpTo Flutter GridView 中的正确位置

Scroll/JumpTo Correct Position in Flutter GridView

我正在 GridView 中创建一个日历界面。我想滚动到当月的第一天。但是,每当我尝试滚动到我计算的位置时,它都是错误的。我目前正在使用 2016 年 1 月 1 日作为日历的起点。我目前为每个日历行使用固定高度,但它仍然没有滚动到正确的位置。

注意:下面的图片生成于 2019 年 10 月 11 日。我正在尝试自动滚动到 2019 年 10 月 1 日。

纵向滚动太远:

当我旋转到横向时,滚动不够:

正在创建 GridView:

  double calendarHeight = 100.0;
  ...
  @override
  Widget build(BuildContext context) {
    // Get the size of the screen
    var size = MediaQuery.of(context).size;
    var ratio = size.width / calendarHeight / 7; // Divide ratio by 7 because there are 7 columns

    Scaffold scaffold = Scaffold(
      ...
      body: new Stack(
        children: <Widget>[
          new PageView(
            children: <Widget>[
              // Calendar Page
              new Container(
                child: new Center(
                  child: GridView.builder(
                    gridDelegate: _calendarGridDelegate(ratio),
                    controller: scrollController,
                    itemCount: _calendarDates.length,
                    itemBuilder: (BuildContext context, int index) {
                      if (index < _calendarDates.length) {
                        return _calendarItemBuilder(index);
                      } else
                        return null;
                    },
                  ),
                ),
                color: Colors.blue,
              ),
              ...

    WidgetsBinding.instance.addPostFrameCallback((_) {
      double scrollTo = (dayInList ~/ 7) * calendarHeight;
      ...
      scrollController.jumpTo(scrollTo);
    });

    return scaffold;

创建网格委托:

/// Defines the [SliverGridDelegateWithFixedCrossAxisCount] grid delegate used
/// by the calendar page
SliverGridDelegateWithFixedCrossAxisCount _calendarGridDelegate(double ratio) {
  return new SliverGridDelegateWithFixedCrossAxisCount(
          childAspectRatio: ratio,
          crossAxisCount: 7,
          mainAxisSpacing: _MAIN_AXIS_SPACING, // _MAIN_AXIS_SPACING = 1.0
          crossAxisSpacing: _CROSS_AXIS_SPACING); // _CROSS_AXIS_SPACING = 1.0
}

在日历中创建一天的内容:

/// Builds a [Widget] for one calendar day in the calendar page
Widget _calendarItemBuilder(int index) {
  String output;
  if (_calendarDates[index].day == 1) {
    output = Constants().monthNames[_calendarDates[index].month - 1] +
        " " +
        _calendarDates[index].day.toString();
  } else {
    output = _calendarDates[index].day.toString();
  }

  return new Container(
    padding: EdgeInsets.all(5.0),
    child: new Center(
      child: Text(output),
    ),
  );
}

我找到了答案,但远不能令人满意,因为它没有任何意义:

double scrollTo = (dayInList ~/ 7) * (calendarHeight - (calendarHeight - size.width/6)/(size.width/6));
...
scrollController.jumpTo(scrollTo);

经过多次反复试验,但它适用于我用于测试的两台设备。

让我们使用 scroll_to_index。在 Gridview、listview 中滚动索引项目是一个很好的解决方案...