欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Flutter中ListView动画OpenContainer动画Flutter径向过渡OpenContainer

程序员文章站 2024-03-24 09:55:16
...

题记
—— 执剑天涯,从你的点滴积累开始,所及之处,必精益求精,即是折腾每一天。

** 你可能需要
CSDN 网易云课堂教程
掘金 EDU学院教程
知乎 Flutter系列文章

本文章通过 OpenContainer 结合列表 ListView来实现页面的径向过渡动画,最终实现现的效果如下:
Flutter中ListView动画OpenContainer动画Flutter径向过渡OpenContainer

引入依赖:

  # Material motion 规范的预构建动画
  animations: ^1.1.1

整个页面通过ListView来构建:

import 'dart:ui';
import 'package:animations/animations.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';


class OpenContainerPage extends StatefulWidget {
  @override
  _FlashAnimationPageState createState() => _FlashAnimationPageState();
}

class _FlashAnimationPageState extends State<OpenContainerPage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("OpenContainer过渡"),
      ),
      backgroundColor: Colors.grey[200],
      ///列表
      body: ListView.builder(
        ///构建每个列表的显示的Widget
        itemBuilder: (BuildContext context, int index) {
          return buildOpenContainer(index);
        },
        itemCount: 10,
      ),
    );
  }

  /// 列表中的每个条目的Widget
  /// [index] 列表条目对应的索引
  buildContentWidget(int index) {
    ///手势事件点击跳转
    return GestureDetector(
        ///条目显示的一张图片
        child: buildShowItemContainer(),
        onTap: () {
          ///点击打开新的页面
          Navigator.of(context)
              .push(MaterialPageRoute(builder: (BuildContext context) {
            return Item2Page();
          }));
        });
  }
  /// lib/code23/main_data2336.dart
  /// 列表中的每个条目的Widget
  /// [index] 列表条目对应的索引
  buildOpenContainerItem(int index) {
    return OpenContainer(
      ///将要打开的页面
      openBuilder:
          (BuildContext context, void Function({Object returnValue}) action) {
        return Item2Page();
      },
      ///现在显示的页面
      closedBuilder: (BuildContext context, void Function() action) {
        ///条目显示的一张图片
        return buildShowItemContainer();
      },
    );
  }
   ... ...  ...  
}

列表中显示的Item构建如下:

  Container buildShowItemContainer() {
    return Container(
      color: Colors.blueGrey,
      ///边距设置
      margin: EdgeInsets.only(top: 8),
      child: Image.asset(
        "assets/images/2.0x/banner4.webp",
        fit: BoxFit.fill,
      ),
    );
  }

将要打开的页面构建如下:

class Item2Page extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return _Item2PageState();
  }
}

class _Item2PageState extends State<Item2Page> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        elevation: 0.0,
        title: Text("页面二"),
      ),

      ///页面二中的Hero
      body: InkWell(
        onTap: () {
          Navigator.of(context).pop(true);
        },
        child: Image.asset(
          "assets/images/2.0x/banner1.webp",
          fit: BoxFit.fill,
        ),
      ),
    );
  }
}

详细属性配制如下:

  buildOpenContainer() {
    ///容器转换路由
    return OpenContainer(
      ///过渡的动画类型
      transitionType: ContainerTransitionType.fade,
      ///过渡时间
      transitionDuration: Duration(milliseconds: 3000),
      ///closedBuilder配置的Widget的背景色
      closedColor: Colors.white,
      ///阴影高度
      closedElevation: 2,
      ///边框样式
      closedShape: RoundedRectangleBorder(
          borderRadius: BorderRadius.all(Radius.circular(10))),

      ///默认显示的Widget
      closedBuilder: (BuildContext context, void Function() action) {
        ///条目显示的一张图片
        return buildShowItemContainer();
      },

      ///点击打开的页面
      openBuilder:
          (BuildContext context, void Function({Object returnValue}) action) {
        return Item2Page();
      },

      ///openBuilder配置的Widget的背景色
      openColor: Colors.blue,
      openElevation: 1.0,
      openShape: RoundedRectangleBorder(
          borderRadius: BorderRadius.all(Radius.circular(10))),

      ///从第二个页面中返回时的回调
      ///参数 value就是上一个页面回传的参数
      onClosed: (value) {
        print("onClosed $value");
      },
    );
  }

完结
Flutter中ListView动画OpenContainer动画Flutter径向过渡OpenContainer