Flutter开发进阶之Package

Flutter开发进阶之Package

通常我们在Flutter开发中需要将部分功能与整体项目隔离,一般有两种方案Plugin和Package,Application是作为主体项目,Module是作为原生项目接入Flutter模块。

当独立模块不需要与原生项目通讯只需要Plugin就可以,但是当需要与原生通讯就需要Package。

一、创建Package

python 复制代码
cd /Users/kevin/Desktop/My

flutter create --org com.kevin --template=plugin --platforms=android,ios -a kotlin -i swift  package_demo

创建Package必须指定平台:

android、ios、web、linux、macos 和 windows。

命令中-a后是指定Android的开发语言,-i是指定iOS的开发语言。

二、通讯

Package会自动创建MethodChannel,还可以根据需要创建BasicMessageChannel和EventChannel。

Flutter
dart 复制代码
class MethodChannelPackageDemo extends PackageDemoPlatform {
  /// The method channel used to interact with the native platform.
  @visibleForTesting
  final methodChannel = const MethodChannel('package_demo_method');
  final messageChannel = const BasicMessageChannel('package_demo_message', 
      StandardMessageCodec());
  final eventChannel = const EventChannel('package_demo_event');

  MethodChannelPackageDemo() {
    methodChannel.setMethodCallHandler((call) async {
      /// 方法
      return call.method;
    });
    messageChannel.setMessageHandler((message) async {
      /// 字符串和半结构化
      return message;
    });
    eventChannel.receiveBroadcastStream().listen((event) {
      /// 事件流
    }, onError: (error) {
      ///
    }, cancelOnError: true,);

  }
  
  @override
  Future<String?> getPlatformVersion() async {
    final version = await methodChannel.invokeMethod<String>('getPlatformVersion');
    return version;
  }
}
iOS
swift 复制代码
public class PackageDemoPlugin: NSObject, FlutterPlugin {
  public static func register(with registrar: FlutterPluginRegistrar) {
    let methodChannel = FlutterMethodChannel(name: "package_demo_method", binaryMessenger: registrar
    .messenger())
    let instance = PackageDemoPlugin()
    registrar.addMethodCallDelegate(instance, channel: methodChannel)
  }

  public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
    switch call.method {
    case "getPlatformVersion":
      result("iOS " + UIDevice.current.systemVersion)
    default:
      result(FlutterMethodNotImplemented)
    }
  }
}
Android
kotlin 复制代码
class PackageDemoPlugin: FlutterPlugin, MethodCallHandler {
  /// The MethodChannel that will the communication between Flutter and native Android
  ///
  /// This local reference serves to register the plugin with the Flutter Engine and unregister it
  /// when the Flutter Engine is detached from the Activity
  private lateinit var methodChannel : MethodChannel

  override fun onAttachedToEngine(flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
    methodChannel = MethodChannel(flutterPluginBinding.binaryMessenger, "package_demo_method")
    methodChannel.setMethodCallHandler(this)
  }

  override fun onMethodCall(call: MethodCall, result: Result) {
    if (call.method == "getPlatformVersion") {
      result.success("Android ${android.os.Build.VERSION.RELEASE}")
    } else {
      result.notImplemented()
    }
  }

  override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) {
    channel.setMethodCallHandler(null)
  }
}

三、调用原生控件

Flutter
dart 复制代码
class PackageView extends StatelessWidget {
  const PackageView({super.key});

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    if (Platform.isAndroid) {
      return AndroidView(
        viewType: 'package_demo/android',
        onPlatformViewCreated: (id) {},
        creationParams: const {'type': 'android'},
        creationParamsCodec: const StandardMessageCodec(),
      );
    } else if (Platform.isIOS) {
      return UiKitView(
        viewType: 'package_demo/ios',
        onPlatformViewCreated: (id) {},
        creationParams: const {'type': 'ios'},
        creationParamsCodec: const StandardMessageCodec(),
      );
    }
    return const SizedBox();
  }
}
iOS
swift 复制代码
public class PackageDemoPlugin: NSObject, FlutterPlugin {
  public static func register(with registrar: FlutterPluginRegistrar) {
    let methodChannel = FlutterMethodChannel(name: "package_demo_method", binaryMessenger: registrar
    .messenger())
    let instance = PackageDemoPlugin()
    registrar.addMethodCallDelegate(instance, channel: methodChannel)
    registrar.register(PackageViewFactory(), withId: "package_demo/ios")
  }

