将动画滑动到底部 [英] Sliding animation to bottom in flutter

查看:70
本文介绍了将动画滑动到底部的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

页面底部有一个点指示器。我需要在滑动到底部5秒钟后将其隐藏。当用户移动到其他页面时,显示的点会滑到顶部,最后在5秒钟后再次隐藏。现在点消失了5秒后消失了,但我需要其他类型的动画。

I have a dot indicator in bottom of the page. I need to hide this after 5 seconds sliding to bottom. When user move to other page show dots sliding to top and finally after 5 seconds hide again. Now the dots hide after 5 seconds in fade out but i need other type of animation.

import 'package:flutter/material.dart';
import 'package:iGota/screens/partials/dots_indicator.dart';
import 'package:iGota/screens/posts_page.dart';
import 'package:iGota/screens/maps_page.dart';

class HomePage extends StatefulWidget {
  static String tag = 'home-page';

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

class _MyHomePageState extends State<HomePage> {
  final _controller = new PageController();
  static const _kDuration = const Duration(milliseconds: 300);
  static const _kCurve = Curves.ease;
  final _kArrowColor = Colors.black.withOpacity(0.8);
  bool _visible = true;

  void initState() {
    super.initState();
    Future.delayed(Duration(milliseconds: 5)).then((_) => _visible = !_visible);
  }

  @override
  Widget build(BuildContext context) {
    final List<Widget> _pages = <Widget>[
      new ConstrainedBox(
        constraints: const BoxConstraints.expand(),
        child: new FlatButton(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              FlatButton(
                onPressed: () {
                  Navigator.pushNamed(context, PostsPage.tag);
                },
                child: Column(
                  children: <Widget>[
                    IconButton(
                      icon:
                          Icon(Icons.save_alt, color: Colors.white, size: 30.0),
                      onPressed: () {
                        Navigator.pushNamed(context, PostsPage.tag);
                      },
                    ),
                    Text(
                      "Contenedores",
                      style: TextStyle(color: Colors.white, fontSize: 20.0),
                    )
                  ],
                ),
              ),
            ],
          ),
          splashColor: Colors.white,
          color: Colors.blue[300],
          onPressed: () {
            Navigator.pushNamed(context, PostsPage.tag);
          },
        ),
      ),
      new ConstrainedBox(
        constraints: const BoxConstraints.expand(),
        child: new FlatButton(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              FlatButton(
                onPressed: () {
                  Navigator.pushNamed(context, MapsPage.tag);
                },
                child: Column(
                  children: <Widget>[
                    IconButton(
                      icon: Icon(Icons.bubble_chart,
                          color: Colors.white, size: 30.0),
                      onPressed: () {
                        Navigator.pushNamed(context, MapsPage.tag);
                      },
                    ),
                    Text(
                      "Válvulas",
                      style: TextStyle(color: Colors.white, fontSize: 20.0),
                    )
                  ],
                ),
              ),
            ],
          ),
          splashColor: Colors.white,
          color: Colors.red[300],
          onPressed: () {
            Navigator.pushNamed(context, MapsPage.tag);
          },
        ),
      ),
    ];

    return new Scaffold(
      body: new IconTheme(
        data: new IconThemeData(color: _kArrowColor),
        child: new Stack(
          children: <Widget>[
            new PageView.builder(
              physics: new AlwaysScrollableScrollPhysics(),
              controller: _controller,
              itemCount: _pages.length,
              itemBuilder: (BuildContext context, int index) {
                this._visible=true;
                return _pages[index % _pages.length];
              },
            ),
            new Positioned(
              bottom: 0.0,
              left: 0.0,
              right: 0.0,
              child: AnimatedOpacity(
                opacity: _visible ? 1.0 : 0.0,
                duration: Duration(milliseconds: 3000),               
                child: new Container(       
                  color: Colors.grey[800].withOpacity(0.5),
                  padding: const EdgeInsets.all(20.0),
                  child: new Center(
                    child: new DotsIndicator(
                      controller: _controller,
                      itemCount: _pages.length,
                      onPageSelected: (int page) {
                        _controller.animateToPage(
                          page,
                          duration: _kDuration,
                          curve: _kCurve,
                        );
                      },
                    ),
                  ),
                ),
              ),
            )
          ],
        ),
      ),
    );
  }
}

我认为位置转换会对我有所帮助,但我不知道如何在不重写的情况下将其添加到代码中。有人可以帮助我吗?

I think position transition would help me but i don't know exactly how can i add to my code without rewriting. So anybody can help me?

更新

import 'package:flutter/material.dart';
import 'package:iGota/screens/partials/dots_indicator.dart';
import 'package:iGota/screens/posts_page.dart';
import 'package:iGota/screens/maps_page.dart';

class HomePage extends StatefulWidget {
  static String tag = 'home-page';

  @override
  HomePageState createState() => new HomePageState();
}

