Get เรียกตัวเองว่าเป็น Microframework ทำหน้าที่ 2 อย่างคือเป็น state management กับเป็น utility package ซึ่งมีเครื่องมือต่างๆ มาให้เราใช้จำนวนมาก ดังนั้นก็ไม่แปลกที่ การใช้ Get ใน Flutter นั้นได้ช่วยให้เราจัดการสิ่งต่างๆ ได้อย่างง่ายดาย
เวลาเราพัฒนาแอปใน Flutter ก็มักมีท่านึงที่ถูกใช้บ่อยๆ ก็คือเราจะสร้าง instance ที่มีเพียงตัวเดียวในแอป แล้วก็แชร์ข้อมูลนี้ทั่วทั้งแอป โดยที่เวลาใช้ก็สามารถอ้างตัว instance ตัวนี้มาใช้ได้เลยจากที่ไหนก็ได้ในแอป ถ้าทำโดยใช้ท่ามาตรฐานตามเอกสารอย่างเป็นทางการของ Flutter เลยก็คือใช้ Provider ที่เป็นหนึ่งใน Flutter Favorite package
ตัวอย่างก็เช่น object ที่เอาไว้เก็บ User info และใช้ร่วมกับ login / logout อะไรพวกนี้ ที่เราจะสร้าง instance ของ user ขึ้นมา 1 ตัวเอาไว้เก็บ user profile แล้วเราก็ทำให้เราสามารถเรียกใช้มันจากไหนก็ได้เพื่อเข้าถึง User profile
Get ไม่ใช่แค่ state manager แต่มันคือ microframework (เขาเรียกตัวเองแบบนี้) ลองมาดู Get ในฐานะ state manager กับแอปง่ายๆ อย่าง counter app ก่อน
import 'package:flutter/material.dart';
import 'package:get/get.dart';
void main() {
runApp(GetMaterialApp(home: Home()));
}
class Counter extends ให้ {
var count = 0.obs;
increment() => count++;
}
class Home extends StatelessWidget {
final counter = Get.put(Counter());
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Obx( () => Text(counter.count.toString())),
RaisedButton(child: Text('Click Me'), onPressed: counter.increment)
],
)),
);
}
}
จากโค้ด จะเห็นว่าเราใช้ GetMaterialApp
แทน MaterialApp
แต่ก็ไม่ได้หมายความว่าเราไม่ได้ใช้ MaterialApp
แบบที่เคยใช้กัน เพราะจริงๆ แล้ว GetMaterialApp
เพียงแต่เข้าไป pre-configure บางอย่างให้เราก่อนเท่านั้น แล้วก็ยังให้ MaterialApp
เป็น child ตามเดิม
หลักๆ แล้ว GetMaterialApp
จะเข้าไปจัดการสิ่งต่างๆ เกี่ยวกับพวก routes, snackbars, internationalization, bottomSheets, dialogs และ high-level api ต่างๆ ที่เกี่ยวข้องกับ routes เท่านั้น แปลว่า ถ้าเราจะใช้ Get แค่ state management หรือ dependency injection เท่านั้น เราก็ไม่จำเป็นต้องใช้ GetMaterialApp
ก็ได้
ส่วนโค้ดข้างในนั้นหมายความว่าอะไร จะอธิบายหลังจากนี้ ต่อไปเรามาดูเรื่อง routes กันต่อ
สร้างหน้าที่ 2 ขึ้นมา ดังนี้
class Second extends StatelessWidget {
final Counter counter = Get.find();
@override
Widget build(context) {
return Scaffold(
appBar: AppBar(title: Text('Second')),
body: Center(child: Text("${counter.count}"))
);
}
}
ในหน้านี้เราจะอ้างถึง counter ตัวเดียวกับหน้าแรก ได้จาก Get.find();
และเอาค่า count ที่อ่านได้มาแสดงไว้กลางจอเพื่อพิสูจน์ว่าดึงค่ามาจาก object ตัวเดียวกันนะ
แล้วเราก็กลับมาแก้ที่หน้า Home
โดยการเพิ่มปุ่มที่กดแล้วให้มันแสดงหน้าที่สอง ดังนี้
RaisedButton(child: Text('Go Second'), onPressed: () => Get.to(Second()))
เท่านี้เมื่อเรากดปุ่มมันก็เปลี่ยนหน้าแล้ว เราแค่บอกไปเลยตรงๆ ว่าให้ไปที่หน้า Second
เท่านั้น แล้ว Get ก็ทำให้
สามเสาหลักของ Get
State Management
แม้แต่ Provider
เองที่เว็บไซต์อย่างเป็นทางการของ Flutter แนะนำให้เราใช้ก็ยังใช้ ChangeNotifier
ทำงานอยู่เบื้องหลัง ซึ่งในหน้าเพจของ Get เองได้อ้างว่าเอกสารของ Flutter เองก็บอกอีกว่าการใช้ ChangeNotifier
นั้นควรใช้กับ listener แค่ 1 ถึง 2 ตัวเท่านั้น (ตอนนี้เข้าไปหาดูไม่เจอแล้ว) ดังนั้น Provider
จึงไม่น่าจะเหมาะกับแอปขนาดกลางถึงขนาดใหญ่
มาถึงตอนนี้ก็อย่างที่บอกไป คือมันเป็น micro framework ไม่ใช่แค่ state management แปลว่าเราจะเลือกใช้เพียงอย่างใดอย่างหนึ่งก็ได้ แล้วแต่ความเหมาะสม
Reactive programming นับเป็นยาขมสำหรับ programmer หลายๆ คนเลย หลายคนบอกว่า งง ซึ่งมันก็ งง จริงๆ 😅 แต่ Get ทำให้เราใช้ Reactive programming ได้ในท่าที่ง่ายๆ อย่างน้อยเราก็เอาไปพูดให้ dev คนอื่นฟังว่าเราก็ใช้ได้พอไม่ขัดเขิน
เช่น เรามีตัวแปรแบบนี้
var count = 0.obs;
หากเราต้องการกำหนดว่า เมื่อค่าในตัวแปรนี้เปลี่ยนให้มาบอกเราด้วย เราก็จะใส่ .obs
ต่อท้ายตัวแปรลงไปแบบนี้
var count = 0.obs;
ถ้าเราเอาค่าในตัวแปรนี้ไปแสดงใน GUI ก็ทำแบบนี้ แล้วเราก็จะได้ Text ที่อัพเดทตัวเองอยู่เสมอตามค่าใน attribute count
Obx(() => Text("${counter.count}"));
Route management
อย่างที่บอกไปว่ามันเป็น microframework ก็เลยทำให้เราสามารถจัดสิ่งๆ ต่างๆ ในแอปได้อย่างง่ายดาย ยกตัวอย่างเช่นการจัดการ route เมื่อเราต้องการเปลี่ยน route ก็ใช้ฟังก์ชั่นนี้
Get.to(NextScreen());
หรือจะปิด Snackbar, dialogs, bottom sheet, หรืออื่นๆ ที่ปกติเราต้องปิดมันด้วยคำสั่ง Navigator.pop(context);
เมื่อเรามี Get เราก็จะเปลี่ยนมาใช้
Get.back();
หรือถ้าอยากจะแสดงหน้าถัดไปแต่ไม่ให้แสดงปุ่ม back เช่น เมื่อ user กด logout แล้วเราต้องการแสดงหน้า login เราก็ใช้แบบนี้
Get.off(NextScreen());
หรือจะแสดงหน้าถัดไปและยกเลิกทุกๆ route ที่เคยเปิดมา Get ก็ทำให้เรา
Get.offAll(NextScreen());
จะเห็นว่าเราไม่ต้องไปยุ่งอะไรกับ context แล้ว เพราะ Get ทำให้ เราแล้วตั้งแต่ขั้นตอนการ pre-configure
Dependency Management
แทนที่เราจะสร้าง object ของ Counter
ขึ้นมาเองตรงๆ เราก็สร้างมันโดยใช้ Get เพื่อที่จะทำให้เราสามารถอ้างถึง counter ในแอปจากที่ไหนก็ได้
const Counter counter = Get.put(Counter());
...
counter.increment();
ตอนอ้างถึง counter
Counter counter = Get.find();
พอได้ reference มาแล้ว เราสามารถเอา counter ไปใช้งานได้เลยตรงๆ แบบนี้
Text("${counter.count}"
นอกจากนี้ Get ยังมี Utils ต่างๆ ให้ใช้อีกมาก ลองไปตามต่อกันได้ที่ get | Flutter Package
การพัฒนาแอปด้วย Flutter นั้นหลายอย่างค่อนข้างเรียบง่าย ตั้งแต่การกำหนดให้ flutter รันแยก environment ได้ แล้วยังมีเรื่อง state management กับ utils ต่างๆ ที่ Get ทำมาให้เราใช้อีก หวังว่า การใช้ Get ใน Flutter นั้นจะทำให้เราทำแอปได้รวดเร็วขึ้นไปอีกขั้น
มาถึงตรงนี้คงไม่ต้องอธิบายโค้ดที่ยกมาตอนแรกแล้ว ว่ามันทำงานยังไง
1 comment
[…] Coding […]
Comments are closed.