0

我正在颤动中创建一个 AnimatedList ,我想要的唯一动画是在按下项目的删除按钮后删除列表项时。该项目删除并消失,但我希望它在删除时为垂直折叠设置动画(我使用 SizeTransition)。动画似乎没有运行。

我认为这与我实现RemovedItemBuilder类的方式有关,但它几乎与 Flutter 文档中SizeTransition类的示例相同。

(当在RemovedItemBuilder类的构建方法中返回DirectMessagePreview的实例作为临时占位符时,我故意传入了索引“99”和名称“哇” )

import 'package:flutter/material.dart';

class DirectMessages extends StatefulWidget {
  const DirectMessages({Key? key}) : super(key: key);

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

class _DirectMessagesState extends State<DirectMessages>
    with TickerProviderStateMixin {
  final GlobalKey<AnimatedListState> listkey = GlobalKey<AnimatedListState>();

  late var list = [1, 2, 3, 4, 5];

  void removeDirectMessage(int index) {
    print(index);
    setState(() {
      list.removeAt(index - 1);
    });
    print(list);
  }

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Container(
        child: AnimatedList(
            key: listkey,
            initialItemCount: list.length,
            itemBuilder: (context, index, animation) {
              return DirectMessagePreview(
                name: list[index].toString(),
                index: index,
              );
            }));
  }
}

class DirectMessagePreview extends StatefulWidget {
  final int index;

  final String name;
  const DirectMessagePreview({
    Key? key,
    required this.index,
    required this.name,
  }) : super(key: key);

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

class _DirectMessagePreviewState extends State<DirectMessagePreview>
    with TickerProviderStateMixin {
  late AnimationController _controller;
  late Animation<double> _animation;

  void initState() {
    super.initState();
  }

  void _move(DragUpdateDetails details) {
    double? delta = details.primaryDelta;
    if (delta != null) this._controller.value -= delta / 112;
  }

  void _handeDragEnd(DragEndDetails details) {
    double velocity = details.velocity.pixelsPerSecond.dx;

    // negative velocity : left swipe, animation forward
    // positive velocity : right swipe, animation reverses

    if (velocity > 0.0) {
      _controller.fling(velocity: -1.0);
    } else if (velocity < 0.0) {
      _controller.fling(velocity: 1.0);
    }
  }

  Widget _buildRemovedItem(
      int item, BuildContext context, Animation<double> animation) {
    return RemovedItemBuilder();
  }

  @override
  Widget build(BuildContext context) {
    _controller = AnimationController(
        duration: Duration(milliseconds: 300),
        reverseDuration: Duration(milliseconds: 30),
        vsync: this);

    _animation = CurvedAnimation(parent: _controller, curve: Curves.linear);

    return GestureDetector(
      onHorizontalDragUpdate: _move,
      onHorizontalDragEnd: _handeDragEnd,
      child: Stack(children: <Widget>[
        Positioned.fill(
          child: Row(
            crossAxisAlignment: CrossAxisAlignment.stretch,
            mainAxisAlignment: MainAxisAlignment.end,
            children: [
              TextButton(
                  onPressed: () {},
                  child: Text('Mute', style: TextStyle(color: Colors.white)),
                  style: ButtonStyle(
                      backgroundColor: MaterialStateProperty.all(Colors.grey),
                      splashFactory: NoSplash.splashFactory,
                      shape:
                          MaterialStateProperty.all(BeveledRectangleBorder()))),
              TextButton(
                  onPressed: () {
                    //print('removing index: ' + widget.index.toString());
                    AnimatedList.of(context).removeItem(
                      widget.index,
                      (context, animation) {
                        return _buildRemovedItem(
                            widget.index, context, animation);
                      },
                    );
                  },
                  child: Text('Delete', style: TextStyle(color: Colors.white)),
                  style: ButtonStyle(
                      backgroundColor: MaterialStateProperty.all(Colors.red),
                      splashFactory: NoSplash.splashFactory,
                      shape:
                          MaterialStateProperty.all(BeveledRectangleBorder()))),
            ],
          ),
        ),
        SlideTransition(
          position: Tween<Offset>(begin: Offset.zero, end: Offset(-.30, 0))
              .animate(_animation),
          child: Container(
              color: Colors.white,
              padding:
                  EdgeInsets.only(left: 16, right: 16, top: 16, bottom: 16),
              child: Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: [
                  Row(
                    children: [
                      Icon(Icons.face), //CircleAvatar()
                      SizedBox(width: 12),
                      Column(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: [
                          Text(widget.name, style: TextStyle(fontSize: 16)),
                          SizedBox(height: 6),
                          Text('Hey this is stan',
                              style: TextStyle(
                                  fontSize: 12, color: Colors.grey[600]))
                        ],
                      )
                    ],
                  ),
                  Text('yesterday')
                ],
              )),
        ),
      ]),
    );
  }
}

class RemovedItemBuilder extends StatefulWidget {
  const RemovedItemBuilder({Key? key}) : super(key: key);

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

class _RemovedItemBuilderState extends State<RemovedItemBuilder>
    with SingleTickerProviderStateMixin {
  late final AnimationController _controller = AnimationController(
    duration: const Duration(milliseconds: 300),
    vsync: this,
  );

  late final Animation<double> _animation =
      CurvedAnimation(parent: _controller, curve: Curves.fastOutSlowIn);

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

  @override
  Widget build(BuildContext context) {
    return SizeTransition(
        sizeFactor: _animation,
        axis: Axis.vertical,
        axisAlignment: -1,
        child: DirectMessagePreview(index: 99, name: 'wow'));
  }
}

4

0 回答 0