温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Flutter怎么实现笑嘻嘻的动态表情

发布时间:2022-04-24 10:12:41 阅读:145 作者:iii 栏目:开发技术
开发者测试专用服务器限时活动,0元免费领,库存有限,领完即止! 点击查看>>

这篇文章主要介绍“Flutter怎么实现笑嘻嘻的动态表情”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Flutter怎么实现笑嘻嘻的动态表情”文章能帮助大家解决问题。

效果如下图所示

Flutter怎么实现笑嘻嘻的动态表情

AnimatedContainer 介绍

在实现之前,先介绍一个新组件 —— AnimatedContainer 。看这个名字就知道和 Container 有关,实际上AnimatedContainer是 Flutter 中的一个动画容器,Container 有的属性基本上它都有,我们看一下二者的构造方法的区别。

AnimatedContainer({
    Key? key,
    this.alignment,
    this.padding,
    Color? color,
    Decoration? decoration,
    this.foregroundDecoration,
    double? width,
    double? height,
    BoxConstraints? constraints,
    this.margin,
    this.transform,
    this.transformAlignment,
    this.child,
    this.clipBehavior = Clip.none,
    Curve curve = Curves.linear,
    required Duration duration,
    VoidCallback? onEnd,
  });

Container({
    Key? key,
    this.alignment,
    this.padding,
    this.color,
    this.decoration,
    this.foregroundDecoration,
    double? width,
    double? height,
    BoxConstraints? constraints,
    this.margin,
    this.transform,
    this.transformAlignment,
    this.child,
    this.clipBehavior = Clip.none,
  });

可以看到,实际上 AnimatedContainer 和 Container 只差了3个属性,而这三个属性就是控制动画的参数:

  • curve:动画曲线,默认是线性;

  • duration:动效时长参数;

  • onEnd:动效结束后的回调方法。

AnimatedContainer的特性是所有涉及外观的属性都会生成一个过渡动效,当这些外观属性发生改变的时候就会使用生成的的动效来完成过渡,从而展现出动画效果。像我们要实现的笑嘻嘻的表情其实就是利用 AnimatedContainer 实现的。

组件结构

我们的笑嘻嘻动效,底部是一个圆形脑袋,上面有两颗眼睛和一个嘴巴,其中眼睛和嘴巴有移动动效,而眼睛的眼珠还有方向的动效。这些动效都可以使用AnimatedContainer来实现。大的页面结构如下:

Flutter怎么实现笑嘻嘻的动态表情

细节实现

脑袋这个很容易,直接用原型裁剪,设置尺寸和底色即可:

// 脑袋
ClipOval(
  childContainer(
    width120,
    height120,
    color: Colors.blue,
  ),
),

眼睛左眼和右眼有点不一样,眼球实际就是AnimatedContainer使用 borderRadius 裁剪为圆形,而眼珠是AnimatedContainer的子组件 —— 黑色的圆圈。具体实现向左或向右看使用一个变量 seeLeft 控制,而向左向右的转换过渡效果都由 AnimatedContainer 控制。

  • seeLeft = true,向左看:眼珠对齐的方式是 bottomLeft,左眼纵向方向上稍微往下移一点;右眼往左移动一定的位置,这样就会有向左看的效果了;

  • seeLeft = false,向右看:眼珠对齐的方式是 bottomRight,右眼纵向方向上稍微往下移一点;左眼往右移动一定的位置,这样就会有向右看的效果了;

实现代码如下:

// 左眼
Positioned(
  top: marginTop,
  left: marginLR,
  childAnimatedContainer(
    alignment:
        seeLeft ? Alignment.bottomLeft : Alignment.bottomRight,
    padding: EdgeInsets.all(eyePadding),
    transform: Matrix4.identity()
      ..translate(
          seeLeft ? 0.0 : sideOffset, seeLeft ? eyeOffset 0.00),
    durationDuration(seconds1),
    curve: Curves.fastOutSlowIn,
    width: eyeSize,
    height: eyeSize,
    decorationBoxDecoration(
      color: Colors.white,
      borderRadius: BorderRadius.circular(eyeSize / 2),
    ),
    childClipOval(
      childContainer(
        color: Colors.black,
        width: eyeBallSize,
        height: eyeBallSize,
      ),
    ),
  ),
),
// 右眼
Positioned(
  top: marginTop,
  right: marginLR,
  childAnimatedContainer(
    alignment:
        seeLeft ? Alignment.bottomLeft : Alignment.bottomRight,
    padding: EdgeInsets.all(eyePadding),
    transform: Matrix4.identity()
      ..translate(seeLeft ? -sideOffset 0.0,
          seeLeft ? 0.0 : eyeOffset, 0),
    durationDuration(seconds1),
    curve: Curves.fastOutSlowIn,
    width: eyeSize,
    height: eyeSize,
    decorationBoxDecoration(
      color: Colors.white,
      borderRadius: BorderRadius.circular(eyeSize / 2),
    ),
    childClipOval(
      childContainer(
        color: Colors.black,
        width: eyeBallSize,
        height: eyeBallSize,
      ),
    ),
  ),
),

这里的眼珠对齐使用的就是AnimatedContainer 的 alignment参数控制,而眼球的位置使用 Matrix4 的平移实现:

Matrix4.identity()
  ..translate(seeLeft ? -sideOffset 0.0, seeLeft ? 0.0 : eyeOffset, 0),

笑脸的实现使用ClipPath,绘制两条弧线就可以了,然后平移的幅度和眼珠保持一致,就可以感觉是转头的效果了,AnimatedContainer 部分的代码如下:

// 笑嘻嘻的嘴巴
Positioned(
  bottom10,
  height40,
  left0,
  childAnimatedContainer(
    alignment:
        seeLeft ? Alignment.bottomLeft : Alignment.bottomRight,
    padding: EdgeInsets.all(4.0),
    transform: Matrix4.identity()
      ..translate(seeLeft ? 25.0 : 35.000),
    durationDuration(seconds1),
    curve: Curves.fastOutSlowIn,
    childClipPath(
      clipperSmileClipPath(),
      childContainer(
        width60,
        height40,
        color: Colors.yellow,
      ),
    ),
  ),
),

笑嘻嘻的嘴巴的裁剪类 SmileClipPath 代码如下:

class SmileClipPath extends CustomClipper<Path{
  @override
  Path getClip(Size size) {
    return Path()
      ..moveTo(00)
      ..arcToPoint(
        Offset(size.width, 0),
        radius: Radius.circular(size.width * 0.55),
        clockwisefalse,
      )
      ..arcToPoint(
        Offset(00),
        radius: Radius.circular(size.width),
        clockwisetrue,
      );
  }

  @override
  bool shouldReclip(covariant CustomClipper<Path> oldClipper) {
    return false;
  }
}

最后,控制状态变量 seeLeft 的变化通过一个按钮点击触发就好了。

floatingActionButton: FloatingActionButton(
  child: Icon(Icons.play_arrow, color: Colors.white),
  onPressed: () {
    setState(() {
      seeLeft = !seeLeft;
    });
  },
),

最终运行效果如下,完整代码已提交至:动画相关代码。

Flutter怎么实现笑嘻嘻的动态表情

关于“Flutter怎么实现笑嘻嘻的动态表情”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识,可以关注亿速云行业资讯频道,小编每天都会为大家更新不同的知识点。

亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI

开发者交流群×