Animation ขั้นสูงด้วย Implicit และ Explicit Animations ใน Flutter
ในบทความนี้ เราจะมาสำรวจโลกของ Animation ใน Flutter ที่ลึกซึ้งยิ่งขึ้น โดยจะเน้นไปที่ Implicit Animation และ Explicit Animation ซึ่งเป็นเครื่องมือสำคัญในการสร้างประสบการณ์ผู้ใช้ที่น่าดึงดูดและมีชีวิตชีวา หลังจากที่เราได้เรียนรู้การจัดการข้อมูล Asynchronous ด้วย FutureBuilder และ StreamBuilder แล้ว การเพิ่ม Animation จะช่วยให้แอปพลิเคชันของเราดูสมบูรณ์และเป็นมิตรกับผู้ใช้มากขึ้น
ความแตกต่างระหว่าง Implicit และ Explicit Animations
ก่อนที่เราจะลงลึกในรายละเอียด มาทำความเข้าใจความแตกต่างพื้นฐานระหว่าง Implicit Animation และ Explicit Animation กันก่อน:
- Implicit Animation: เป็น Animation ที่เกิดขึ้นโดยอัตโนมัติเมื่อคุณเปลี่ยนค่าของ Properties ของ Widget ตัวอย่างเช่น การเปลี่ยนสีของ
Containerผ่านAnimatedContainer - Explicit Animation: เป็น Animation ที่คุณควบคุมทุกรายละเอียดของการเปลี่ยนแปลงค่า Properties ผ่าน
AnimationControllerและTween
โดยทั่วไป Implicit Animation จะใช้งานง่ายกว่า เหมาะสำหรับ Animation ที่เรียบง่าย ในขณะที่ Explicit Animation ให้ความยืดหยุ่นและการควบคุมที่มากกว่า เหมาะสำหรับ Animation ที่ซับซ้อนและต้องการการปรับแต่ง
Implicit Animations: ความง่ายในการสร้าง Animation
Implicit Animation เป็นวิธีที่ง่ายที่สุดในการเพิ่ม Animation ให้กับ Widget ของคุณใน Flutter Widget หลักที่ใช้ในการสร้าง Implicit Animation คือ AnimatedContainer
AnimatedContainer
AnimatedContainer เป็น Widget ที่คล้ายกับ Container แต่มีความสามารถในการ Animate การเปลี่ยนแปลงของ Properties ต่างๆ เช่น width, height, color, margin, padding และ decoration
ตัวอย่าง: สร้าง Animation การเปลี่ยนสีและขนาดของ Container
import 'package:flutter/material.dart';
class AnimatedContainerExample extends StatefulWidget {
@override
_AnimatedContainerExampleState createState() => _AnimatedContainerExampleState();
}
class _AnimatedContainerExampleState extends State<AnimatedContainerExample> {
double _width = 100;
double _height = 100;
Color _color = Colors.blue;
void _animateContainer() {
setState(() {
_width = _width == 100 ? 200 : 100;
_height = _height == 100 ? 200 : 100;
_color = _color == Colors.blue ? Colors.red : Colors.blue;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('AnimatedContainer Example')),
body: Center(
child: GestureDetector(
onTap: _animateContainer,
child: AnimatedContainer(
duration: Duration(milliseconds: 500),
width: _width,
height: _height,
decoration: BoxDecoration(
color: _color,
borderRadius: BorderRadius.circular(10),
),
curve: Curves.easeInOut,
),
),
),
);
}
}
คำอธิบาย:
- เราสร้าง StatefulWidget ชื่อ
AnimatedContainerExampleเพื่อให้สามารถเปลี่ยนแปลง State ของ Widget ได้ - เรากำหนดตัวแปร
_width,_heightและ_colorเพื่อเก็บค่าปัจจุบันของ Container - ฟังก์ชัน
_animateContainerจะทำการเปลี่ยนแปลงค่าของตัวแปรเหล่านี้ เมื่อมีการ Tap ที่ Container AnimatedContainerจะทำการ Animate การเปลี่ยนแปลงค่าเหล่านี้โดยอัตโนมัติ โดยใช้durationและcurveที่เรากำหนดdurationกำหนดระยะเวลาในการ Animate (ในตัวอย่างนี้คือ 500 milliseconds)curveกำหนดลักษณะการเปลี่ยนแปลง (ในตัวอย่างนี้คือCurves.easeInOutซึ่งเป็นการเปลี่ยนแปลงที่ราบรื่น)
นอกจาก AnimatedContainer แล้ว Flutter ยังมี Implicit Animation Widget อื่นๆ อีกมากมาย เช่น AnimatedOpacity, AnimatedPadding, AnimatedPositioned และ AnimatedDefaultTextStyle ซึ่งแต่ละ Widget จะมี Properties ที่สามารถ Animate ได้แตกต่างกันไป
Explicit Animations: การควบคุม Animation อย่างละเอียด
Explicit Animation ช่วยให้คุณสามารถควบคุมทุกรายละเอียดของการเปลี่ยนแปลงค่า Properties ของ Widget ได้อย่างแม่นยำ ซึ่งจำเป็นต้องใช้ AnimationController และ Tween
AnimationController
AnimationController เป็น Class ที่จัดการ Animation โดยจะควบคุมการเริ่มต้น, หยุด, และการเปลี่ยนแปลงค่าของ Animation
Tween
Tween เป็น Class ที่กำหนดช่วงของการเปลี่ยนแปลงค่าของ Animation ตัวอย่างเช่น คุณสามารถใช้ Tween เพื่อกำหนดให้ค่าของ Animation เปลี่ยนจาก 0.0 เป็น 1.0
AnimatedWidget
AnimatedWidget เป็น Abstract Class ที่ใช้ในการสร้าง Widget ที่มีการเปลี่ยนแปลงตามค่าของ Animation คุณต้อง Override เมธอด build เพื่อสร้าง Widget ที่มีการเปลี่ยนแปลงตามค่าของ Animation
ตัวอย่าง: สร้าง Animation การ Fade In/Out ของ Opacity ด้วย Explicit Animation
import 'package:flutter/material.dart';
class FadeInFadeOut extends StatefulWidget {
@override
_FadeInFadeOutState createState() => _FadeInFadeOutState();
}
class _FadeInFadeOutState extends State<FadeInFadeOut> with SingleTickerProviderStateMixin {
late AnimationController _controller;
late Animation<double> _animation;
@override
void initState() {
super.initState();
_controller = AnimationController(
duration: const Duration(seconds: 2),
vsync: this,
);
_animation = Tween<double>(begin: 0.0, end: 1.0).animate(_controller);
_controller.repeat(reverse: true); // ทำให้ Animation เล่นซ้ำไปมา
}
@override
void dispose() {
_controller.dispose(); // ปล่อย Resource เมื่อ Widget ถูก Destroy
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Fade In/Out Example')),
body: Center(
child: FadeTransition(
opacity: _animation,
child: Padding(
padding: EdgeInsets.all(8),
child: FlutterLogo(size: 150),
),
),
),
);
}
}
คำอธิบาย:
- เราสร้าง StatefulWidget ชื่อ
FadeInFadeOutเพื่อให้สามารถจัดการ Animation ได้ - เราใช้
SingleTickerProviderStateMixinเพื่อให้AnimationControllerสามารถทำงานได้อย่างถูกต้อง - เราสร้าง
AnimationControllerโดยกำหนดduration(ระยะเวลาในการ Animate) และvsync(TickerProvider) - เราสร้าง
Tweenเพื่อกำหนดช่วงของการเปลี่ยนแปลงค่า Opacity จาก 0.0 (โปร่งใส) เป็น 1.0 (ทึบ) - เราใช้
animatemethod ของTweenเพื่อสร้างAnimationโดยส่งAnimationControllerเป็น Argument - เราเรียก
_controller.repeat(reverse: true)เพื่อให้ Animation เล่นซ้ำไปมา - ในเมธอด
buildเราใช้FadeTransitionWidget เพื่อแสดงผล Widget ที่มีการ Fade In/Out โดยส่ง_animationเป็น Argument ให้กับ Propertiesopacity - เราเรียก
_controller.dispose()ในเมธอดdisposeเพื่อปล่อย Resource เมื่อ Widget ถูก Destroy
FadeTransition เป็น Widget ที่ใช้ในการ Animate Opacity โดยใช้ Animation<double> เป็น Input นอกจาก FadeTransition แล้ว Flutter ยังมี Transition Widget อื่นๆ อีกมากมาย เช่น ScaleTransition, RotationTransition, SlideTransition และ SizeTransition ซึ่งแต่ละ Widget จะใช้ Animation ที่มีชนิดข้อมูลแตกต่างกันไป
สรุป
ในบทความนี้ เราได้เรียนรู้เกี่ยวกับ Implicit Animation และ Explicit Animation ใน Flutter โดย Implicit Animation เป็นวิธีที่ง่ายในการเพิ่ม Animation ให้กับ Widget ของคุณ ในขณะที่ Explicit Animation ให้ความยืดหยุ่นและการควบคุมที่มากกว่า
การเลือกใช้ Implicit Animation หรือ Explicit Animation ขึ้นอยู่กับความซับซ้อนของ Animation ที่คุณต้องการสร้าง หากคุณต้องการสร้าง Animation ที่เรียบง่ายและรวดเร็ว Implicit Animation เป็นตัวเลือกที่ดี แต่หากคุณต้องการควบคุมทุกรายละเอียดของการเปลี่ยนแปลงค่า Properties Explicit Animation จะเป็นตัวเลือกที่เหมาะสมกว่า
ในบทความถัดไป เราจะมาเรียนรู้เกี่ยวกับการจัดการ Gesture ด้วย GestureDetector และ Custom Gestures เพื่อให้แอปพลิเคชันของเราตอบสนองต่อการสัมผัสของผู้ใช้ได้อย่างมีประสิทธิภาพ