传递 scrollController 时,CustomScrollView 滚动行为发生变化

CustomScrollView scroll behavior changes when scrollController is passed

我正在尝试自动滚动到 CustomScrollView 内的 SliverList 的末尾。 SliverList 本身没有控制器 属性 所以我必须将 ScrollController 传递给 CustomScrollView.

问题是当我将控制器传递给 CustomScrollView 时,它的行为发生了变化,它不再滚动外部列表并且不会导致 SliverAppBar 小部件折叠。我怎样才能自动滚动 SliverList 并保持 CustomScrollView 的行为像以前一样?

这是我的代码:

class _MyHomePageState extends State<MyHomePage> {
  ScrollController _scrollController = ScrollController();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text(widget.title),
        ),
        floatingActionButton: FloatingActionButton(
          onPressed: () {
            _scrollController.animateTo(
              _scrollController.position.maxScrollExtent,
              curve: Curves.easeOut,
              duration: const Duration(seconds: 1),
            );
          },
        ),
        body: NestedScrollView(
          headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
            return <Widget>[
              SliverAppBar(
                expandedHeight: 230.0,
                pinned: true,
                flexibleSpace: FlexibleSpaceBar(
                  title: Text('SliverAppBar Expand'),
                ),
              )
            ];
          },
          body: CustomScrollView(
                //When controller is passed to CustomScrollView, its behavior changes
                // controller: _scrollController,  
                slivers: [
                  //Some widgets are here
                  SliverList(
                    delegate: SliverChildBuilderDelegate(
                      (context, index) {
                        return Container(
                          height: 80,
                          color: Colors.primaries[index % Colors.primaries.length],
                          alignment: Alignment.center,
                          child: Text(
                            'Item : $index',
                          ),
                        );
                      },
                      childCount: 20,
                    ),
                  ),
                ],
              ),
            ) ,
         );
      }
    }

我想您可能会注意到这里示例的解释:NestedScrollView class

// The "controller" and "primary" members should be left
// unset, so that the NestedScrollView can control this
// inner scroll view.
// If the "controller" property is set, then this scroll
// view will not be associated with the NestedScrollView.
// The PageStorageKey should be unique to this ScrollView;
// it allows the list to remember its scroll position when
// the tab view is not on the screen.

// This Builder is needed to provide a BuildContext that is
// "inside" the NestedScrollView, so that
// sliverOverlapAbsorberHandleFor() can find the
// NestedScrollView.

正确的做法是获取CustomScrollView使用的controller,而不是自己添加一个新的controller。

可以通过在 CustomScrollView 上方添加一个 Builder 并将控制器分配给 _scrollController.

...
  body: NestedScrollView(
    ...
    body: Builder(
      builder: (context){
        _scrollController = PrimaryScrollController.of(context);
        return CustomScrollView(
          ...
      },
    ),
  ),
...