📜  如何在颤动中减去 appbar 的高度 - Dart (1)

📅  最后修改于: 2023-12-03 15:24:40.959000             🧑  作者: Mango

如何在颤动中减去 AppBar 的高度 - Dart

在开发移动应用时,我们经常会遇到需要向上滚动页面并在顶部添加 AppBar 的情况。当用户向上滚动页面时,我们希望 AppBar 消失并且页面最上方的内容完全填满屏幕。但是常常会出现问题,因为 AppBar 的高度会占据我们想要填充的空间。在本文中,我们将提供一种通过控制器在颤动中减去 AppBar 高度的可靠方法。

使用 SliverAppBar

SliverAppBar 是一个特殊的 AppBar,它可以与 CustomScrollView 一起使用。SliverAppBar 不会像普通的 AppBar 一样占据页面的空间,而是将其压缩到一个可滚动的小部件中。通过使用 SliverAppBar,我们可以轻松地在颤动中减去 AppBar 的高度。

我们创建一个新的 SliverAppBar 小部件,然后将其放置在 CustomScrollView 中:

CustomScrollView(
  controller: _scrollController,
  slivers: <Widget>[
    SliverAppBar(
      title: Text('My App'),
      pinned: true,
      expandedHeight: 200.0,
      flexibleSpace: FlexibleSpaceBar(
        background: Image.network(
          'https://example.com/image.jpg',
          fit: BoxFit.cover,
        ),
      ),
    ),
    ...
  ],
)

我们需要注意以下几点:

  • 我们将 CustomScrollViewcontroller 设置为 _scrollController,这样我们就可以在颤动时监听滚动事件。
  • 我们将 pinned 属性设置为 true,这样 SliverAppBar 将保持在屏幕的顶部。
  • 我们将 expandedHeight 属性设置为 200.0,这是 SliverAppBar 将始终保留的高度。
  • 我们使用 FlexibleSpaceBar 将一个 Image 小部件放置在 SliverAppBar 的内部部分。
监听颤动事件

接下来,我们需要监听 CustomScrollView 的滚动事件并根据需要更改顶部内容的高度。我们将使用一个 ScrollController 来监视滚动事件,并使用一个布尔值来跟踪当前是否正在颤动:

final _scrollController = ScrollController();
bool _isShrinking = false;

CustomScrollView 中,我们将使用 _scrollController 监听颤动并根据需要更改 _isShrinking 的值:

_scrollController.addListener(() {
  if (_scrollController.offset > (_scrollController.position.minScrollExtent + kToolbarHeight)) {
    if (!_isShrinking) {
      setState(() {
        _isShrinking = true;
      });
    }
  } else {
    if (_isShrinking) {
      setState(() {
        _isShrinking = false;
      });
    }
  }
});

在上述代码中,我们检查滚动位置是否超过了 CustomScrollView 的最小距离(minScrollExtent)和 AppBar 的高度(kToolbarHeight)。如果已经超过了这个位置,我们会设置 _isShrinkingtrue,这样我们就可以在稍后的步骤中调整页面的高度。

调整页面高度

最后,我们需要根据 _isShrinking 的值来调整页面的高度。我们可以通过将 SliverAppBar 的大小设置为 0.0 以实现减去 AppBar 高度的效果:

SliverAppBar(
  ...
  expandedHeight: _isShrinking ? 0.0 : 200.0,
  ...
)

在代码中,我们将 expandedHeight 的值根据 _isShrinking 的值设置为 0.0200.0。这样在向上滚动页面时,SliverAppBar 将逐渐消失并使内容完全填满屏幕。

结论

在本文中,我们学习了如何使用 SliverAppBarCustomScrollView 在颤动中减去 AppBar 的高度。通过在颤动事件中使用控制器来监视滚动并根据需要更改高度,我们成功地实现了这个效果。

(完整代码见下面)

import 'package:flutter/material.dart';

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final _scrollController = ScrollController();
  bool _isShrinking = false;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: CustomScrollView(
        controller: _scrollController,
        slivers: <Widget>[
          SliverAppBar(
            title: Text('My App'),
            pinned: true,
            expandedHeight: _isShrinking ? 0.0 : 200.0,
            flexibleSpace: FlexibleSpaceBar(
              background: Image.network(
                'https://example.com/image.jpg',
                fit: BoxFit.cover,
              ),
            ),
          ),
          SliverList(
            delegate: SliverChildBuilderDelegate(
              (BuildContext context, int index) {
                return Container(
                  padding: EdgeInsets.all(20.0),
                  child: Text('Item $index'),
                );
              },
              childCount: 100,
            ),
          ),
        ],
      ),
    );
  }

  @override
  void dispose() {
    _scrollController.dispose();
    super.dispose();
  }

  @override
  void initState() {
    super.initState();
    _scrollController.addListener(() {
      if (_scrollController.offset > (_scrollController.position.minScrollExtent + kToolbarHeight)) {
        if (!_isShrinking) {
          setState(() {
            _isShrinking = true;
          });
        }
      } else {
        if (_isShrinking) {
          setState(() {
            _isShrinking = false;
          });
        }
      }
    });
  }
}