如何使用流畅的动画从页面视图中删除页面?

Posted

技术标签:

【中文标题】如何使用流畅的动画从页面视图中删除页面?【英文标题】:How to remove a page from Page View with a smooth animation? 【发布时间】:2019-07-21 11:12:20 【问题描述】:

我还是 Flutter 动画的新手,我正在尝试让 PageView 在您按下动画时关闭它。

我有这个代码:

class Carroussel extends StatefulWidget 
  @override
  _CarrousselState createState() => new _CarrousselState();


class _CarrousselState extends State<Carroussel> 
  PageController controller;
  int currentpage = 0;

  @override
  initState() 
    super.initState();
    controller = new PageController(
      initialPage: currentpage,
      keepPage: false,
      viewportFraction: 0.5,
    );
  

  @override
  dispose() 
    controller.dispose();
    super.dispose();
  

  @override
  Widget build(BuildContext context) 
    return new Scaffold(
      body: new Center(
        child: new Container(
          child: new PageView.builder(
              onPageChanged: (value) 
                setState(() 
                  currentpage = value;
                );
              ,
              controller: controller,
              itemBuilder: (context, index) => builder(index)),
        ),
      ),
    );
  

  builder(int index) 
    return new AnimatedBuilder(
      animation: controller,
      builder: (context, child) 
        double value = 1.0;
        if (pageController.position.haveDimensions) 
          value = controller.page - index;
          value = (1 - (value.abs() * .5)).clamp(0.0, 1.0);
        

        return new Center(
          child: new SizedBox(
            height: Curves.easeOut.transform(value) * 300,
            width: Curves.easeOut.transform(value) * 250,
            child: child,
          ),
        );
      ,
      child: new Container(
        margin: const EdgeInsets.all(8.0),
        color: index % 2 == 0 ? Colors.blue : Colors.red,
      ),
    );
  

以上代码作者:https://***.com/a/47357960/1194779

产生以下内容:

现在我需要在按下卡片后通过动画将其关闭。

我已尝试实现将卡片向下滑动的 SlideTransition。但我无法让 PageView 为刚刚移除的卡片的填充空白空间设置动画。

【问题讨论】:

你有解决办法吗? 同样,有这方面的消息吗? 【参考方案1】:

您可以使用Dismissible 在您的小部件上启用滑动手势。尽管与 PageViews 一起使用时,Dismissible 会产生可能不受欢迎的卡顿。

class Carousel extends StatefulWidget 
  @override
  _CarouselState createState() => _CarouselState();


class _CarouselState extends State<Carousel>
  late PageController controller;
  int currentPage = 0;
  List<String> listItem = ['Page 1', 'Page 2', 'Page 3', 'Page 4'];

  @override
  initState() 
    super.initState();
    controller = PageController(
      initialPage: currentPage,
      keepPage: false,
      viewportFraction: 0.5,
    );
  

  @override
  dispose() 
    controller.dispose();
    super.dispose();
  

  @override
  Widget build(BuildContext context) 
    return Scaffold(
      body: Center(
        child: Container(
          child: PageView.builder(
            itemCount: listItem.length,
            onPageChanged: (value) 
              setState(() 
                currentPage = value;
              );
            ,
            controller: controller,
            itemBuilder: (BuildContext context, int index) =>
                pageBuilder(index),
          ),
        ),
      ),
    );
  

  pageBuilder(int index) 
    var dismissibleKey = GlobalKey<State>();
    return AnimatedBuilder(
      animation: controller,
      builder: (context, child) 
        double value = 1.0;
        if (controller.position.haveDimensions) 
          value = controller.page! - index;
          value = (1 - (value.abs() * .5)).clamp(0.0, 1.0);
        

        return Center(
          child: SizedBox(
            height: Curves.easeOut.transform(value) * 300,
            width: Curves.easeOut.transform(value) * 250,
            child: child,
          ),
        );
      ,
      child: Dismissible(
        key: dismissibleKey,
        direction: DismissDirection.down,
        onDismissed: (DismissDirection direction) 
          /// Remove item from List
          setState(() 
            listItem.removeAt(index);
          );
        ,
        child: InkWell(
          onLongPress: () 
            debugPrint('Delete! $index');
            setState(() 
              listItem.removeAt(index);
            );
          ,
          onTap: () 
            controller.animateToPage(index,
                duration: Duration(milliseconds: 500), curve: Curves.ease);
          ,
          child: Container(
            margin: const EdgeInsets.all(8.0),
            // color: index % 2 == 0 ? Colors.blue : Colors.red,
            color: Colors.lightBlueAccent,
            child: Center(
              child: Text('$listItem[index]'),
            ),
          ),
        ),
      ),
    );
  

【讨论】:

以上是关于如何使用流畅的动画从页面视图中删除页面?的主要内容,如果未能解决你的问题,请参考以下文章

如何从列表视图中删除某些内容并重新加载页面?颤振网络

如何在 Facebook 页面顶部菜单中创建动画?

如何使我的滚动到顶部按钮动画流畅

如何在 iOS 中获得最流畅的动画?

如何通过许多子视图保持 iOS 动画流畅

页面视图滚动上的颤动文本动画