如何在 Flutter 中自定义 SliverAppBar 中的 flexibleSpace 属性?

Ayu*_*har 5 dart flutter

我想使用自定义小部件树,而不是在 SliverAppBar 的 flexibleSpace 属性中使用 FlexibleSpaceBar,在展开时,但在滚动时,我想显示自定义文本,而不是小部件树。

我创建了一个自定义小部件树,该树应分配给 flexibleSpace 属性,但我不知道如何在滚动时显示自定义文本,并隐藏小部件树。

SliverAppBar(
          expandedHeight: 180.0,
          backgroundColor: const Color(0xFF9e0118),
          iconTheme: IconThemeData(color: Colors.white),
          floating: true,
          pinned: true,
          flexibleSpace: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            crossAxisAlignment: CrossAxisAlignment.center,
            children: <Widget>[
              Container(
                  margin: EdgeInsets.only(top: 16.0),
                  padding: EdgeInsets.only(left: 32.0, right: 32.0),
                  child: Text(
                    'Some text',
                    textAlign: TextAlign.center,
                    style: TextStyle(
                        color: Colors.white,
                        fontFamily: 'PlayfairDisplay',
                        fontStyle: FontStyle.italic,
                        fontSize: 16.0),
                  )),
              Container(
                  margin: EdgeInsets.only(top: 16.0),
                  padding: EdgeInsets.only(left: 32.0, right: 32.0),
                  child: Text(
                    'some text',
                    textAlign: TextAlign.center,
                    style: TextStyle(
                        color: Colors.white,
                        fontFamily: 'PlayfairDisplay',
                        fontSize: 16.0),
                  )),
            ],
          ),
        ),
Run Code Online (Sandbox Code Playgroud)

wes*_*tdb 11

您可能希望将小部件树包装在小FlexibleSpaceBar部件中,并将小部件树添加为背景。我希望我理解你的问题。检查这个 gif

SliverAppBar(
      expandedHeight: 180.0,
      backgroundColor: const Color(0xFF9e0118),
      iconTheme: IconThemeData(color: Colors.white),
      floating: true,
      pinned: true,
      flexibleSpace: FlexibleSpaceBar(
        collapseMode: CollapseMode.pin,
        centerTitle: true,
        background: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: <Widget>[
            Container(
                margin: EdgeInsets.only(top: 16.0),
                padding: EdgeInsets.only(left: 32.0, right: 32.0),
                child: Text(
                  'Some text',
                  textAlign: TextAlign.center,
                  style: TextStyle(
                      color: Colors.white,
                      fontFamily: 'PlayfairDisplay',
                      fontStyle: FontStyle.italic,
                      fontSize: 16.0),
                )),
            Container(
                margin: EdgeInsets.only(top: 16.0),
                padding: EdgeInsets.only(left: 32.0, right: 32.0),
                child: Text(
                  'some text',
                  textAlign: TextAlign.center,
                  style: TextStyle(
                      color: Colors.white,
                      fontFamily: 'PlayfairDisplay',
                      fontSize: 16.0),
                )),
          ],
        ),
      ),
    ),
Run Code Online (Sandbox Code Playgroud)


Mig*_*alv 5

要完成@westdabestdb 的回答,让标题出现在滚动条上,这真的很简单。

您只需要添加您选择的 Animated Widget 并使用滚动控制器中的 addListener 来切换布尔值。要查找更多动画小部件,请访问 Flutter 动画小部件的官方文档:https : //flutter.dev/docs/development/ui/widgets/animation

这是一个带有 AnimatedOpacity 小部件和视差折叠模式的示例,在我看来它们可以很好地协同工作。

class YourPage extends StatelessWidget {
  const YourPage({Key key}) : super(key: key);

  ScrollController _scrollController;
  bool _isScrolled = false;

  @override
  void initState() { 
    _scrollController = ScrollController();
    _scrollController.addListener(_listenToScrollChange);
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
        body: CustomScrollView(
          controller: _scrollController,
          slivers: <Widget>[
            SliverAppBar(
              expandedHeight: 144.0,
              pinned: true,
              forceElevated: true,
              ////////////////////////////////////
              // HERE IS THE PART TO BE ADDED
              title: AnimatedOpacity(
                duration: Duration(milliseconds: 300),
                opacity: _isScrolled ? 1.0 : 0.0,
                curve: Curves.ease,
                child: Text("YOUR TITLE HERE"),
              ),
              ////////////////////////////////////
              flexibleSpace: FlexibleSpaceBar(
                titlePadding: const EdgeInsets.only(bottom: 8.0),
                centerTitle: true,
                collapseMode: CollapseMode.parallax,
                background: Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  crossAxisAlignment: CrossAxisAlignment.center,
                  children: <Widget>[
                    Container(
                        margin: EdgeInsets.only(top: 16.0),
                        padding: EdgeInsets.only(left: 32.0, right: 32.0),
                        child: Text(
                          'Some text',
                          textAlign: TextAlign.center,
                          style: TextStyle(
                              color: Colors.white,
                              fontFamily: 'PlayfairDisplay',
                              fontStyle: FontStyle.italic,
                              fontSize: 16.0),
                        )),
                    Container(
                        margin: EdgeInsets.only(top: 16.0),
                        padding: EdgeInsets.only(left: 32.0, right: 32.0),
                        child: Text(
                          'some text',
                          textAlign: TextAlign.center,
                          style: TextStyle(
                              color: Colors.white,
                              fontFamily: 'PlayfairDisplay',
                              fontSize: 16.0),
                        )),
                  ],
                ),
              ),
            )
          ],
        ),
      ),
    );
  }

// METHODS
  void _listenToScrollChange() {
    if (_scrollController.offset >= 48.0) {
      setState(() {
        _isScrolled = true;
      });
    } else {
      setState(() {
        _isScrolled = false;
      });
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

您只需使用 _listenToScrollChange 中的 if 值和动画的 Duration 即可获得所需的输出。