中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Android?Flutter怎么實現彈簧動畫交互

發布時間:2023-04-28 15:28:05 來源:億速云 閱讀:144 作者:iii 欄目:開發技術

本篇內容主要講解“Android Flutter怎么實現彈簧動畫交互”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“Android Flutter怎么實現彈簧動畫交互”吧!

1.創建一個動畫控制器

首頁創建一個測試使用的Demo頁面

void main() {
  runApp(const MaterialApp(home: PhysicsCardDragDemo()));
}
class PhysicsCardDragDemo extends StatelessWidget {
  const PhysicsCardDragDemo({super.key});
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: const DraggableCard(
        child: FlutterLogo(
          size: 128,
        ),
      ),
    );
  }
}

DraggableCard 是自定義的一個 StatefulWidget,代碼如下:

class _DraggableCardState extends State<DraggableCard> {
  @override
  void initState() {
    super.initState();
  }
  @override
  void dispose() {
    super.dispose();
  }
  @override
  Widget build(BuildContext context) {
    return Align(
      child: Card(
        child: widget.child,
      ),
    );
  }
}

然后在 _DraggableCardState 中創建一個動畫控制器,并在頁面銷毀的時候釋放動畫控制器,代碼如下:

class _DraggableCardState extends State<DraggableCard>
    with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  @override
  void initState() {
    super.initState();
    _controller =  AnimationController(vsync: this, duration: const Duration(seconds: 1));
  }
  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }
  @override
  Widget build(BuildContext context) {
    return Align(
      child: Card(
        child: widget.child,
      ),
    );
  }
}

SingleTickerProviderStateMixin是用來在StatefulWidget中管理單個AnimationController的Mixin;它提供了一個TickerProvider,用于將AnimationController與TickerProviderStateMixin一起使用。

TickerProviderStateMixin提供了一個Ticker,它可以在每個frame中調用AnimationController的方法,這使得AnimationController可以在每個frame中更新動畫。

2.使用手勢移動Widget

在 _DraggableCardState 中,結合使用 Alignment 與 GestureDetector,代碼如下:

class _DraggableCardState extends State<DraggableCard>
    with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  Alignment _dragAlignment = const Alignment(0, 0);
  @override
  Widget build(BuildContext context) {
    var size = MediaQuery.of(context).size;
    return GestureDetector(
      onPanDown: (details) {},
      onPanUpdate: (details) {
        _dragAlignment += Alignment(
          details.delta.dx / (size.width / 2),
          details.delta.dy / (size.height / 2),
        );
        setState(() {
        });
      },
      onPanEnd: (details) {},
      child: Align(
        alignment: _dragAlignment,
        child: Card(
          child: widget.child,
        ),
      ),
    );
  }

GestureDetector用來檢測手勢,例如輕觸、滑動、拖動等,可以用來實現各種交互效果。

Alignment用于控制子widget在父widget中的位置。可以通過Alignment的構造函數來指定子widget相對于父widget的位置,如Alignment.topLeft表示子widget位于父widget的左上角。也可以通過FractionalOffset來指定子widget相對于父widget的位置,如FractionalOffset(0.5, 0.5)表示子widget位于父widget的中心。Alignment還可以與Stack一起使用,實現多個子widget的定位。

Android?Flutter怎么實現彈簧動畫交互

3.創建一個動畫Widget

我們需要實現,當手指抬起時,被移動的 Widget 動畫的方式彈回去。

在這里需要一個 Animation ,再定義一個 runAnimation 方法,同時為 第一步創建的動畫控制器添加一個更新監聽。

class _DraggableCardState extends State<DraggableCard>
    with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  late Animation<Alignment> _animation;
  @override
  void initState() {
    super.initState();
    _controller =
        AnimationController(vsync: this, duration: const Duration(seconds: 1));
    _controller.addListener(() {
      setState(() {
        _dragAlignment = _animation.value;
      });
    });
  }
  void _runAnimation() {
    _animation = _controller.drive(
      AlignmentTween(
        begin: _dragAlignment,
        end: Alignment.center,
      ),
    );
    _controller.reset();
    _controller.forward();
  }
 }

然后在手指抬起的時候,執行動畫,將被移動的 Widget (如這里的圖片)以動畫的方式移動回原位:

@override
  Widget build(BuildContext context) {
    var size = MediaQuery.of(context).size;
    return GestureDetector(
      onPanDown: (details) {
        _controller.stop();
      },
      onPanUpdate: (details) {
        _dragAlignment += Alignment(
          details.delta.dx / (size.width / 2),
          details.delta.dy / (size.height / 2),
        );
        setState(() {
        });
      },
      onPanEnd: (details) {
        _runAnimation();
      },
      child: Align(
        alignment: _dragAlignment,
        child: Card(
          child: widget.child,
        ),
      ),
    );
  }

Android?Flutter怎么實現彈簧動畫交互

4.計算速度以模擬彈簧運動

最后一步是做一些數學運算,計算小部件完成拖動后的速度。這是為了使小部件在被拍回之前能夠以這種速度逼真地繼續。(_runAnimation方法已經通過設置動畫的開始和結束對齊來設置方向。)

導入包如下:

import 'package:flutter/physics.dart';

onPanEnd回調提供了一個DragEndDetails對象。此對象提供指針停止接觸屏幕時的速度。速度以像素每秒為單位,但Align小部件不使用像素。它使用介于[-1.0,-1.0]和[1.0,1.0]之間的坐標值,其中[0.0,0.0]表示中心。步驟2中計算的大小用于將像素轉換為該范圍內的坐標值。

然后修改 runAnimation 執行動畫函數如下:

void _runAnimation(Offset pixelsPerSecond, Size size) {
    _animation = _controller.drive(
      AlignmentTween(
        begin: _dragAlignment,
        end: Alignment.center,
      ),
    );
    final unitsPerSecondX = pixelsPerSecond.dx / size.width;
    final unitsPerSecondY = pixelsPerSecond.dy / size.height;
    final unitsPerSecond = Offset(unitsPerSecondX, unitsPerSecondY);
    final unitVelocity = unitsPerSecond.distance;
   //它可以用于模擬彈簧的阻尼、質量和剛度等屬性,從而實現更加真實的動畫效果。
    const spring = SpringDescription(
      mass: 30,
      stiffness: 1,
      damping: 1,
    );
    //SpringSimulation用來模擬一個彈簧的運動,可以用于創建具有彈性的動畫效果。
    final simulation = SpringSimulation(spring, 0, 1, -unitVelocity);
    _controller.animateWith(simulation);
  }

然后在手指抬起的時候調用

onPanEnd: (details) {
    _runAnimation(details.velocity.pixelsPerSecond, size);
  },

Android?Flutter怎么實現彈簧動畫交互

到此,相信大家對“Android Flutter怎么實現彈簧動畫交互”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

五原县| 喀喇沁旗| 高要市| 本溪| 晋宁县| 鹤壁市| 龙游县| 新巴尔虎左旗| 利辛县| 治多县| 灵山县| 河西区| 屏山县| 贵德县| 安义县| 永仁县| 娱乐| 樟树市| 吴川市| 通海县| 宁武县| 长春市| 奉新县| 蚌埠市| 上饶县| 塔河县| 穆棱市| 奈曼旗| 哈巴河县| 大竹县| 临武县| 南陵县| 民和| 门头沟区| 泽普县| 桃源县| 昆山市| 大邑县| 辽宁省| 南宁市| 澄江县|