在状态更改时重置Flutter CustomScrollView

时间:2019-05-28 04:34:54

标签: flutter dart flutter-sliver

我正在构建一个垂直滚动的日历,并且已将我的日子实现为多个SliverList,以便我可以集中精力进行某天的初始化,而仍然保留过去和将来的日子。

问题是,当focusDate通过父项的状态更改而发生更改时,列表会正确更新日期,但会保持其滚动位置。例如,如果我滚动到列表的顶部,则更改focusDate的天数更新,但是我仍然位于列表的顶部。

我希望在focusDate更改时完全替换列表(不仅仅是日期)。从日期选择器中选择日期时,会发生这种情况。因此,无论如何都需要获取新数据,并且可以创建新的CustomScrollView并将其重点放在正确的日期。

import 'package:flutter/material.dart';

import 'day.dart';

class DaysManager extends StatelessWidget {
  List<Day> days;

  DaysManager({DateTime focusDate}) {
    final DateTime startDate = focusDate.subtract(Duration(days: 30));
    days = List.generate(61, (int index) {
      return Day(
        date: startDate.add(Duration(days: index)),
      );
    });
  }

  @override
  Widget build(BuildContext context) {
    return _buildScrollView();
  }

  CustomScrollView _buildScrollView() {
    final focusKey = ValueKey('focus');

    return CustomScrollView(
      center: focusKey,
      slivers: <Widget>[
        SliverList(
          delegate: SliverChildListDelegate(
            days.sublist(0, 31).reversed.toList(),
          ),
        ),
        SliverList(
          key: focusKey,
          delegate: SliverChildListDelegate(
            days.sublist(31, 32),
          ),
        ),
        SliverList(
          delegate: SliverChildListDelegate(
            days.sublist(32),
          ),
        ),
      ],
    );
  }
}

2 个答案:

答案 0 :(得分:0)

您可以将ScrollController添加到CustomListView。设置状态时,请使用控制器将动画设置为刚选择的位置。

ScrollController有一个方法:

Future<Void> animateTo(
  double offset, {
  @required Duration duration,
  @required Curve curve,
})

偏移量是要设置动画的位置。

答案 1 :(得分:-1)

        ScrollController _scrollController;
        @override
        void initState() {
          super.initState();
          _scrollController = new ScrollController();
        }

        @override
        Widget build(BuildContext context) {
          return ListView.builder(itemBuilder: (context, index){
            return FlatButton(onPressed: (){
              _scrollController.animateTo(index*(YOUR_VIEW_HEIGHT), duration: new Duration(seconds: 2), curve: Curves.ease);
            }, child: Text("Item   $index"));
          }, controller: _scrollController,);
        }