Dev to webs {Coding…}

ร บทเรียนฟรีด้านการพัฒนาซอฟต์แวร์ ที่ครอบคลุมเนื้อหาหลากหลาย ตั้งแต่การเขียนโค้ดพื้นฐานไปจนถึงเทคนิคขั้นสูง

บทที่ 17: การสร้าง Plugin สำหรับใช้งานเอง (Custom Platform Plugin)

🔖 หมวดบทเรียน: การสร้างปลั๊กอิน 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