🔖 หมวดบทเรียน: การสร้างปลั๊กอิน Flutter เชื่อมต่อกับ Native Code แบบ reusable
📌 เหมาะสำหรับ: ผู้ที่ต้องการ reusable module สำหรับ native feature เฉพาะ
🎯 เป้าหมาย: สร้าง Flutter plugin แบบกำหนดเองที่ใช้ซ้ำในหลายโปรเจกต์ และแชร์ได้ผ่าน pub.dev หรือ git
🧭 เกริ่นนำ
ปลั๊กอินของ Flutter คือแพ็กเกจที่รวมโค้ด Dart และ native เข้าด้วยกัน เพื่อให้เราสามารถเรียกใช้ฟังก์ชัน native ได้โดยไม่ต้องแก้ไขโค้ดในโปรเจกต์หลัก การสร้าง Plugin เองจะช่วยให้ reusable, maintain ได้ดี และแชร์กับทีม/ชุมชนได้ง่าย
⚙️ สร้าง Plugin ใหม่
flutter create --template=plugin --platforms=android,ios flutter_battery_plugin
โครงสร้างที่ได้:
flutter_battery_plugin/
├── lib/flutter_battery_plugin.dart // API Dart
├── android/src/.../FlutterBatteryPlugin.kt
├── ios/Classes/FlutterBatteryPlugin.swift
🧪 ตัวอย่างโค้ด
lib/flutter_battery_plugin.dart
import 'dart:async';
import 'package:flutter/services.dart';
class FlutterBatteryPlugin {
static const MethodChannel _channel = MethodChannel('flutter_battery_plugin');
static Future<int?> getBatteryLevel() async {
final int? level = await _channel.invokeMethod('getBatteryLevel');
return level;
}
}
android/src/…/FlutterBatteryPlugin.kt
class FlutterBatteryPlugin: FlutterPlugin, MethodCallHandler {
override fun onAttachedToEngine(binding: FlutterPlugin.FlutterPluginBinding) {
val channel = MethodChannel(binding.binaryMessenger, "flutter_battery_plugin")
channel.setMethodCallHandler(this)
}
override fun onMethodCall(call: MethodCall, result: Result) {
if (call.method == "getBatteryLevel") {
val batteryLevel = ... // เหมือนบทที่ 16
result.success(batteryLevel)
} else {
result.notImplemented()
}
}
override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) {}
}
🧪 iOS/Classes/FlutterBatteryPlugin.swift
public class FlutterBatteryPlugin: NSObject, FlutterPlugin {
public static func register(with registrar: FlutterPluginRegistrar) {
let channel = FlutterMethodChannel(name: "flutter_battery_plugin", binaryMessenger: registrar.messenger())
let instance = FlutterBatteryPlugin()
registrar.addMethodCallDelegate(instance, channel: channel)
}
public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
if call.method == "getBatteryLevel" {
// ดึงค่า battery แล้วส่งกลับ
} else {
result(FlutterMethodNotImplemented)
}
}
}
✅ สรุป
- การสร้าง plugin ทำให้ reusable native code ได้ง่าย
- แยก logic native ออกจากโปรเจกต์หลัก ลดความซับซ้อน
- สามารถแชร์ผ่าน pub.dev หรือใช้ผ่าน git dependency ได้
บทถัดไปเราจะไปต่อกับ การทำ Performance Optimization สำหรับ Flutter App