flutter - 在Flutter中,如何创建一个带有毛玻璃效果的SliverAppBar?

标签 flutter flutter-sliver

我想创建一个类似于 Apple News 应用程序中的顶部应用程序栏。

在屏幕截图中看模糊有点困难,因为条太细了,但你明白了。

screenshot

我希望栏通过滚动来扩展和收缩,并在收缩时固定在顶部,就像在屏幕截图中一样,SliverAppBar 完成了所有这些,只是我不能将它包裹在 ClipRect、BackdropFilter 和 Opacity 中来创建毛玻璃效果,因为 CustomScrollView 只接受 RenderSliv​​er 子类。

我的测试代码:

Widget build(BuildContext context) {
  return CustomScrollView(
    slivers: <Widget>[
      SliverAppBar(
        title: Text('SliverAppBar'),
        elevation: 0,
        floating: true,
        pinned: true,
        backgroundColor: Colors.grey[50],
        expandedHeight: 200.0,
        flexibleSpace: FlexibleSpaceBar(
            background: Image.network("https://i.imgur.com/cFzxleh.jpg", fit: BoxFit.cover)
        ),
      )
      ,
      SliverFixedExtentList(
        itemExtent: 150.0,
        delegate: SliverChildListDelegate(
          [
            Container(color: Colors.red),
            Container(color: Colors.purple),
            Container(color: Colors.green),
            Container(color: Colors.orange),
            Container(color: Colors.yellow),
            Container(color: Colors.pink,
              child: Image.network("https://i.imgur.com/cFzxleh.jpg", fit: BoxFit.cover)
            ),
          ],
        ),
      ),
    ],
  );
}

有没有办法实现我想要的?

最佳答案

我设法通过将 AppBar 包装在 SliverPersistentHeader 中使其工作(这基本上就是 SliverAppBar 所做的)。

in action 忽略未模糊的边缘,这是一个 iOS 模拟器错误。

这是概念验证代码示例:

class TranslucentSliverAppBar extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return SliverPersistentHeader(
        floating: true,
        pinned: true,
        delegate: _TranslucentSliverAppBarDelegate(
            MediaQuery.of(context).padding,
        )
    );
  }
}

class _TranslucentSliverAppBarDelegate extends SliverPersistentHeaderDelegate {

  /// This is required to calculate the height of the bar
  final EdgeInsets safeAreaPadding;

  _TranslucentSliverAppBarDelegate(this.safeAreaPadding);

  @override
  double get minExtent => safeAreaPadding.top;

  @override
  double get maxExtent => minExtent + kToolbarHeight;

  @override
  Widget build(BuildContext context, double shrinkOffset, bool overlapsContent) {
    return ClipRect(child: BackdropFilter(
      filter: ImageFilter.blur(sigmaX: 16, sigmaY: 16),
      child: Opacity(
          opacity: 0.93,
          child: Container(
              // Don't wrap this in any SafeArea widgets, use padding instead
              padding: EdgeInsets.only(top: safeAreaPadding.top),
              height: maxExtent,
              color: Colors.white,
              // Use Stack and Positioned to create the toolbar slide up effect when scrolled up
              child: Stack(
                  overflow: Overflow.clip,
                  children: <Widget>[
                    Positioned(
                      bottom: 0, left: 0, right: 0,
                      child: AppBar(
                          primary: false,
                          elevation: 0,
                          backgroundColor: Colors.transparent,
                          title: Text("Translucent App Bar"),
                      ),
                    )
                  ],
              )
          )
      )
    ));
  }

  @override
  bool shouldRebuild(_TranslucentSliverAppBarDelegate old) {
    return maxExtent != old.maxExtent || minExtent != old.minExtent ||
        safeAreaPadding != old.safeAreaPadding;
  }
}

关于flutter - 在Flutter中,如何创建一个带有毛玻璃效果的SliverAppBar?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57635895/

相关文章:

javascript - 类型错误 : Cannot read property 'instanceIdentifier' of undefined (FirebaseStorage)

flutter - SliverChildBuilderDelegate 使用 setState 更改数据时不重建其子级

flutter - 如何在 statefulWidget 中使用 flutter provider?

flutter - Dart 使用 json_serializable 解析到/从 json 库类

list - dart - 如果包含在列表中,如何检查 id/name?

mobile - 滚动时如何从 SliverAppBar 淡入/淡出小部件?

flutter - SliverAppBar 不在 AppBar 中淡入淡出

flutter - 如何在 flutter 中使用嵌套的 WillPopScope

flutter - CustomScrollView 内的固定 SliverPersistentHeader 滚动到 NestedScrollView 内另一个固定的 SliverPersistentHeader 后面

dart - Flutter:折叠 FlexibleSpaceBar 时更改文本