การสร้าง Custom Transition Animations ใน Flutter
ในบทความที่แล้ว เราได้เรียนรู้เกี่ยวกับการใช้ Slivers เพื่อสร้าง Scrollable Layouts ที่ซับซ้อนและยืดหยุ่น ในบทความนี้ เราจะมาเรียนรู้เกี่ยวกับการสร้าง Custom Transition Animations เพื่อเพิ่มลูกเล่นและความน่าสนใจให้กับแอป Flutter ของคุณ การ Transition Animation ที่ดีสามารถช่วยให้ผู้ใช้เข้าใจการเปลี่ยนแปลงของหน้าจอ และทำให้ประสบการณ์การใช้งานโดยรวมดีขึ้น
ทำความเข้าใจ Transition Animations
Transition Animations คือการเปลี่ยนแปลงที่เกิดขึ้นระหว่างการนำทางจากหน้าจอหนึ่งไปยังอีกหน้าจอหนึ่ง Flutter มี Transition Animation พื้นฐานให้ใช้งานอยู่แล้ว เช่น Fade Transition, Slide Transition, และ Scale Transition แต่ในบางครั้ง เราอาจต้องการ Transition Animation ที่เป็นเอกลักษณ์และสอดคล้องกับแบรนด์ของเราเอง ใน Flutter เราสามารถสร้าง Custom Transition Animations ได้โดยใช้ PageRouteBuilder และ TransitionsBuilder
PageRouteBuilder: หัวใจของการสร้าง Custom Transitions
PageRouteBuilder เป็นคลาสที่ช่วยให้เราสามารถกำหนดลักษณะการนำทาง (Navigation) ของหน้าจอได้อย่างละเอียด รวมถึงกำหนด Transition Animation ที่เราต้องการ PageRouteBuilder รับ parameter ที่สำคัญคือ pageBuilder ซึ่งเป็น function ที่สร้าง Widget ของหน้าจอที่เราต้องการนำทางไป และ transitionsBuilder ซึ่งเป็น function ที่กำหนด Transition Animation ที่จะเกิดขึ้นระหว่างการนำทาง
โครงสร้างพื้นฐานของ PageRouteBuilder:
PageRouteBuilder(
pageBuilder: (context, animation, secondaryAnimation) => YourNextPage(),
transitionsBuilder: (context, animation, secondaryAnimation, child) {
// กำหนด Transition Animation ที่นี่
return child; // หรือ Widget ที่ถูก Wrap ด้วย Animation
},
transitionDuration: Duration(milliseconds: 500), // กำหนดระยะเวลาของ Animation (optional)
)
คำอธิบาย Parameter:
pageBuilder: Function ที่รับBuildContext,Animation<double>(animation), และAnimation<double>(secondaryAnimation) และ return Widget ของหน้าจอที่เราจะนำทางไปtransitionsBuilder: Function ที่รับBuildContext,Animation<double>(animation),Animation<double>(secondaryAnimation), และWidget(child) และ return Widget ที่ถูก Wrap ด้วย AnimationtransitionDuration(optional): กำหนดระยะเวลาของ Transition Animation
TransitionsBuilder: สร้าง Animation ที่คุณต้องการ
transitionsBuilder เป็นส่วนสำคัญในการสร้าง Custom Transition Animations เราสามารถใช้ Animation object ที่ถูกส่งเข้ามาเพื่อควบคุมการเปลี่ยนแปลงของ properties ต่างๆ ของ Widget เช่น opacity, position, scale, rotation, หรือ properties อื่นๆ ที่เราต้องการ
ตัวอย่าง: Fade Transition
PageRouteBuilder(
pageBuilder: (context, animation, secondaryAnimation) => SecondScreen(),
transitionsBuilder: (context, animation, secondaryAnimation, child) {
return FadeTransition(
opacity: animation,
child: child,
);
},
)
ในตัวอย่างนี้ เราใช้ FadeTransition ซึ่งเป็น Widget ที่กำหนด opacity ของ child Widget ตามค่าของ animation object เมื่อ animation มีค่า 0 opacity จะเป็น 0 (transparent) และเมื่อ animation มีค่า 1 opacity จะเป็น 1 (opaque)
ตัวอย่าง: Slide Transition
PageRouteBuilder(
pageBuilder: (context, animation, secondaryAnimation) => SecondScreen(),
transitionsBuilder: (context, animation, secondaryAnimation, child) {
const begin = Offset(1.0, 0.0);
const end = Offset.zero;
const curve = Curves.ease;
var tween = Tween(begin: begin, end: end).chain(CurveTween(curve: curve));
return SlideTransition(
position: animation.drive(tween),
child: child,
);
},
)
ในตัวอย่างนี้ เราใช้ SlideTransition ซึ่งเป็น Widget ที่เลื่อน child Widget จากตำแหน่งเริ่มต้นไปยังตำแหน่งสุดท้าย โดยใช้ animation object และ Tween เพื่อกำหนดการเปลี่ยนแปลงของตำแหน่งตามเวลา
กรณีใช้งานจริง: Custom Slide-In Transition
ลองสร้าง Custom Slide-In Transition ที่เลื่อนหน้าจอใหม่เข้ามาจากด้านล่างขึ้นด้านบน พร้อมกับ Fade-In effect
class CustomSlideInRoute extends PageRouteBuilder {
CustomSlideInRoute({required Widget page})
: super(
pageBuilder: (context, animation, secondaryAnimation) => page,
transitionsBuilder: (context, animation, secondaryAnimation, child) {
const begin = Offset(0.0, 1.0);
const end = Offset.zero;
const curve = Curves.ease;
var tween = Tween(begin: begin, end: end).chain(CurveTween(curve: curve));
return SlideTransition(
position: animation.drive(tween),
child: FadeTransition(
opacity: animation,
child: child,
),
);
},
transitionDuration: Duration(milliseconds: 500),
);
}
// วิธีใช้งาน:
Navigator.push(
context,
CustomSlideInRoute(page: SecondScreen()),
);
ในตัวอย่างนี้ เราสร้างคลาส CustomSlideInRoute ที่ extends PageRouteBuilder และกำหนด Transition Animation ให้เลื่อนหน้าจอขึ้นมาจากด้านล่างพร้อมกับ Fade-In effect จากนั้นเราสามารถใช้ Navigator.push เพื่อนำทางไปยังหน้าจอใหม่โดยใช้ CustomSlideInRoute
ข้อผิดพลาดที่พบบ่อยและการแก้ไข
- Transition Animation ไม่ทำงาน: ตรวจสอบให้แน่ใจว่าคุณได้กำหนด
transitionDurationในPageRouteBuilderหากไม่ได้กำหนด ค่า default คือ 0 ซึ่งจะทำให้ Transition Animation ไม่แสดงผล - Widget ไม่แสดงผล: ตรวจสอบให้แน่ใจว่าคุณได้ return
child(หรือ Widget ที่ถูก Wrap ด้วย Animation) ในtransitionsBuilderหากไม่ได้ return Widget ใดๆ หน้าจอใหม่จะไม่แสดงผล - Animation ดูไม่เป็นธรรมชาติ: ลองปรับค่า
curveในTweenเพื่อให้ Animation ดูเป็นธรรมชาติมากขึ้น Flutter มีCurvesให้เลือกใช้งานมากมาย เช่นCurves.ease,Curves.easeInOut,Curves.bounceIn, และอื่นๆ - ประสิทธิภาพของ Animation ไม่ดี: หาก Animation ซับซ้อนมากเกินไป อาจทำให้แอปทำงานช้าลง ลองลดความซับซ้อนของ Animation หรือใช้
CacheExtentในListViewหรือGridViewเพื่อลดจำนวน Widget ที่ต้อง render
แนวคิดเชิงระบบและ Pattern ทั่วไป
Reusable Transition Animations: สร้าง Custom Transition Animations เป็นคลาสแยกต่างหาก เพื่อให้สามารถนำไปใช้ซ้ำได้ในหลายๆ ส่วนของแอป
Adaptive Transitions: สร้าง Transition Animations ที่แตกต่างกันตาม Platform (Android, iOS) เพื่อให้สอดคล้องกับ User Experience ของแต่ละ Platform
Hero Animations: ใช้ Hero Widgets เพื่อสร้าง Transition Animations ที่เชื่อมโยง Widget ระหว่างหน้าจอสองหน้าจอ ทำให้ Transition ดูลื่นไหลและเป็นธรรมชาติมากขึ้น
สรุป
การสร้าง Custom Transition Animations ใน Flutter เป็นวิธีที่ยอดเยี่ยมในการเพิ่มลูกเล่นและความน่าสนใจให้กับแอปของคุณ โดยใช้ PageRouteBuilder และ TransitionsBuilder เราสามารถกำหนด Transition Animation ที่เป็นเอกลักษณ์และสอดคล้องกับแบรนด์ของเราเองได้ อย่ากลัวที่จะทดลองและสร้างสรรค์ Transition Animations ที่ไม่เหมือนใคร!
ในบทความถัดไป เราจะเรียนรู้เกี่ยวกับการใช้ Rive (Flare) สำหรับ Vector Animations เพื่อสร้าง Animations ที่สวยงามและมีประสิทธิภาพสูง