在屏幕水龙头上显示(滑入)或隐藏(滑出)抖动AppBar

时间:2018-11-26 22:31:59

标签: android dart flutter

请尝试在点击屏幕时滑动AppBar并在再次点击屏幕时滑动AppBar来创建这种效果。

sample image

我可以通过将float和snap设置为true来在SliverAppBar中创建类似的东西。区别在于appBar在向下滚动时显示,而在轻击或向上滚动屏幕时隐藏。

这是SliverAppBar的示例代码:

 @override
  Widget build(BuildContext context) {

    return Scaffold(
          body: CustomScrollView(
            controller: _ctrlr,

                slivers: <Widget>[
                  SliverAppBar(
                    floating: true,
                    snap: true,

                  ),
                  SliverList(
                    delegate: SliverChildListDelegate([
                      Text('1', style: TextStyle(fontSize: 160.0),),
                      Text('2', style: TextStyle(fontSize: 160.0),),
                      Text('3', style: TextStyle(fontSize: 160.0),),
                      Text('4', style: TextStyle(fontSize: 160.0),),
                    ]),
                  )
                ],
        ),
    );
  }  

我该如何实现?我也考虑过将AppBar放在堆栈中,但我认为这不是最好的方法。非常感谢您的帮助!

4 个答案:

答案 0 :(得分:2)

我遇到了类似的需求,发现了你的问题。由于没有答案,因此我自己尝试解决问题。我知道您在6个月前问过这个问题,但是我想回答一个(几乎完整的)答案,以防其他人发生在上面。

(对于我的方法不够优雅,我深表歉意,但是在撰写本文时,我只使用Flutter大约一个星期。:)

import 'package:flutter/material.dart';
import 'package:transparent_image/transparent_image.dart';

class FramePage extends StatefulWidget {
  final String title;
  final String imageUrl;

  FramePage({Key key, this.title, this.imageUrl}) : super(key: key);

  @override
  _FramePageState createState() => _FramePageState();
}

class _FramePageState extends State<FramePage> with SingleTickerProviderStateMixin {
  AnimationController _controller;
  bool _appBarVisible;

  @override
  void initState() {
    super.initState();

    _appBarVisible = true;
    _controller = AnimationController(
      duration: const Duration(milliseconds: 700),
      value: 1.0,
      vsync: this,
    );
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  void _toggleAppBarVisibility() {
    _appBarVisible = !_appBarVisible;
    _appBarVisible ? _controller.forward() : _controller.reverse();
  }

  Widget get _imageWidget {
    return Center(
      child: GestureDetector(
      onTap: () => setState(() { _toggleAppBarVisibility(); } ),
      child: Container(
          foregroundDecoration: new BoxDecoration(color: Color.fromRGBO(155, 85, 250, 0.0)),
          child: FadeInImage.memoryNetwork(
            placeholder: kTransparentImage,
            image: widget.imageUrl,
            fit: BoxFit.cover,
          ),
        ),
      ),
    );
  }

  @override
  Widget build(BuildContext context)
  {
    Animation<Offset> offsetAnimation = new Tween<Offset>(
      begin: Offset(0.0, -70),
      end: Offset(0.0, 0.0),
    ).animate(_controller);

    return Scaffold(
      body: Stack(
        children: <Widget>[
          _imageWidget,
          SlideTransition(
            position: offsetAnimation,
            child: Container(
              height: 75,
              child: AppBar(
                title: Text(widget.title),
              ),
            ),
          ),
        ],
      )
    );
  }
}

从本质上讲,AppBar被删除为脚手架的直接部分,而是被添加到Stack中,在其中可以对其进行动画处理。为了确保图像在其后面可见,将其放置在容器中,以便可以控制其高度(否则,您将无法看到图像)。

在上面的代码中,点击图像可使AppBar缩回,再次点击则使其重新出现。但是由于某种原因,我还无法真正获得平滑地前后动画的效果,但是效果在那里。

在实践中,它看起来像这样:

Animating the AppBar visibility

如果有人(在做之前)想出让我平滑制作动画所缺少的内容,请随时提供帮助。

答案 1 :(得分:0)

只需用AnimatedBuilder和Transform.translate小部件替换Bob H.解决方案中的SlideTransition:

 *** Variable ***
     ${profile}          https://web.facebook.com/xxx
 *** Keywords ***
     Click Profile
     [Arguments]        ${xpath}
     Click Element      ${xpath}
 *** Test Cases ***
     Go To           ${profile}

答案 2 :(得分:0)

这是我的答案:

new

答案 3 :(得分:0)

我在这里遇到了 CopsOnRoad 建议的更好方法:Flutter - How can I dynamically show or hide App Bars on pages

只是为他人重新分享。

我们可以在另一个小部件中抽象动画部分,例如:

setf

现在这个 class SlidingAppBar extends PreferredSize { SlidingAppBar({ @required this.child, @required this.controller, @required this.visible, }); @override final PreferredSizeWidget child; @override Size get preferredSize => child.preferredSize; final AnimationController controller; final bool visible; @override Widget build(BuildContext context) { visible ? controller.reverse() : controller.forward(); return SlideTransition( position: Tween<Offset>(begin: Offset.zero, end: Offset(0, -1)).animate( CurvedAnimation(parent: controller, curve: Curves.fastOutSlowIn), ), child: child, ); } } 小部件可以与 SlidingAppBarScaffold 字段一起使用,而不是使用 appBar 小部件,例如:

Stack