首页 > 解决方案 > 滚动/跳转到 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),
    ),
  );
}

标签: flutterflutter-layoutflutter-sliverflutter-gridview

解决方案


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

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

这需要大量的试验和错误,但它适用于我用于测试的两台设备。


推荐阅读