Flutter - 如何在导航过程中创建一个固定的AppBar最佳实践

4
在本地Android开发中,通常使用FragmentTransaction创建导航动画,在其中,actionBar的位置保持不变(但是actionBar的内容会改变),而actionBar下方的片段执行转换动画(如滑入或滑出)。
简单来说,AppBar和正文执行不同的转换动画。在Flutter中,创建这样的动画的最佳做法是什么?
目前我能想到的解决方案是在Scaffold.body中使用导航,并使用Stream + StreamBuilder来开始重新绘制AppBar。类似以下代码的方式。
Scaffold(
    appBar: StreamBuilder<Int>(
        stream: Bloc.of(context).currentFragmentId
        builder: //Some logic to decide which AppBar is appropriate
    ),
    body: Navigator(
        //Navigation between fragments
    ),
)

但这真的很奇怪。那么有没有最佳实践来做到这一点呢?请告诉我!


但是在Scaffold内部的PageView无法访问AppBar。而且PageView也不能执行hold/slide_up动画。 - First_Strike
PageView将成为脚手架的主体,因此在所有页面中保持appbar相同-至于动画方面-您可以自定义它。 - anmol.majhail
你可以使用GlobalKey来更新或刷新appbar,同时你也可以使用body来展示你的fragments。 - Massimo Caroccia
2个回答

1

好的,由于目前没有可用的答案。我将在这里分享我的解决方案,尽管它并不那么优雅。

解决方案是将AppBar包装在Hero小部件中。由于Scaffold只接受PreferredSize小部件作为应用栏,因此需要进行一些自定义。

class HeroAppBar extends StatelessWidget implements PreferredSizeWidget {
//...
  @override
  final Size preferredSize = Size.fromHeight(kToolbarHeight + (bottom?.preferredSize?.height ?? 0.0));
//...
  @override
  Widget build(BuildContext context) {
    return Hero(
      tag: tag,
      child: AppBar(
        //...
      ),
    );
  }
}

确保您的导航器实现了HeroController。(默认导航器已经实现了它)


0
也许有一个更优雅的解决方案(从代码角度而言),与@First_Strike相反:
import 'package:flutter/material.dart';

extension HeroAppBar on AppBar {
  PreferredSizeWidget toHero(Object tag) {
    return PreferredSize(
      preferredSize: preferredSize,
      child: Hero(tag: tag, child: this),
    );
  }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接