如何以编程方式折叠或展开 SliverPresistentHeader [自定义浮动应用栏]
Posted
技术标签:
【中文标题】如何以编程方式折叠或展开 SliverPresistentHeader [自定义浮动应用栏]【英文标题】:How to programmatically Collapse or Expand SliverPresistentHeader [custom floating app bar] 【发布时间】:2021-03-11 13:36:56 【问题描述】:我正在尝试使用来自shrinkOffset
值的引用以编程方式折叠 或展开 SliverPresistantHeader。我到处寻找如何实现此功能,但找不到任何解决方案(所以我在这里问)。
这是我的自定义代码 SliverPresistantHeaderDelegate:
import 'package:bom/constants/constants.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
class BomAppHeader implements SliverPersistentHeaderDelegate
BomAppHeader(
this.expandedHeight,
this.title,
this.body,
@required this.notificationShade,
);
final double notificationShade;
final double expandedHeight;
final Widget title;
final Widget body;
@override
double get maxExtent
if (expandedHeight == null || expandedHeight < kToolbarHeight)
return minExtent;
else
return notificationShade + expandedHeight;
@override
double get minExtent
return title == null
? notificationShade
: notificationShade + kToolbarHeight;
double bodyOpacity(double shrinkOffset)
return max(0.0, 1 - (shrinkOffset / (maxExtent - minExtent)));
@override
Widget build(
BuildContext context, double shrinkOffset, bool overlapsContent)
// print(max(0.0, 1 - (shrinkOffset / (maxExtent - minExtent))));
return Stack(
fit: StackFit.expand,
children: [
Container(
decoration: kAppBarDecoration,
),
Opacity(
opacity: bodyOpacity(shrinkOffset),
child: Container(
height: maxExtent > minExtent ? double.infinity : 0.0,
margin: title == null
? EdgeInsets.only(top: notificationShade + 2)
: EdgeInsets.only(
top: notificationShade, bottom: kToolbarHeight),
padding: EdgeInsets.all(8.0),
child: body,
),
),
Column(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
SizedBox(
height: notificationShade,
),
Container(
height: title == null ? 0.0 : kToolbarHeight,
padding: EdgeInsets.all(5.0),
child: title,
),
]),
],
);
double titleOpacity(double shrinkOffset)
// simple formula: fade out text as soon as shrinkOffset > 0
return 1.0 - max(0.0, shrinkOffset) / maxExtent;
// more complex formula: starts fading out text when shrinkOffset > minExtent
//return 1.0 - max(0.0, (shrinkOffset - minExtent)) / (maxExtent - minExtent);
@override
bool shouldRebuild(covariant SliverPersistentHeaderDelegate oldDelegate)
return true;
@override
// TODO: implement showOnScreenConfiguration
PersistentHeaderShowOnScreenConfiguration get showOnScreenConfiguration =>
null;
@override
// TODO: implement snapConfiguration
FloatingHeaderSnapConfiguration get snapConfiguration => null;
@override
// TODO: implement stretchConfiguration
OverScrollHeaderStretchConfiguration get stretchConfiguration => null;
@override
// TODO: implement vsync
TickerProvider get vsync => null;
到目前为止,我还没有找到任何解决方案来实现这一点,仍在网上冲浪。
【问题讨论】:
【参考方案1】:由于 Flutter 是开源的,我们可以访问它们的内置代码(我最近深入研究了每个小部件代码以了解每件事情的工作原理 ;-)),我发现 snap
功能是我最喜欢的功能我正在从颤振文档中寻找。所以我研究了SliverAppBar
以及 snap 是如何在其中实现的。刚刚复制了我需要的东西,现在一切都按预期工作了。
[如果有人需要我的代码,请告诉我。我想没有人对此问题感兴趣或调查过,哈哈,最好说,我的问题是个垃圾问题]
【讨论】:
一点也不,没有愚蠢的问题,我会对你的所作所为和从中取得的成果感兴趣【参考方案2】:将滚动控制器添加到您的“自定义滚动视图”
ScrollController _scrollController;
Widget build(BuildContext context)
_scrollController = ScrollController();
return Scaffold(
body: CustomScrollView( shrinkWrap: true, controller: _scrollController,
physics: BouncingScrollPhysics(),
slivers: <Widget>[
SliverAppBar(
pinned: false,
:
:
:
onPressed: () // Scroll to top when on click => Expand
_scrollController.animateTo(
_scrollController.position.minScrollExtent,
duration:Duration(milliseconds:1300),
curve: Curves.decelerate,);
,
onPressed: () // Scroll to bottom when on click => Collapse
scrollController.animateTo(
scrollController.position.maxScrollExtent,
duration: Duration(milliseconds: 1300),
curve: Curves.decelerate,
);
,
【讨论】:
以上是关于如何以编程方式折叠或展开 SliverPresistentHeader [自定义浮动应用栏]的主要内容,如果未能解决你的问题,请参考以下文章
我可以在 Visual Studio 2012 中以编程方式折叠/展开某个名称的所有预处理器块吗?
Swft3 (RxSwift, RxCocoa) - TableView 使用响应式编程展开和折叠概念
winform, ListView Groups 下面的项目如何实现折叠,展开(默认都是展开) 类似treeview的效果