如何使用流畅的动画从页面视图中删除页面? [英] How to remove a page from Page View with a smooth animation?

查看:12
本文介绍了如何使用流畅的动画从页面视图中删除页面?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

我有这个代码:

类 Carroussel 扩展 StatefulWidget {@覆盖_CarrousselState createState() =>新的_CarrousselState();}_CarrousselState 类扩展了状态<Carroussel>{PageController 控制器;int 当前页 = 0;@覆盖初始化状态(){super.initState();控制器 = 新页面控制器(初始页:当前页,保持页面:假,视口分数:0.5,);}@覆盖处置(){控制器.dispose();super.dispose();}@覆盖小部件构建(BuildContext 上下文){返回新的脚手架(身体:新中心(孩子:新容器(孩子:新的PageView.builder(onPageChanged:(值){设置状态((){当前页=值;});},控制器:控制器,itemBuilder: (context, index) =>建造者(索引)),),),);}建造者(整数指数){返回新的动画生成器(动画:控制器,建设者:(上下文,孩子){双值 = 1.0;if (pageController.position.haveDimensions) {值 = 控制器页面 - 索引;值 = (1 - (value.abs() * .5)).clamp(0.0, 1.0);}返回新中心(孩子:新的大小盒(高度:Curves.easeOut.transform(value) * 300,宽度:Curves.easeOut.transform(value) * 250,孩子:孩子,),);},孩子:新容器(边距:常量 EdgeInsets.all(8.0),颜色:索引 % 2 == 0 ?颜色.蓝色:颜色.红色,),);}}

以上代码作者:

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

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

解决方案

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

class Carousel extends StatefulWidget {@覆盖_CarouselState createState() =>_CarouselState();}类 _CarouselState 扩展状态<Carousel>{后期 PageController 控制器;int currentPage = 0;列表<字符串>listItem = ['第1页','第2页','第3页','第4页'];@覆盖初始化状态(){super.initState();控制器 = 页面控制器(初始页:当前页,保持页面:假,视口分数:0.5,);}@覆盖处置(){控制器.dispose();super.dispose();}@覆盖小部件构建(BuildContext 上下文){返回脚手架(身体:中心(孩子:容器(孩子:PageView.builder(itemCount:listItem.length,onPageChanged:(值){设置状态((){当前页面 = 值;});},控制器:控制器,itemBuilder: (BuildContext context, int index) =>pageBuilder(索引),),),),);}pageBuilder(int index) {var dismissibleKey = GlobalKey<State>();返回动画生成器(动画:控制器,建设者:(上下文,孩子){双值 = 1.0;if (controller.position.haveDimensions) {值 = 控制器页面!- 指数;值 = (1 - (value.abs() * .5)).clamp(0.0, 1.0);}退货中心(孩子:大小框(高度:Curves.easeOut.transform(value) * 300,宽度:Curves.easeOut.transform(value) * 250,孩子:孩子,),);},孩子:可解雇(键:dismissibleKey,方向:DismissDirection.down,onDismissed: (DismissDirection 方向) {///从列表中删除项目设置状态((){listItem.removeAt(index);});},孩子:墨水井(长按:(){debugPrint('删除!$index');设置状态((){listItem.removeAt(index);});},点按:(){控制器.animateToPage(索引,持续时间:持续时间(毫秒:500),曲线:Curves.ease);},孩子:容器(边距:常量 EdgeInsets.all(8.0),//颜色:索引 % 2 == 0 ?颜色.蓝色:颜色.红色,颜色:Colors.lightBlueAccent,孩子:中心(孩子:文本('${listItem[index]}'),),),),),);}}

I'm still new to flutter animation, and I'm trying to make a PageView to dismiss when you press on it with an animation.

I have this code:

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,
      ),
    );
  }
}

Author of the above code: https://stackoverflow.com/a/47357960/1194779

That Produces the following:

Now I need to make it once I press on a card to be dismissed with an animation.

I have tried implementing SlideTransition that slides the card downwards. But I'm failing to make the PageView to animate the filling empty space of the just removed card.

解决方案

You can use Dismissible to enable swipe gestures on your widget. Though when used with PageViews, Dismissible creates a jank that may be undesirable.

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]}'),
            ),
          ),
        ),
      ),
    );
  }
}

这篇关于如何使用流畅的动画从页面视图中删除页面?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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