Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/dart/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Flutter 状态更改时重置颤振自定义滚动视图_Flutter_Dart_Flutter Sliver - Fatal编程技术网

Flutter 状态更改时重置颤振自定义滚动视图

Flutter 状态更改时重置颤振自定义滚动视图,flutter,dart,flutter-sliver,Flutter,Dart,Flutter Sliver,我正在构建一个垂直滚动日历,我已经将我的日子实现为多个SliverLists,这样我就可以专注于某一天,而在过去和未来仍然有日子 问题是,当focusDate通过父级中的状态更改而更改时,列表会正确更新日期,但保持其滚动位置。例如,如果我被滚动到列表的顶部,则更改focusDatedays更新,但我仍然位于列表的顶部 我希望在focusDate更改时完全替换列表(而不仅仅是日期)。从日期选择器中拾取日期时会发生这种情况。因此,无论如何都需要获取新数据,并且可以创建一个新的CustomScroll

我正在构建一个垂直滚动日历,我已经将我的日子实现为多个
SliverList
s,这样我就可以专注于某一天,而在过去和未来仍然有日子

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

我希望在
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),
          ),
        ),
      ],
    );
  }
}
导入“包装:颤振/材料.省道”;
输入“day.dart”;
类DaysManager扩展了无状态小部件{
列出日期;
DaysManager({DateTime focusDate}){
最终日期时间开始日期=焦点日期减去(持续时间:30天);
天数=列表生成(61,(整数索引){
回归日(
日期:startDate.add(持续时间(天数:索引)),
);
});
}
@凌驾
小部件构建(构建上下文){
返回_buildScrollView();
}
CustomScrollView\u buildScrollView(){
最终焦点键=值键(“焦点”);
返回自定义滚动视图(
中心:focusKey,
条子:[
银表(
委托:SliverChildListDelegate(
days.sublist(0,31).reversed.toList(),
),
),
银表(
键:focusKey,
委托:SliverChildListDelegate(
天。子列表(31,32),
),
),
银表(
委托:SliverChildListDelegate(
天。子列表(32),
),
),
],
);
}
}

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

ScrollController有一个方法:

Future<Void> animateTo(
  double offset, {
  @required Duration duration,
  @required Curve curve,
})
未来动画( 双偏移{ @所需的持续时间, @要求的曲线, })
其中“偏移”是要设置动画的位置

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

        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,);
        }
ScrollController有一个方法:

Future<Void> animateTo(
  double offset, {
  @required Duration duration,
  @required Curve curve,
})
未来动画( 双偏移{ @所需的持续时间, @要求的曲线, })
其中“偏移”是要设置动画的位置

我看到一些引用,但我不确定控制器方法应该放在哪里。setState是从父类调用的。我正在创建列表,但是在创建和返回之间,我将在哪里调用
animateTo
?还有,为什么我不能创建一个新列表?当日子一天天过去,一个卷轴出现的时候,看起来会很糟糕。我只想让它完全重新初始化。将控制器声明为类变量,然后在CustomScrollView中通过名为“controller”的参数传递控制器。更新列表后,如果在该方法中设置state,请使用控制器对象调用animateTo方法。如果类DaysManager是无状态的,请使用该方法。我相信您正在StatefulWidget中使用它,您在其中调用set state。调用setState时,DaysManager应该使用新数据而不是旧数据重建。你能展示一些你想要达到的目标的截图吗?这是完全正确的,它会用新的数据重建。但它保持其滚动位置。就像在中一样,它正在替换数据,但没有重置滚动。我看到了一些引用,但我不确定控制器方法应该放在哪里。setState是从父类调用的。我正在创建列表,但是在创建和返回之间,我将在哪里调用
animateTo
?还有,为什么我不能创建一个新列表?当日子一天天过去,一个卷轴出现的时候,看起来会很糟糕。我只想让它完全重新初始化。将控制器声明为类变量,然后在CustomScrollView中通过名为“controller”的参数传递控制器。更新列表后,如果在该方法中设置state,请使用控制器对象调用animateTo方法。如果类DaysManager是无状态的,请使用该方法。我相信您正在StatefulWidget中使用它,您在其中调用set state。调用setState时,DaysManager应该使用新数据而不是旧数据重建。你能展示一些你想要达到的目标的截图吗?这是完全正确的,它会用新的数据重建。但它保持其滚动位置。就像在中一样,它正在替换数据,但没有重置滚动。我不需要按钮。我正在寻找一种方法,使列表在重建时将其滚动位置重置为SliverList键。@WillLuce Button仅供参考。您的视图将位于Button的位置。我不需要按钮。我正在寻找一种方法,使列表在重建时将其滚动位置重置为SliverList键。@WillLuce Button仅供参考,您的视图将位于按钮的位置。
        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,);
        }