Перетаскиваемый свиток, который отскакивает назад - трепетать - PullRequest
0 голосов
/ 28 ноября 2018

В данный момент создаем перетаскиваемый свиток, который отскакивает назад.Использование контроллера анимации, анимации и анимации.Это работает ... Для первого перетаскивания.Последующие перемещения перетаскиваются из первой / исходной позиции.

enter image description here.

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

// void main() => runApp(new MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: new Scaffold(
        appBar: new AppBar(
          title: new Text('Draggable Scroll Bar Demo'),
        ),
        //DraggableScrollbar builds Stack with provided Scrollable List of Grid
        body: new DraggableScrollbar(
          child: _buildGrid(),
        ),
      ),
    );
  }

  Widget _buildGrid() {
    return GridView.builder(
      gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
        crossAxisCount: 5,
      ),
      padding: EdgeInsets.zero,
      itemCount: 1000,
      itemBuilder: (context, index) {
        return Container(
          alignment: Alignment.center,
          margin: EdgeInsets.all(2.0),
          color: Colors.grey[300],
        );
      },
    );
  }
}

class DraggableScrollbar extends StatefulWidget {
  const DraggableScrollbar({this.child});

  final Widget child;

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

class _DraggableScrollbarState extends State<DraggableScrollbar>
    with TickerProviderStateMixin {
  //this counts offset for scroll thumb for Vertical axis
  double _barOffset;
  // controller for the thing
  AnimationController animationController;
  Animation<double> animation;

  @override
  void initState() {
    super.initState();
    animationController =
        AnimationController(vsync: this, duration: Duration(seconds: 1));
    _barOffset = 300.0;
  }

  void _onVerticalDragUpdate(DragUpdateDetails details) {
    setState(() {
      _barOffset += details.delta.dy;
    });
  }

  void _animateSelectorBack() {
    if (mounted) {
      setState(() {
        _barOffset = animation.value;
      });
    }
  }

  void _verticalGoesBack(DragEndDetails details) {
    animationController.reset();

    animation = Tween<double>(begin: _barOffset, end: 300.0)
        .animate(animationController)
          ..addListener(_animateSelectorBack);

    animationController.forward();
  }

  @override
  Widget build(BuildContext context) {
    return new Stack(children: <Widget>[
      widget.child,
      GestureDetector(
          onVerticalDragUpdate: _onVerticalDragUpdate,
          onVerticalDragEnd: _verticalGoesBack,
          child: Container(
              alignment: Alignment.topRight,
              margin: EdgeInsets.only(top: _barOffset),
              child: _buildScrollThumb())),
    ]);
  }

  Widget _buildScrollThumb() {
    return new Container(
      height: 40.0,
      width: 20.0,
      color: Colors.blue,
    );
  }

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

Я думаю, что он сохраняет исходную позицию, но этого не может быть, потому что он устанавливает состояние в исходную позицию.Я запутался в том, как анимации / управление состоянием работают вместе

Ответы [ 2 ]

0 голосов
/ 29 ноября 2018

Я нашел способ, который каким-то образом работает.

void _verticalGoesBack(DragEndDetails details) {
    animationController.reset();

    animation = Tween<double>(begin: _barOffset, end: 300.0)
        .animate(animationController)
          ..addListener(_animateSelectorBack)
          ..addStatusListener((status) {
            if (status == AnimationStatus.completed) {
              animationController.removeListener(_animateSelectorBack);
            }
          });

    animationController.forward();
  }

Думаю, _animateSelectorBack несколько сохраняет положение начальной полосы прокрутки.Может быть, неправильно об этом.Я думаю, что он чище без добавления переменных и дополнительной инициализации.

0 голосов
/ 28 ноября 2018

animationController.reset() сбрасывал значение _barOffset, поэтому я просто создал _previousPosition, который анимация использует в качестве начального значения:

class _DraggableScrollbarState extends State<DraggableScrollbar>
    with TickerProviderStateMixin {
  //this counts offset for scroll thumb for Vertical axis
  double _barOffset;
  double _previousPosition;
  // controller for the thing
  AnimationController animationController;
  Animation<double> animation;

  @override
  void initState() {
    super.initState();
    _barOffset = 300.0;
    _previousPosition = 0.0;
    animationController =
        AnimationController(vsync: this, duration: Duration(seconds: 1));
  }

  void _onVerticalDragUpdate(DragUpdateDetails details) {
    setState(() {
      _barOffset += details.delta.dy;
      _previousPosition = _barOffset;
    });
  }

  void _animateSelectorBack() {
    if (mounted) {
      setState(() {
        _barOffset = animation.value;
      });
    }
  }

  void _verticalGoesBack(DragEndDetails details) {
    animationController.reset();

    animation = Tween<double>(begin: _previousPosition, end: 300.0)
        .animate(animationController)
        ..addListener(_animateSelectorBack);

    animationController.forward();
  }

  @override
  Widget build(BuildContext context) {
    return new Stack(children: <Widget>[
      widget.child,
      GestureDetector(
          onVerticalDragUpdate: _onVerticalDragUpdate,
          onVerticalDragEnd: _verticalGoesBack,
          child: Container(
              alignment: Alignment.topRight,
              margin: EdgeInsets.only(top: _barOffset),
              child: _buildScrollThumb())),
    ]);
  }

  Widget _buildScrollThumb() {
    return new Container(
      height: 40.0,
      width: 20.0,
      color: Colors.blue,
    );
  }

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

Возможно, есть более элегантный способ достижения этогоно это работает, так что не стесняйтесь использовать его!

demo

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...