【问题标题】:Flutter - Partial SlideTransition in widgetFlutter - 小部件中的部分 SlideTransition
【发布时间】:2018-04-21 22:21:55
【问题描述】:

我正在尝试创建下面的动画,其中Container 后面有一个小部件。

我尝试使用 Dismissible 类,但它的动画不会在某个点停止,它会走到最后并随着项目消失,根据下面的 gif:

我将代码插入到 SlideTransition 类中,但我不确定如何集成 onHorizontalDragStartonHorizontalDragUpdateonHorizontalDragEnd 以使用隐藏的后部小部件生成预期的效果。

你能帮我解决这个问题吗?

按照下面的代码和你的屏幕:

import 'package:flutter/material.dart';

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

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

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => new _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin {
  AnimationController _controller;
  Animation<double> _animation;
  bool _dragUnderway = false;

  @override
  void initState() {
    _controller = new AnimationController(
      vsync: this,
      duration: const Duration(milliseconds: 200),
    );
    _animation = new CurvedAnimation(
      parent: _controller,
      curve: new Interval(0.0, 1.0, curve: Curves.linear),
    );
    _controller.reverse();
    super.initState();
  }



  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(),
      body: new Center(
        child: new GestureDetector(
          //onHorizontalDragStart: ,
          //onHorizontalDragUpdate:,
          //onHorizontalDragEnd: ,
          child: new SlideTransition(
            position: new Tween<Offset>(
              begin:  Offset.zero,
              end: const Offset(1.0, 0.0),
            ).animate(_animation),
            child: new Container(
              decoration: new BoxDecoration(
                border: new Border(
                  top: new BorderSide(style: BorderStyle.solid, color: Colors.black26),
                  bottom: new BorderSide(style: BorderStyle.solid, color: Colors.black26),
                )
              ),
              padding: new EdgeInsets.only(top: 20.0, bottom: 20.0),
              child: new Row(
                mainAxisAlignment: MainAxisAlignment.center,
                crossAxisAlignment: CrossAxisAlignment.center,
                children: <Widget>[
                  new Text('foo'),                  
                ],
              ),
            ),
          )
        )
      ),
    );
  }
}

【问题讨论】:

    标签: dart flutter


    【解决方案1】:

    我找到了解决办法,按照下面的代码和演示:

    import 'package:flutter/material.dart';
    
    void main() {
      runApp(new MyApp());
    }
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return new MaterialApp(
          home: new MyHomePage(),
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
      @override
      _MyHomePageState createState() => new _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin {
      AnimationController _controller;
      Animation<double> _animation;
    
      void initState() {
        super.initState();
        _controller = new AnimationController(duration: 
          const Duration(milliseconds: 246), vsync: this);
    
        _animation = new CurvedAnimation(
          parent: _controller,
          curve: new Interval(0.0, 1.0, curve: Curves.linear),
        );
      }
    
      void _move(DragUpdateDetails details) {
        final double delta = details.primaryDelta / 304;
        switch (Directionality.of(context)) {
          case TextDirection.rtl:
            _controller.value += delta;
            break;
          case TextDirection.ltr:
            _controller.value -= delta;
            break;
        }
      }  
    
      void _handleDragEnd(DragEndDetails details) {
        bool _isFlingGesture = -details.velocity.pixelsPerSecond.dx > 700;
    
        if (_isFlingGesture) {
          final double flingVelocity = details.velocity.pixelsPerSecond.dx;
          _controller.fling(velocity: flingVelocity.abs() * 0.003333);
        } else if (_controller.value < 0.4) {
          _controller.reverse();
        } else {
          _controller.forward();
        }
      }
    
      @override
      Widget build(BuildContext context) {
        return new Scaffold(
          appBar: new AppBar(),
          body: new Center(
            child: new GestureDetector(
              onHorizontalDragUpdate: _move,
              onHorizontalDragEnd: _handleDragEnd,
              child: new Stack(
                children: <Widget>[
                  new Positioned.fill(            
                    child: new Row(
                      mainAxisAlignment: MainAxisAlignment.end,
                      children: <Widget>[
                        new Container(
                          decoration: new BoxDecoration(
                            color: Colors.black38,
                            border: new Border(
                              top: new BorderSide(style: BorderStyle.solid, color: Colors.black12),
                              bottom: new BorderSide(style: BorderStyle.solid, color: Colors.black12),
                            ),
                          ),
                          child: new IconButton(                          
                            padding: new EdgeInsets.only(top: 16.0, bottom: 16.0, left: 24.0, right: 24.0),
                            icon: new Icon(Icons.thumb_up),
                            color: new Color(0xFFFFFFFF),
                            onPressed: () {},
                          )
                        ),
                        new Container(
                          decoration: new BoxDecoration(
                            color: Colors.black54,
                            border: new Border(
                              top: new BorderSide(style: BorderStyle.solid, color: Colors.black12),
                              bottom: new BorderSide(style: BorderStyle.solid, color: Colors.black12),
                            ),
                          ),
                          child: new IconButton(                          
                            padding: new EdgeInsets.only(top: 16.0, bottom: 16.0, left: 24.0, right: 24.0),
                            icon: new Icon(Icons.edit),
                            color: new Color(0xFFFFFFFF),
                            onPressed: () {},
                          )
                        ),
                        new Container(
                          decoration: new BoxDecoration(
                            color: new Color(0xFFE57373),
                            border: new Border(
                              top: new BorderSide(style: BorderStyle.solid, color: const Color(0xFFE57373)),
                              bottom: new BorderSide(style: BorderStyle.solid, color: const Color(0xFFE57373)),
                            ),
                          ),
                          child: new IconButton(                          
                            padding: new EdgeInsets.only(top: 16.0, bottom: 16.0, left: 24.0, right: 24.0),
                            icon: new Icon(Icons.delete),
                            color: new Color(0xFFFFFFFF),
                            onPressed: () {},
                          )
                        ),
                      ],
                    ),
                  ),
                  new SlideTransition(
                    position: new Tween<Offset>(
                      begin:  Offset.zero,
                      end: const Offset(-0.6, 0.0), //controls the opening of the slice
                    ).animate(_animation),
                    child: new Container(
                      decoration: new BoxDecoration(
                        border: new Border(
                          top: new BorderSide(style: BorderStyle.solid, color: Colors.black26),
                          bottom: new BorderSide(style: BorderStyle.solid, color: Colors.black26),
                        ),
                        color: new Color(0xFFFFFFFF),
                      ),
                      padding: new EdgeInsets.only(top: 20.0, bottom: 20.0),
                      child: new Row(
                        mainAxisAlignment: MainAxisAlignment.center,
                        crossAxisAlignment: CrossAxisAlignment.center,
                        children: <Widget>[
                          new Text('foo'),
                        ],
                      ),
                    ),
                  ),                           
                ],
              )
            )
          ),
        );
      }
    }
    

    【讨论】:

    • 优秀的解决方案。但是,如果您想要更灵活,则应以编程方式解决“偏移(-0.6,0.0)”。一种方法是将手势检测器包装到带有 boxConstraints 参数的 LayoutBuilder 中。知道了动作按钮的宽度,当然还有它们的数量,就可以很容易地计算出必要的偏移量,如下所示:Offset(-1 * (actionWidth * actionButtons.length)/ constraints.maxWidth, 0.0)
    猜你喜欢
    • 2021-10-28
    • 1970-01-01
    • 2021-08-06
    • 1970-01-01
    • 2021-05-09
    • 2021-07-14
    • 2020-10-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多