class HomePageState extends State<HomePage>
    with SingleTickerProviderStateMixin {
  final _controller = new PageController();
  static const _kDuration = const Duration(milliseconds: 300);
  static const _kCurve = Curves.ease;
  final _kArrowColor = Colors.black.withOpacity(0.8);
  AnimationController controller;
  Animation<Offset> offset;

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

    controller =AnimationController(vsync: this, duration: Duration(seconds: 1));
    Future.delayed(Duration(seconds: 5)).then((_) => controller.forward());

    offset = Tween<Offset>(begin: Offset.zero, end: Offset(0.0, 1.0))
        .animate(controller);
  }

  @override
  Widget build(BuildContext context) {
    GestureDetector(onTap: () {
      setState(() {
        controller.reverse();
      });
    });
    final List<Widget> _pages = <Widget>[
      new ConstrainedBox(
        constraints: const BoxConstraints.expand(),
        child: new FlatButton(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              FlatButton(
                onPressed: () {
                  Navigator.pushNamed(context, PostsPage.tag);
                },
                child: Column(
                  children: <Widget>[
                    IconButton(
                      icon:
                          Icon(Icons.save_alt, color: Colors.white, size: 30.0),
                      onPressed: () {
                        Navigator.pushNamed(context, PostsPage.tag);
                      },
                    ),
                    Text(
                      "Contenedores",
                      style: TextStyle(color: Colors.white, fontSize: 20.0),
                    )
                  ],
                ),
              ),
            ],
          ),
          splashColor: Colors.white,
          color: Colors.blue[300],
          onPressed: () {
            Navigator.pushNamed(context, PostsPage.tag);
          },
        ),
      ),
      new ConstrainedBox(
        constraints: const BoxConstraints.expand(),
        child: new FlatButton(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              FlatButton(
                onPressed: () {
                  Navigator.pushNamed(context, MapsPage.tag);
                },
                child: Column(
                  children: <Widget>[
                    IconButton(
                      icon: Icon(Icons.bubble_chart,
                          color: Colors.white, size: 30.0),
                      onPressed: () {
                        Navigator.pushNamed(context, MapsPage.tag);
                      },
                    ),
                    Text(
                      "Válvulas",
                      style: TextStyle(color: Colors.white, fontSize: 20.0),
                    )
                  ],
                ),
              ),
            ],
          ),
          splashColor: Colors.white,
          color: Colors.red[300],
          onPressed: () {
            Navigator.pushNamed(context, MapsPage.tag);
          },
        ),
      ),
    ];

    return new Scaffold(
      body: new IconTheme(
        data: new IconThemeData(color: _kArrowColor),
        child: new Stack(
          children: <Widget>[
            new PageView.builder(
              physics: new AlwaysScrollableScrollPhysics(),
              controller: _controller,
              itemCount: _pages.length,
              itemBuilder: (BuildContext context, int index) {
                return _pages[index % _pages.length];
              },
            ),
            new Positioned(
              bottom: 0.0,
              left: 0.0,
              right: 0.0,
              child: SlideTransition(
                position: offset,
                child: new Container(
                  color: Colors.grey[800].withOpacity(0.5),
                  padding: const EdgeInsets.all(20.0),
                  child: new Center(
                    child: new DotsIndicator(
                      controller: _controller,
                      itemCount: _pages.length,
                      onPageSelected: (int page) {
                        _controller.animateToPage(
                          page,
                          duration: _kDuration,
                          curve: _kCurve,
                        );
                      },
                    ),
                  ),
                ),
              ),
            )
          ],
        ),
      ),
    );
  }
}

现在我需要调用 controller.reverse 当用户触摸屏...

Now i need to call controller.reverse when user touch screen...

推荐答案

为指示器创建滑动动画(如果我理解的话)您的要求正确),我只建议使用 SlideTransition 小部件。将其集成到您现有的代码中不需要太多的工作。

To create a sliding animation for your indicator (if I've understood your requirement right), I would simply suggest using the SlideTransition widget. It should not require much work to integrate it in your existing code.

下面的代码显示了 SlideTransition 。如果您想从一个屏幕导航到另一个屏幕期间继续显示它,则必须将其绘制在导航器的上方图层中。

The code belows shows a minimal example of the SlideTransition. If you'd like to keep displaying it during the navigation from one screen to another, you'd have to draw it in a layer above your Navigator.

如果您喜欢使用 Stack ,则可以改用叠加功能,如此答案。通过在导航过渡期间显示期间显示动画,也可以解决这一难题。

If you do not like to use a Stack, you can instead use the Overlay functionality of flutter, as given in this answer. This would also solve the struggle, with keeping the animation displayed during the navigation transition.

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Home(),
    );
  }
}

class Home extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => HomeState();
}

class HomeState extends State<Home> with SingleTickerProviderStateMixin {
  AnimationController controller;
  Animation<Offset> offset;

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

    controller =
        AnimationController(vsync: this, duration: Duration(seconds: 1));

    offset = Tween<Offset>(begin: Offset.zero, end: Offset(0.0, 1.0))
        .animate(controller);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Stack(
        children: <Widget>[
          Center(
            child: RaisedButton(
              child: Text('Show / Hide'),
              onPressed: () {
                switch (controller.status) {
                  case AnimationStatus.completed:
                    controller.reverse();
                    break;
                  case AnimationStatus.dismissed:
                    controller.forward();
                    break;
                  default:
                }
              },
            ),
          ),
          Align(
            alignment: Alignment.bottomCenter,
            child: SlideTransition(
              position: offset,
              child: Padding(
                padding: EdgeInsets.all(50.0),
                child: CircularProgressIndicator(),
              ),
            ),
          )
        ],
      ),
    );
  }
}

这篇关于将动画滑动到底部的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