Flutter OpenContainer 容器转换过渡 Material Design 设计风格的实践

929 阅读2分钟

题记

—— 执剑天涯,从你的点滴积累开始,所及之处,必精益求精,优美的应用体验 来自于细节的处理,更源自于码农的自我要求与努力


Flutter是谷歌推出的最新的移动开发框架。

【x1】微信公众号的每日提醒 随时随记 每日积累 随心而过 文章底部扫码关注

【x2】各种系列的视频教程 免费开源 关注 你不会迷路

【x3】系列文章 百万 Demo 随时 复制粘贴 使用

【x4】一目了然的源码


本文章实现的 Demo 如下: 在这里插入图片描述

Material Design 设计风格中的容器转换过渡 ,如一个列表点击跳转详情,进行无缝切换,在Flutter 中也就是 Container transform 容器切换,通过OpenContainer来实现。

OpenContainer 在两个子窗口组件之间进行无缝切换,执行起来的效果看起来像是同一个窗口组件切换,分别通过 closedBuilder 和 openBuilder 属性来配置。


class AnimationOpenContainerPage extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return _HomePageState();
  }
}

class _HomePageState extends State<AnimationOpenContainerPage> {
  
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.grey[300],
      appBar: AppBar(
        title: Text("浏览图片"),
      ),
      body: buildOpenContainer(),
    );
  }
  ... ...
 }

OpenContainer 的构建使用如下:

  OpenContainer<dynamic> buildOpenContainer() {
    return OpenContainer(
      //背景颜色
      closedColor: Colors.transparent,
      //阴影
      closedElevation: 0.0,
      //圆角
      closedShape: const RoundedRectangleBorder(
        borderRadius: BorderRadius.all(Radius.circular(10.0)),
      ),
      //显示的布局
      closedBuilder: (context, action) {
        return Container(
          color: Colors.grey,
          height: 120,
          margin: EdgeInsets.all(20),
        );
      },
      //过渡的方式
      transitionType: ContainerTransitionType.fade,
      //过渡的时间
      transitionDuration: const Duration(milliseconds: 3500),

      //即将打开的 Widget 的边框样式
      openShape: const RoundedRectangleBorder(
        borderRadius: BorderRadius.all(Radius.circular(1.0)),
      ),
      //即将打开的 Widget 的背景
      openColor: Colors.transparent,
      //阴影
      openElevation: 1.0,
      //布局
      openBuilder: (context, action) {
        return DetailsPage();
      },
    );
  }

当前显示的Widget 通过closedBuilder来构建的,如下图所示: 在这里插入图片描述

DetailsPage 是打开的页面详情,代码如下:

class DetailsPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      //背景透明
      backgroundColor: Colors.white,
      appBar: AppBar(
        title: Text("商品详情"),
      ),
      body: buildCurrentWidget(),
    );
  }

  Widget buildCurrentWidget() {
    return Container(
      color: Colors.white,
      padding: EdgeInsets.all(8),
      margin: EdgeInsets.all(10),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Image.asset(
            "images/banner3.webp",
            fit: BoxFit.fill,
          ),
          SizedBox(
            width: 12,
          ),
          Text(
            "每日分享 精彩一刻",
            style: TextStyle(fontSize: 22),
          ),
          SizedBox(
            height: 4,
          ),
          Container(
            child: Text(
              "优美的应用体验 来自于细节的处理,更源自于码农的自我要求与努力",
              softWrap: true,
              overflow: TextOverflow.ellipsis,
              maxLines: 3,
              style: TextStyle(fontSize: 16),
            ),
          ),
        ],
      ),
    );
  }
}

如下图所示 在这里插入图片描述 以小编的性格,要实现百万Demo随时复制粘贴肯定是需要源码的完整源码在这里

有兴趣 你可以关注一下 西瓜视频 --- 早起的年轻人

在这里插入图片描述