折叠时从中心向左颤动条子标题

Flutter sliver title from center to left when collapsing

我的目标是遵循我的设计(灵感来自三星天气),但是当您刚开始学习时,实现代码很困难。展开时标题应居中,折叠时标题应位于左上角。

到目前为止,这是我的代码和我目前的进度。棘手的部分是将标题移动到中心。

      Scaffold(
        backgroundColor: Colors.transparent,
        body: CustomScrollView(
          slivers: [
            SliverAppBar(
              actions: <Widget>[
                IconButton(
                  icon: const Icon(Icons.search),
                  onPressed: () {},
                ),
              ],
              pinned: _pinned,
              snap: _snap,
              floating: _floating,
              expandedHeight: 160,
              backgroundColor: Colors.transparent,
              elevation: 0.0,
              flexibleSpace: FlexibleSpaceBar(
                titlePadding: EdgeInsets.all(18),
                // centerTitle: true,
                title: Text('Panahon'),
              ),
            ),
            SliverToBoxAdapter(
                child: SizedBox(
              height: 800,
              child: Card(),
            ))
          ],
        ),
      ),

编辑:应用程序会根据时间动态更改主题。

您可以使用 SliverPersistentHeaderDelegate 创建自定义的银色应用栏,您将获得 shrinkOffset 可用于为应用栏元素设置动画。

运行 在 dartPad

用这个

替换你的SliverAppBar
SliverPersistentHeader(
  pinned: true,
  delegate: MySliverHeaderDelegate(onActionTap: () {
    debugPrint("on Tap");
  }),
),

和自定义SliverHeaderDelegate

class MySliverHeaderDelegate extends SliverPersistentHeaderDelegate {
  final double _maxExtent = 160;
  final VoidCallback onActionTap;

  MySliverHeaderDelegate({
    required this.onActionTap,
  });
  @override
  Widget build(
      BuildContext context, double shrinkOffset, bool overlapsContent) {
    debugPrint(shrinkOffset.toString());
    return Container(
      color: Colors.cyanAccent,
      child: Stack(
        children: [
          Align(
            alignment: Alignment(
                //little padding
                -(shrinkOffset > _maxExtent - 20
                        ? _maxExtent - 20
                        : shrinkOffset) /
                    _maxExtent,
                0),
            child: const Text('Panahon'),
          ),

          // here provide actions
          Positioned(
            top: 0,
            right: 0,
            child: IconButton(
              icon: const Icon(Icons.search),
              onPressed: onActionTap,
            ),
          ),
        ],
      ),
    );
  }

  @override
  double get maxExtent => _maxExtent;

  @override
  double get minExtent => kToolbarHeight;

  @override
  bool shouldRebuild(covariant MySliverHeaderDelegate oldDelegate) {
    return oldDelegate != this;
  }
}