  public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
    switch call.method {
    case "getPlatformVersion":
      result("iOS " + UIDevice.current.systemVersion)
    default:
      result(FlutterMethodNotImplemented)
    }
  }
}

class PackageViewFactory: NSObject, FlutterPlatformViewFactory {
    
    func create(withFrame frame: CGRect, viewIdentifier viewId: Int64, arguments args: Any?) -> FlutterPlatformView {
        return PackageView()
    }
    
    func createArgsCodec() -> FlutterMessageCodec & NSObjectProtocol {
        return FlutterStandardMessageCodec.sharedInstance()
    }
    
}

class PackageView: NSObject, FlutterPlatformView {
    
    func view() -> UIView {
        return UIView()
    }
    
}
Android
kotlin 复制代码
class PackageDemoPlugin: FlutterPlugin, MethodCallHandler {
  /// The MethodChannel that will the communication between Flutter and native Android
  ///
  /// This local reference serves to register the plugin with the Flutter Engine and unregister it
  /// when the Flutter Engine is detached from the Activity
  private lateinit var methodChannel : MethodChannel

  override fun onAttachedToEngine(flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
    methodChannel = MethodChannel(flutterPluginBinding.binaryMessenger, "package_demo_method")
    methodChannel.setMethodCallHandler(this)
    flutterPluginBinding.platformViewRegistry.registerViewFactory("package_demo/android", PackageViewFactory());
  }

  override fun onMethodCall(call: MethodCall, result: Result) {
    if (call.method == "getPlatformVersion") {
      result.success("Android ${android.os.Build.VERSION.RELEASE}")
    } else {
      result.notImplemented()
    }
  }

  override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) {
    methodChannel.setMethodCallHandler(null)
  }
}

class PackageViewFactory: PlatformViewFactory(StandardMessageCodec.INSTANCE){

    override fun create(context: Context?, viewId: Int, args: Any?): PlatformView {
        return PackageView(context)
    }

}

class PackageView internal constructor(context: Context?): PlatformView{

    override fun getView(): View? {
        TODO("Not yet implemented")
    }

    override fun dispose() {
        TODO("Not yet implemented")
    }

}

四、添加进项目

Package创建成功后可以放置在本地或者上传到github,通过path:或者git: \n url: \n ref: 去添加进项目,通过指定版本去建立依赖。

相关推荐
雨白1 小时前
Jetpack系列(二):Lifecycle与LiveData结合,打造响应式UI
android·android jetpack
kk爱闹3 小时前
【挑战14天学完python和pytorch】- day01
android·pytorch·python
每次的天空4 小时前
Android-自定义View的实战学习总结
android·学习·kotlin·音视频
恋猫de小郭5 小时前
Flutter Widget Preview 功能已合并到 master,提前在体验毛坯的预览支持
android·flutter·ios
断剑重铸之日6 小时前
Android自定义相机开发(类似OCR扫描相机)
android
随心最为安6 小时前
Android Library Maven 发布完整流程指南
android
岁月玲珑6 小时前
【使用Android Studio调试手机app时候手机老掉线问题】
android·ide·android studio
还鮟10 小时前
CTF Web的数组巧用
android
点金石游戏出海10 小时前
每周资讯 | Krafton斥资750亿日元收购日本动画公司ADK;《崩坏:星穹铁道》新版本首日登顶iOS畅销榜
游戏·ios·业界资讯·apple·崩坏星穹铁道
小蜜蜂嗡嗡11 小时前
Android Studio flutter项目运行、打包时间太长
android·flutter·android studio