如何检测 SliverAppBar 是否被固定

How to detect SliverAppBar is pinned

我对我的申请很满意。 我想做的是当 SliverAppBar 完全向上滚动时,我想在其中显示一个不同的小部件。

任何人都可以提供一些帮助吗?

我知道使用 SliverPersistentHeader 可以完成类似的事情。但是有没有办法根据 header 的位置来显示和隐藏它?

class SliversBasicPage extends StatelessWidget {
  _isPinned() {
    return false;
  }
  @override
  Widget build(BuildContext context) {
    return CustomScrollView(
      slivers: <Widget>[
        SliverAppBar(
          pinned: true,
          floating: false,
          expandedHeight: 120.0,
          flexibleSpace: FlexibleSpaceBar(
            title: _isPinned() ? Text('PINNED') : Text('NOT PINNED'),
          ),
        ),
        SliverFixedExtentList(
          itemExtent: 50,
          delegate: SliverChildListDelegate([
            Container(color: Colors.red),
            Container(color: Colors.green),
            Container(color: Colors.blue),
          ]),
        ),
      ],
    );
  }
}

您需要做几件事。首先,您需要一个有状态的小部件,以便您可以更改固定标志的状态并进行 UI 重建。其次,您需要一个 ScrollController 来侦听滚动状态,并根据应用栏的 collapsed/non-collapsed 状态切换值为 isPinned

控制器可能看起来像这样:

final ScrollController _sliverScrollController = ScrollController();
  var isPinned = false;

.....

  @override
  void initState() {
    super.initState();

    _sliverScrollController.addListener(() {
      if (!isPinned &&
          _sliverScrollController.hasClients &&
          _sliverScrollController.offset > kToolbarHeight) {
        setState(() {
          isPinned = true;
        });
      } else if (isPinned &&
          _sliverScrollController.hasClients &&
          _sliverScrollController.offset < kToolbarHeight) {
        setState(() {
          isPinned = false;
        });
      }
    });
  }

.....

将此控制器添加到 CustomScrollView 的控制器参数中。