This commit is contained in:
2024-11-17 16:01:34 +08:00
commit 7d68ed0f6c
250 changed files with 8930 additions and 0 deletions

View File

@ -0,0 +1,82 @@
library foundation_fluttify;
export 'src/extension/image_provider.x.dart';
export 'src/function/functions.dart';
export 'src/object/obejcts.dart';
export 'src/type/core/array.dart';
export 'src/type/core/broadcast_event_channel.dart';
export 'src/type/core/fluttify_message_codec.dart';
export 'src/type/core/ref.dart';
export 'src/type/core/typedefs.dart';
export 'src/type/platform/android_type/android/app/activity.dart';
export 'src/type/platform/android_type/android/app/application.dart';
export 'src/type/platform/android_type/android/app/notification.dart';
export 'src/type/platform/android_type/android/app/pending_intent.dart';
export 'src/type/platform/android_type/android/content/broadcast_receiver.dart';
export 'src/type/platform/android_type/android/content/content_provider.dart';
export 'src/type/platform/android_type/android/content/context.dart';
export 'src/type/platform/android_type/android/content/intent.dart';
export 'src/type/platform/android_type/android/content/intent_filter.dart';
export 'src/type/platform/android_type/android/graphics/bitmap.dart';
export 'src/type/platform/android_type/android/graphics/drawable/drawable.dart';
export 'src/type/platform/android_type/android/graphics/point.dart';
export 'src/type/platform/android_type/android/graphics/point_f.dart';
export 'src/type/platform/android_type/android/location/location.dart';
export 'src/type/platform/android_type/android/opengl/gl_surface_view.dart';
export 'src/type/platform/android_type/android/os/binder.dart';
export 'src/type/platform/android_type/android/os/bundle.dart';
export 'src/type/platform/android_type/android/os/parcelable.dart';
export 'src/type/platform/android_type/android/util/pair.dart';
export 'src/type/platform/android_type/android/view/motion_event.dart';
export 'src/type/platform/android_type/android/view/surface_holder.dart';
export 'src/type/platform/android_type/android/view/surface_view.dart';
export 'src/type/platform/android_type/android/view/view.dart';
export 'src/type/platform/android_type/android/view/view_group.dart';
export 'src/type/platform/android_type/android/widget/frame_layout.dart';
export 'src/type/platform/android_type/android/widget/image_view.dart';
export 'src/type/platform/android_type/android/widget/linear_layout.dart';
export 'src/type/platform/android_type/android/widget/relative_layout.dart';
export 'src/type/platform/android_type/android/widget/text_view.dart';
export 'src/type/platform/android_type/java/io/closeable.dart';
export 'src/type/platform/android_type/java/io/file.dart';
export 'src/type/platform/android_type/java/io/serializable.dart';
export 'src/type/platform/android_type/java/lang/object.dart';
export 'src/type/platform/android_type/java/lang/throwable.dart';
export 'src/type/platform/android_type/org/json/json_object.dart';
export 'src/type/platform/ios_type/av_audio_session_category_options.dart';
export 'src/type/platform/ios_type/ca_action.dart';
export 'src/type/platform/ios_type/ca_animation.dart';
export 'src/type/platform/ios_type/ca_basic_animation.dart';
export 'src/type/platform/ios_type/ca_media_timing.dart';
export 'src/type/platform/ios_type/ca_property_animation.dart';
export 'src/type/platform/ios_type/cg_point.dart';
export 'src/type/platform/ios_type/cg_rect.dart';
export 'src/type/platform/ios_type/cg_size.dart';
export 'src/type/platform/ios_type/ns_coding.dart';
export 'src/type/platform/ios_type/ns_copying.dart';
export 'src/type/platform/ios_type/ns_data.dart';
export 'src/type/platform/ios_type/ns_date.dart';
export 'src/type/platform/ios_type/ns_error.dart';
export 'src/type/platform/ios_type/ns_mutable_copying.dart';
export 'src/type/platform/ios_type/ns_object.dart';
export 'src/type/platform/ios_type/ns_operation.dart';
export 'src/type/platform/ios_type/ns_url.dart';
export 'src/type/platform/ios_type/ns_user_activity.dart';
export 'src/type/platform/ios_type/ns_value.dart';
export 'src/type/platform/ios_type/ui_application.dart';
export 'src/type/platform/ios_type/ui_application_shortcut_item.dart';
export 'src/type/platform/ios_type/ui_bar_style.dart';
export 'src/type/platform/ios_type/ui_color.dart';
export 'src/type/platform/ios_type/ui_control.dart';
export 'src/type/platform/ios_type/ui_edge_insets.dart';
export 'src/type/platform/ios_type/ui_image.dart';
export 'src/type/platform/ios_type/ui_image_view.dart';
export 'src/type/platform/ios_type/ui_status_bar_style.dart';
export 'src/type/platform/ios_type/ui_user_notification_settings.dart';
export 'src/type/platform/ios_type/ui_view.dart';
export 'src/type/platform/ios_type/ui_view_controller.dart';
export 'src/type/widget/android_opengl_GLSurfaceView.widget.dart';
export 'src/type/widget/android_view_SurfaceView.widget.dart';
export 'src/type/widget/android_widget_FrameLayout.widget.dart';
export 'src/type/widget/scoped_release_pool.widget.dart';
export 'src/type/widget/ui_view.widget.dart';

View File

@ -0,0 +1,36 @@
import 'dart:async';
import 'dart:typed_data';
import 'dart:ui';
import 'package:flutter/material.dart';
Map<String, Uint8List> _cache = {};
extension ImageProviderX on ImageProvider {
Future<Uint8List> toImageData(ImageConfiguration config) async {
final completer = Completer<Uint8List>();
final key = await obtainKey(config);
if (_cache.containsKey(key.toString())) {
debugPrint('命中缓存');
completer.complete(_cache[key.toString()]);
} else {
late ImageStreamListener listener;
ImageStream stream = resolve(config); //获取图片流
listener = ImageStreamListener((imageInfo, sync) async {
final byteData =
await imageInfo.image.toByteData(format: ImageByteFormat.png);
final result = byteData?.buffer.asUint8List();
if (result != null) {
_cache[key.toString()] = result;
}
if (!completer.isCompleted) completer.complete(result);
stream.removeListener(listener); //移除监听
});
stream.addListener(listener);
}
return completer.future;
}
}

View File

@ -0,0 +1,255 @@
import 'dart:async';
import 'dart:io';
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import '../../foundation_fluttify.dart';
typedef _FutureCallback<T> = Future<T> Function(Set<Ref?> releasePool);
bool _enableFluttifyLog = true;
Future<void> enableFluttifyLog(bool enable) {
_enableFluttifyLog = enable;
return kMethodChannel.invokeMethod('PlatformService::enableLog', {
'enable': enable,
});
}
bool get fluttifyLogEnabled => _enableFluttifyLog;
Future<T> platform<T>({
_FutureCallback<T>? android,
_FutureCallback<T>? ios,
}) async {
// 方法单位的释放池, 如果需要的时候可以在这里直接释放, 不使用这个释放池的话可以使用[ScopedReleasePool]
final releasePool = <Ref?>{};
try {
if (android != null && Platform.isAndroid) {
return await android(releasePool);
} else if (ios != null && Platform.isIOS) {
return await ios(releasePool);
} else {
return Future.value();
}
} catch (e) {
return Future.error(e);
} finally {
if (releasePool.isNotEmpty) {
await releasePool.whereType<Ref>().release_batch();
releasePool.clear();
// remove all local object from global object pool
gGlobalReleasePool.removeAll(releasePool);
}
}
}
Future<void> clearHeap() async {
await kMethodChannel.invokeMethod('PlatformService::clearHeap');
}
Future<void> pushStack(String name, Ref ref) async {
await kMethodChannel.invokeMethod(
'PlatformService::pushStack',
{'name': name, '__this__': ref},
);
}
Future<void> pushStackJsonable(String name, dynamic jsonable) async {
await kMethodChannel.invokeMethod('PlatformService::pushStackJsonable', {
'name': name,
'data': jsonable,
});
}
Future<void> clearStack() async {
await kMethodChannel.invokeMethod('PlatformService::clearStack');
}
Future<void> setupOrientationSensor() async {
await kMethodChannel.invokeMethod('PlatformService::setupOrientationSensor');
}
Future<void> startActivity(
String activityClass, {
Map<String, dynamic> extras = const {},
}) async {
assert(activityClass.isNotEmpty);
await kMethodChannel.invokeMethod(
'PlatformService::startActivity',
{'activityClass': activityClass, 'extras': extras},
);
}
Future<android_content_Intent> startActivityForResult(
String activityClass, {
required int requestCode,
Map<String, dynamic> extras = const {},
}) async {
assert(activityClass.isNotEmpty);
final result = await kMethodChannel.invokeMethod(
'PlatformService::startActivityForResult',
{
'activityClass': activityClass,
'extras': extras,
'requestCode': requestCode,
},
);
return android_content_Intent()
..refId = result
..tag__ = 'platform';
}
Future<void> presentViewController(
String viewControllerClass, {
bool withNavigationController = false,
}) async {
assert(viewControllerClass.isNotEmpty);
await kMethodChannel.invokeMethod(
'PlatformService::presentViewController',
{
'viewControllerClass': viewControllerClass,
'withNavigationController': withNavigationController,
},
);
}
/// viewId转换为refId
///
/// 使用这个方法前, 保存PlatformView是把viewId作为key保存在Map中, 带来了不一致性.
/// 使用这个方法把viewId转换为对应PlatformView对象的refId, 使其与普通对象的行为保持一致.
Future<String?> viewId2RefId(String viewId) async {
return kMethodChannel.invokeMethod(
'PlatformService::viewId2RefId',
{'viewId': viewId},
);
}
/// 不怎么好用
@deprecated
Future<String?> getAssetPath(String flutterAssetPath) async {
return kMethodChannel.invokeMethod(
'PlatformService::getAssetPath',
{'flutterAssetPath': flutterAssetPath},
);
}
void log(String content) {
if (fluttifyLogEnabled) debugPrint(content);
}
T? FoundationFluttifyAndroidAs<T>(dynamic __this__) {
if (T == android_content_Context) {
return (android_content_Context()..refId = (__this__ as Ref).refId) as T;
} else if (T == android_content_Intent) {
return (android_content_Intent()..refId = (__this__ as Ref).refId) as T;
} else if (T == android_content_ContentProvider) {
return (android_content_ContentProvider()..refId = (__this__ as Ref).refId)
as T;
} else if (T == android_app_Application) {
return (android_app_Application()..refId = (__this__ as Ref).refId) as T;
} else if (T == android_app_Notification) {
return (android_app_Notification()..refId = (__this__ as Ref).refId) as T;
} else if (T == android_app_Activity) {
return (android_app_Activity()..refId = (__this__ as Ref).refId) as T;
} else if (T == android_app_PendingIntent) {
return (android_app_PendingIntent()..refId = (__this__ as Ref).refId) as T;
} else if (T == android_os_Bundle) {
return (android_os_Bundle()..refId = (__this__ as Ref).refId) as T;
} else if (T == android_os_Binder) {
return (android_os_Binder()..refId = (__this__ as Ref).refId) as T;
} else if (T == android_view_View) {
return (android_view_View()..refId = (__this__ as Ref).refId) as T;
} else if (T == android_view_SurfaceView) {
return (android_view_SurfaceView()..refId = (__this__ as Ref).refId) as T;
} else if (T == android_view_SurfaceHolder) {
return (android_view_SurfaceHolder.subInstance()
..refId = (__this__ as Ref).refId) as T;
} else if (T == android_opengl_GLSurfaceView) {
return (android_opengl_GLSurfaceView()..refId = (__this__ as Ref).refId)
as T;
} else if (T == android_view_View_OnApplyWindowInsetsListener) {
return (android_view_View_OnApplyWindowInsetsListener.subInstance()
..refId = (__this__ as Ref).refId) as T;
} else if (T == android_view_ViewGroup) {
return (android_view_ViewGroup()..refId = (__this__ as Ref).refId) as T;
} else if (T == android_graphics_Point) {
return (android_graphics_Point()..refId = (__this__ as Ref).refId) as T;
} else if (T == android_graphics_PointF) {
return (android_graphics_PointF()..refId = (__this__ as Ref).refId) as T;
} else if (T == android_graphics_Bitmap) {
return (android_graphics_Bitmap()..refId = (__this__ as Ref).refId) as T;
} else if (T == android_widget_ImageView) {
return (android_widget_ImageView()..refId = (__this__ as Ref).refId) as T;
} else if (T == java_io_Serializable) {
return (java_io_Serializable.subInstance()..refId = (__this__ as Ref).refId)
as T;
} else if (T == java_io_File) {
return (java_io_File()..refId = (__this__ as Ref).refId) as T;
} else if (T == android_location_Location) {
return (android_location_Location()..refId = (__this__ as Ref).refId) as T;
} else if (T == android_view_MotionEvent) {
return (android_view_MotionEvent()..refId = (__this__ as Ref).refId) as T;
} else if (T == android_graphics_drawable_Drawable) {
return (android_graphics_drawable_Drawable()
..refId = (__this__ as Ref).refId) as T;
} else if (T == android_widget_FrameLayout) {
return (android_widget_FrameLayout()..refId = (__this__ as Ref).refId) as T;
} else if (T == android_widget_TextView) {
return (android_widget_TextView()..refId = (__this__ as Ref).refId) as T;
} else if (T == android_widget_LinearLayout) {
return (android_widget_LinearLayout()..refId = (__this__ as Ref).refId)
as T;
} else if (T == android_widget_RelativeLayout) {
return (android_widget_RelativeLayout()..refId = (__this__ as Ref).refId)
as T;
} else if (T == android_os_Parcelable) {
return (android_os_Parcelable.subInstance()
..refId = (__this__ as Ref).refId) as T;
} else if (T == android_util_Pair) {
return (android_util_Pair()..refId = (__this__ as Ref).refId) as T;
} else {
return null;
}
}
T? FoundationFluttifyIOSAs<T>(dynamic __this__) {
if (T == CGRect) {
return (CGRect()..refId = (__this__ as Ref).refId) as T;
} else if (T == CGPoint) {
return (CGPoint()..refId = (__this__ as Ref).refId) as T;
} else if (T == CGSize) {
return (CGSize()..refId = (__this__ as Ref).refId) as T;
} else if (T == UIEdgeInsets) {
return (UIEdgeInsets()..refId = (__this__ as Ref).refId) as T;
} else if (T == NSError) {
return (NSError()..refId = (__this__ as Ref).refId) as T;
} else if (T == NSCoding) {
return (NSCoding.subInstance()..refId = (__this__ as Ref).refId) as T;
} else if (T == NSCopying) {
return (NSCopying.subInstance()..refId = (__this__ as Ref).refId) as T;
} else if (T == NSMutableCopying) {
return (NSMutableCopying.subInstance()..refId = (__this__ as Ref).refId)
as T;
} else if (T == UIView) {
return (UIView()..refId = (__this__ as Ref).refId) as T;
} else if (T == UIViewController) {
return (UIViewController()..refId = (__this__ as Ref).refId) as T;
} else if (T == UIControl) {
return (UIControl()..refId = (__this__ as Ref).refId) as T;
} else if (T == UIImage) {
return (UIImage()..refId = (__this__ as Ref).refId) as T;
} else if (T == UIImageView) {
return (UIImageView()..refId = (__this__ as Ref).refId) as T;
} else if (T == UIColor) {
return (UIColor()..refId = (__this__ as Ref).refId) as T;
} else if (T == NSData) {
return (NSData()..refId = (__this__ as Ref).refId) as T;
} else if (T == NSDate) {
return (NSDate()..refId = (__this__ as Ref).refId) as T;
} else if (T == NSOperation) {
return (NSOperation()..refId = (__this__ as Ref).refId) as T;
} else {
return null;
}
}

197
lib/src/object/obejcts.dart Normal file
View File

@ -0,0 +1,197 @@
import 'package:flutter/services.dart';
import 'package:foundation_fluttify/foundation_fluttify.dart';
import 'package:foundation_fluttify/src/type/core/ref.dart';
import 'package:foundation_fluttify/src/type/core/stack.dart';
import 'package:foundation_fluttify/src/type/core/typedefs.dart';
/// native object release pool, all objects returned by the native side will be in this set
final gGlobalReleasePool = <Ref>{};
final gReleasePoolStack = Stack<ScopedReleasePoolState>();
const kMethodChannelName = 'com.fluttify/foundation_method';
const kMethodCodec = StandardMethodCodec(FluttifyMessageCodec());
final kMethodChannel = MethodChannel(kMethodChannelName, kMethodCodec)
..setMethodCallHandler((call) async {
final method = call.method;
final arguments = call.arguments as Map<String, dynamic>;
final application = UIApplication()..refId = arguments['application'];
switch (method) {
case 'applicationDidFinishLaunchingWithOptions':
if (applicationDidFinishLaunchingWithOptions != null) {
final launchOptions = arguments['launchOptions'] as Map;
applicationDidFinishLaunchingWithOptions!(application, launchOptions);
}
break;
case 'applicationWillFinishLaunchingWithOptions':
if (applicationWillFinishLaunchingWithOptions != null) {
final launchOptions = arguments['launchOptions'] as Map;
applicationWillFinishLaunchingWithOptions!(
application, launchOptions);
}
break;
case 'applicationDidBecomeActive':
if (applicationDidBecomeActive != null) {
applicationDidBecomeActive!(application);
}
break;
case 'applicationWillResignActive':
if (applicationWillResignActive != null) {
applicationWillResignActive!(application);
}
break;
case 'applicationDidEnterBackground':
if (applicationDidEnterBackground != null) {
applicationDidEnterBackground!(application);
}
break;
case 'applicationWillEnterForeground':
if (applicationWillEnterForeground != null) {
applicationWillEnterForeground!(application);
}
break;
case 'applicationWillTerminate':
if (applicationWillTerminate != null) {
applicationWillTerminate!(application);
}
break;
case 'applicationDidRegisterUserNotificationSettings':
if (applicationDidRegisterUserNotificationSettings != null) {
final notificationSettings = UIUserNotificationSettings()
..refId = arguments['notificationSettings'];
applicationDidRegisterUserNotificationSettings!(
application, notificationSettings);
}
break;
case 'applicationDidRegisterForRemoteNotificationsWithDeviceToken':
if (applicationDidRegisterForRemoteNotificationsWithDeviceToken !=
null) {
final deviceToken = NSData()..refId = arguments['deviceToken'];
applicationDidRegisterForRemoteNotificationsWithDeviceToken!(
application, deviceToken);
}
break;
case 'applicationDidReceiveRemoteNotificationFetchCompletionHandler':
if (applicationDidReceiveRemoteNotificationFetchCompletionHandler !=
null) {
final userInfo = arguments['userInfo'] as Map;
applicationDidReceiveRemoteNotificationFetchCompletionHandler!(
application, userInfo);
}
break;
case 'applicationOpenURLOptions':
if (applicationOpenURLOptions != null) {
final url = NSURL()..refId = arguments['url'];
final options = (arguments['options'] as Map).cast<String, dynamic>();
applicationOpenURLOptions!(application, url, options);
}
break;
case 'applicationHandleOpenURL':
if (applicationHandleOpenURL != null) {
final url = NSURL()..refId = arguments['url'];
applicationHandleOpenURL!(application, url);
}
break;
case 'applicationOpenURLSourceApplicationAnnotation':
if (applicationOpenURLSourceApplicationAnnotation != null) {
final openURL = NSURL()..refId = arguments['openURL'];
final sourceApplication = arguments['sourceApplication'] as String;
final annotation = NSObject()..refId = arguments['annotation'];
applicationOpenURLSourceApplicationAnnotation!(
application,
openURL,
sourceApplication,
annotation,
);
}
break;
case 'applicationPerformActionForShortcutItemCompletionHandler':
if (applicationPerformActionForShortcutItemCompletionHandler != null) {
final shortcutItem = UIApplicationShortcutItem()
..refId = arguments['shortcutItem'];
applicationPerformActionForShortcutItemCompletionHandler!(
application, shortcutItem);
}
break;
case 'applicationHandleEventsForBackgroundURLSessionCompletionHandler':
if (applicationHandleEventsForBackgroundURLSessionCompletionHandler !=
null) {
final identifier = arguments['identifier'] as String;
applicationHandleEventsForBackgroundURLSessionCompletionHandler!(
application, identifier);
}
break;
case 'applicationPerformFetchWithCompletionHandler':
applicationPerformFetchWithCompletionHandler?.call(application);
break;
case 'applicationContinueUserActivityRestorationHandler':
if (applicationContinueUserActivityRestorationHandler != null) {
final userActivity = NSUserActivity()
..refId = arguments['userActivity'];
applicationContinueUserActivityRestorationHandler!(
application, userActivity);
}
break;
default:
return Future.error('not implemented');
}
});
const kBroadcastEventChannelName = 'com.fluttify/foundation_broadcast_event';
const kBroadcastEventChannel =
FluttifyBroadcastEventChannel(kBroadcastEventChannelName);
const kSensorEventChannelName = 'com.fluttify/foundation_sensor_event';
const kSensorEventChannel = EventChannel(kSensorEventChannelName);
ApplicationDidFinishLaunchingWithOptions?
applicationDidFinishLaunchingWithOptions;
ApplicationWillFinishLaunchingWithOptions?
applicationWillFinishLaunchingWithOptions;
ApplicationDidBecomeActive? applicationDidBecomeActive;
ApplicationWillResignActive? applicationWillResignActive;
ApplicationDidEnterBackground? applicationDidEnterBackground;
ApplicationWillEnterForeground? applicationWillEnterForeground;
ApplicationWillTerminate? applicationWillTerminate;
ApplicationDidRegisterUserNotificationSettings?
applicationDidRegisterUserNotificationSettings;
ApplicationDidRegisterForRemoteNotificationsWithDeviceToken?
applicationDidRegisterForRemoteNotificationsWithDeviceToken;
ApplicationDidReceiveRemoteNotificationFetchCompletionHandler?
applicationDidReceiveRemoteNotificationFetchCompletionHandler;
ApplicationOpenURLOptions? applicationOpenURLOptions;
ApplicationHandleOpenURL? applicationHandleOpenURL;
ApplicationOpenURLSourceApplicationAnnotation?
applicationOpenURLSourceApplicationAnnotation;
ApplicationPerformActionForShortcutItemCompletionHandler?
applicationPerformActionForShortcutItemCompletionHandler;
ApplicationHandleEventsForBackgroundURLSessionCompletionHandler?
applicationHandleEventsForBackgroundURLSessionCompletionHandler;
ApplicationPerformFetchWithCompletionHandler?
applicationPerformFetchWithCompletionHandler;
ApplicationContinueUserActivityRestorationHandler?
applicationContinueUserActivityRestorationHandler;

View File

@ -0,0 +1,5 @@
class Array<T> {
Array.ofList(this.data);
final List<T> data;
}

View File

@ -0,0 +1,13 @@
import 'package:flutter/services.dart';
import 'package:foundation_fluttify/src/type/platform/android_type/android/content/intent.dart';
class FluttifyBroadcastEventChannel extends EventChannel {
const FluttifyBroadcastEventChannel(String name) : super(name);
@override
Stream<android_content_Intent> receiveBroadcastStream([dynamic arguments]) {
return super
.receiveBroadcastStream(arguments)
.map((event) => android_content_Intent()..refId = event);
}
}

View File

@ -0,0 +1,210 @@
import 'dart:convert';
import 'dart:io';
import 'dart:typed_data';
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:foundation_fluttify/foundation_fluttify.dart';
import 'package:foundation_fluttify/src/type/core/array.dart';
class FluttifyMessageCodec extends StandardMessageCodec {
const FluttifyMessageCodec({
this.tag,
this.androidCaster,
this.iosCaster,
});
final String? tag;
/// 外部传入造型回调, 自动把Ref转换为目标对象
/// foundation内部还是手动处理
final dynamic Function(dynamic ref, String typeName)? androidCaster;
final dynamic Function(dynamic ref, String typeName)? iosCaster;
static const int _valueNull = 0;
static const int _valueTrue = 1;
static const int _valueFalse = 2;
static const int _valueInt32 = 3;
static const int _valueInt64 = 4;
static const int _valueLargeInt = 5;
static const int _valueFloat64 = 6;
static const int _valueString = 7;
static const int _valueUint8List = 8;
static const int _valueInt32List = 9;
static const int _valueInt64List = 10;
static const int _valueFloat64List = 11;
static const int _valueList = 12;
static const int _valueMap = 13;
// Fluttify使用 Android only
static const int _valueArray = 125;
// Fluttify使用
static const int _valueEnum = 126;
// 虽然dart端说明自定义类型要用128以上的值, 但是Java那边是用byte接收, 128已经超出, 所以
// 这里直接使用127了, 肯定不会与flutter本身的类型冲突
static const int _valueRef = 127;
@override
void writeValue(WriteBuffer buffer, dynamic value) {
if (value == null || (value is Ref && value.refId == null)) {
buffer.putUint8(_valueNull);
} else if (value is bool) {
buffer.putUint8(value ? _valueTrue : _valueFalse);
} else if (value is double) {
// Double precedes int because in JS everything is a double.
// Therefore in JS, both `is int` and `is double` always
// return `true`. If we check int first, we'll end up treating
// all numbers as ints and attempt the int32/int64 conversion,
// which is wrong. This precedence rule is irrelevant when
// decoding because we use tags to detect the type of value.
buffer.putUint8(_valueFloat64);
buffer.putFloat64(value);
} else if (value is int) {
if (-0x7fffffff - 1 <= value && value <= 0x7fffffff) {
buffer.putUint8(_valueInt32);
buffer.putInt32(value);
} else {
buffer.putUint8(_valueInt64);
buffer.putInt64(value);
}
} else if (value is String) {
buffer.putUint8(_valueString);
final Uint8List bytes = utf8.encoder.convert(value);
writeSize(buffer, bytes.length);
buffer.putUint8List(bytes);
} else if (value is Uint8List) {
buffer.putUint8(_valueUint8List);
writeSize(buffer, value.length);
buffer.putUint8List(value);
} else if (value is Int32List) {
buffer.putUint8(_valueInt32List);
writeSize(buffer, value.length);
buffer.putInt32List(value);
} else if (value is Int64List) {
buffer.putUint8(_valueInt64List);
writeSize(buffer, value.length);
buffer.putInt64List(value);
} else if (value is Float64List) {
buffer.putUint8(_valueFloat64List);
writeSize(buffer, value.length);
buffer.putFloat64List(value);
} else if (value is Array) {
buffer.putUint8(_valueArray);
writeSize(buffer, value.data.length);
for (final dynamic item in value.data) {
writeValue(buffer, item);
}
} else if (value is Iterable) {
buffer.putUint8(_valueList);
writeSize(buffer, value.length);
for (final dynamic item in value) {
writeValue(buffer, item);
}
} else if (value is Map) {
buffer.putUint8(_valueMap);
writeSize(buffer, value.length);
value.forEach((dynamic key, dynamic value) {
writeValue(buffer, key);
writeValue(buffer, value);
});
}
// 以下为fluttify增加的类型
// 枚举 传递索引值
else if (value is Enum) {
buffer.putUint8(_valueEnum);
buffer.putInt32(value.index);
}
// fluttify Ref类
else if (value is Ref) {
buffer.putUint8(_valueRef);
final Uint8List bytes = utf8.encoder.convert(value.refId!);
writeSize(buffer, bytes.length);
buffer.putUint8List(bytes);
} else {
throw ArgumentError.value(value);
}
}
@override
dynamic readValueOfType(int type, ReadBuffer buffer) {
switch (type) {
case _valueNull:
return null;
case _valueTrue:
return true;
case _valueFalse:
return false;
case _valueInt32:
return buffer.getInt32();
case _valueInt64:
return buffer.getInt64();
case _valueFloat64:
return buffer.getFloat64();
case _valueLargeInt:
case _valueString:
final int length = readSize(buffer);
return utf8.decoder.convert(buffer.getUint8List(length));
case _valueUint8List:
final int length = readSize(buffer);
return buffer.getUint8List(length);
case _valueInt32List:
final int length = readSize(buffer);
return buffer.getInt32List(length);
case _valueInt64List:
final int length = readSize(buffer);
return buffer.getInt64List(length);
case _valueFloat64List:
final int length = readSize(buffer);
return buffer.getFloat64List(length);
case _valueArray:
final int length = readSize(buffer);
final dynamic result =
List<dynamic>.filled(length, null, growable: false);
for (int i = 0; i < length; i++) {
result[i] = readValue(buffer);
}
return result;
case _valueList:
final int length = readSize(buffer);
final dynamic result =
List<dynamic>.filled(length, null, growable: false);
for (int i = 0; i < length; i++) {
result[i] = readValue(buffer);
}
return result;
case _valueMap:
final int length = readSize(buffer);
final dynamic result = <dynamic, dynamic>{};
for (int i = 0; i < length; i++) {
result[readValue(buffer)] = readValue(buffer);
}
return result;
case _valueEnum:
return buffer.getInt32();
case _valueRef:
final int length = readSize(buffer);
final String refId = utf8.decoder.convert(buffer.getUint8List(length));
Ref ref = Ref()
..refId = refId
..tag__ = tag;
if (Platform.isAndroid && androidCaster != null) {
ref = androidCaster!(ref, refId.split(':')[0]);
} else if (Platform.isIOS && iosCaster != null) {
ref = iosCaster!(ref, refId.split(':')[0]);
}
// 如果有ScopedReleasePool, 则使用ScopedReleasePool里的释放池
// 否则使用全局的释放池
if (gReleasePoolStack.peek() != null) {
log('添加对象 $ref 到局部释放池');
gReleasePoolStack.peek()?.add(ref);
} else {
log('添加对象 $ref 到全局释放池');
gGlobalReleasePool.add(ref);
}
return ref;
default:
throw const FormatException('Message corrupted');
}
}
}

195
lib/src/type/core/ref.dart Normal file
View File

@ -0,0 +1,195 @@
import 'package:foundation_fluttify/src/object/obejcts.dart';
class Ref {
/// unique id of native side counterpart object
String? refId;
/// custom tag
String? tag__;
/// 释放当前引用对象
Future<void> release__() async {
// 这里使用refId去删除元素, 因为PlatformView和普通对象的键不同, 不是hashCode, 原生端不能
// 通过获取hash的方式删除元素
await kMethodChannel
.invokeMethod('PlatformService::release', {'__this__': refId});
}
Future<bool?> isNull() {
return kMethodChannel
.invokeMethod('PlatformService::isNull', {'__this__': this});
}
/// 通过反射调用方法
Future<void> performSelectorWithObject__(String selector, Object object) {
return kMethodChannel
.invokeMethod('PlatformService::performSelectorWithObject', {
'__this__': this,
'selector': selector,
'object': object,
});
}
/// 为类型添加属性
Future<void> addProperty__(int propertyKey, Ref property) async {
assert(property is Ref);
assert(propertyKey > 0);
return kMethodChannel.invokeMethod('PlatformService::addProperty', {
'__this__': this,
'propertyKey': propertyKey,
'property': property,
});
}
/// 为类型添加属性
Future<void> addListProperty__(int propertyKey, List<Ref> property) async {
assert(propertyKey > 0);
return kMethodChannel.invokeMethod('PlatformService::addListProperty', {
'__this__': this,
'propertyKey': propertyKey,
'property': property,
});
}
/// 获取添加字段的值
Future<Ref> getProperty__(int propertyKey) async {
assert(propertyKey > 0);
final result =
await kMethodChannel.invokeMethod('PlatformService::getProperty', {
'__this__': this,
'propertyKey': propertyKey,
});
return Ref()..refId = result;
}
/// 为类型添加jsonable属性
Future<void> addJsonableProperty__(int propertyKey, Object property) async {
assert(propertyKey > 0);
assert(property is String ||
property is int ||
property is double ||
property is Map ||
property is List ||
property is bool);
return kMethodChannel.invokeMethod('PlatformService::addJsonableProperty', {
'__this__': this,
'propertyKey': propertyKey,
'property': property,
});
}
/// 获取添加字段的jsonable值
Future<dynamic> getJsonableProperty__(int propertyKey) async {
assert(propertyKey > 0);
return kMethodChannel.invokeMethod('PlatformService::getJsonableProperty', {
'__this__': this,
'propertyKey': propertyKey,
});
}
/// 转换为批处理
List<T> asBatch<T extends Ref>(int length) {
assert(length > 0);
return List.filled(length, this as T);
}
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is Ref && runtimeType == other.runtimeType && refId == other.refId;
@override
int get hashCode => refId.hashCode;
@override
String toString() {
return 'Ref{refId: $refId, runtimeType: $runtimeType, tag__: $tag__}';
}
}
extension Ref_Batch on Iterable<Ref> {
// 这里使用refId去删除元素, 因为PlatformView和普通对象的键不同, 不是hashCode, 原生端不能
// 通过获取hash的方式删除元素
Future<void> release_batch() async {
return kMethodChannel.invokeMethod(
'PlatformService::release_batch',
{'__this_batch__': map((e) => e.refId).toList()},
);
}
}
extension RefList_Batch on List<Ref> {
/// 为类型添加属性
Future<void> addProperty_batch(int propertyKey, List<Ref> property) async {
assert(property is List<Ref>);
return kMethodChannel.invokeMethod(
'PlatformService::addProperty_batch',
[
for (int i = 0; i < length; i++)
<String, dynamic>{
'__this__': this[i],
'propertyKey': propertyKey,
'property': property[i],
}
],
);
}
/// 获取添加字段的值
Future<List<Ref>> getProperty_batch(int propertyKey) async {
final List resultBatch = await kMethodChannel.invokeMethod(
'PlatformService::getProperty_batch',
[
for (int i = 0; i < length; i++)
<String, dynamic>{
'__this__': this[i],
'propertyKey': propertyKey,
}
],
);
return resultBatch
.map((refId) => Ref()
..refId = refId
..tag__ = 'platform')
.toList();
}
/// 为类型添加jsonable属性
Future<void> addJsonableProperty_batch(
int propertyKey,
List<Object> property,
) async {
assert(property is List<String> ||
property is List<int> ||
property is List<double> ||
property is List<Map> ||
property is List<List> ||
property is List<bool>);
return kMethodChannel.invokeMethod(
'PlatformService::addJsonableProperty_batch',
[
for (int i = 0; i < length; i++)
<String, dynamic>{
'__this__': this[i],
'propertyKey': propertyKey,
'property': property[i],
}
],
);
}
/// 获取添加字段的jsonable值
Future<List<dynamic>> getJsonableProperty_batch(int propertyKey) async {
final List resultBatch = await kMethodChannel.invokeMethod(
'PlatformService::getJsonableProperty_batch',
[
for (int i = 0; i < length; i++)
<String, dynamic>{
'__this__': this[i],
'propertyKey': propertyKey,
}
],
);
return resultBatch;
}
}

View File

@ -0,0 +1,34 @@
import 'dart:collection';
class Stack<T> {
final ListQueue<T> _list = ListQueue();
/// check if the stack is empty.
bool get isEmpty => _list.isEmpty;
/// check if the stack is not empty.
bool get isNotEmpty => _list.isNotEmpty;
/// push element in top of the stack.
void push(T e) {
_list.addLast(e);
}
/// get the top of the stack and delete it.
T pop() {
T res = _list.last;
_list.removeLast();
return res;
}
/// get the top of the stack without deleting it.
T? peek() {
if (_list.isEmpty) return null;
return _list.last;
}
/// get the size of the stack.
int size() {
return _list.length;
}
}

View File

@ -0,0 +1,181 @@
import 'dart:async';
import 'package:foundation_fluttify/foundation_fluttify.dart';
import 'package:foundation_fluttify/src/type/platform/ios_type/ui_application.dart';
typedef FutureVoidCallback = Future<void> Function();
typedef FutureValueChanged<T> = Future<void> Function(T value);
typedef Action0 = FutureOr<void> Function();
typedef Action1<T> = FutureOr<void> Function(T arg0);
typedef Action2<T1, T2> = FutureOr<void> Function(T1 arg0, T2 arg1);
typedef Action3<T1, T2, T3> = FutureOr<void> Function(
T1 arg1, T2 arg2, T3 arg3);
typedef Action4<T1, T2, T3, T4> = FutureOr<void> Function(
T1 arg1,
T2 arg2,
T3 arg3,
T4 arg4,
);
typedef Action5<T1, T2, T3, T4, T5> = FutureOr<void> Function(
T1 arg1,
T2 arg2,
T3 arg3,
T4 arg4,
T5 arg5,
);
typedef Action6<T1, T2, T3, T4, T5, T6> = FutureOr<void> Function(
T1 arg1,
T2 arg2,
T3 arg3,
T4 arg4,
T5 arg5,
T6 arg6,
);
typedef Action7<T1, T2, T3, T4, T5, T6, T7> = FutureOr<void> Function(
T1 arg1,
T2 arg2,
T3 arg3,
T4 arg4,
T5 arg5,
T6 arg6,
T7 arg7,
);
typedef Action8<T1, T2, T3, T4, T5, T6, T7, T8> = FutureOr<void> Function(
T1 arg1,
T2 arg2,
T3 arg3,
T4 arg4,
T5 arg5,
T6 arg6,
T7 arg7,
T8 arg8,
);
typedef Action9<T1, T2, T3, T4, T5, T6, T7, T8, T9> = FutureOr<void> Function(
T1 arg1,
T2 arg2,
T3 arg3,
T4 arg4,
T5 arg5,
T6 arg6,
T7 arg7,
T8 arg8,
T9 arg9,
);
typedef Function0<R> = FutureOr<R> Function();
typedef Function1<T, R> = FutureOr<R> Function(T arg0);
typedef Function2<T1, T2, R> = FutureOr<R> Function(T1 arg0, T2 arg1);
typedef Function3<T1, T2, T3, R> = FutureOr<R> Function(
T1 arg1, T2 arg2, T3 arg3);
typedef Function4<T1, T2, T3, T4, R> = FutureOr<R> Function(
T1 arg1,
T2 arg2,
T3 arg3,
T4 arg4,
);
typedef Function5<T1, T2, T3, T4, T5, R> = FutureOr<R> Function(
T1 arg1,
T2 arg2,
T3 arg3,
T4 arg4,
T5 arg5,
);
typedef Function6<T1, T2, T3, T4, T5, T6, R> = FutureOr<R> Function(
T1 arg1,
T2 arg2,
T3 arg3,
T4 arg4,
T5 arg5,
T6 arg6,
);
typedef Function7<T1, T2, T3, T4, T5, T6, T7, R> = FutureOr<R> Function(
T1 arg1,
T2 arg2,
T3 arg3,
T4 arg4,
T5 arg5,
T6 arg6,
T7 arg7,
);
typedef Function8<T1, T2, T3, T4, T5, T6, T7, T8, R> = FutureOr<R> Function(
T1 arg1,
T2 arg2,
T3 arg3,
T4 arg4,
T5 arg5,
T6 arg6,
T7 arg7,
T8 arg8,
);
typedef Function9<T1, T2, T3, T4, T5, T6, T7, T8, T9, R> = FutureOr<R> Function(
T1 arg1,
T2 arg2,
T3 arg3,
T4 arg4,
T5 arg5,
T6 arg6,
T7 arg7,
T8 arg8,
T9 arg9,
);
typedef ApplicationDidFinishLaunchingWithOptions = void Function(
UIApplication application,
Map options,
);
typedef ApplicationWillFinishLaunchingWithOptions = void Function(
UIApplication application,
Map options,
);
typedef ApplicationDidBecomeActive = void Function(UIApplication application);
typedef ApplicationWillResignActive = void Function(UIApplication application);
typedef ApplicationDidEnterBackground = void Function(
UIApplication application);
typedef ApplicationWillEnterForeground = void Function(
UIApplication application);
typedef ApplicationWillTerminate = void Function(UIApplication application);
typedef ApplicationDidRegisterUserNotificationSettings = void Function(
UIApplication application,
UIUserNotificationSettings notificationSettings,
);
typedef ApplicationDidRegisterForRemoteNotificationsWithDeviceToken = void
Function(
UIApplication application,
NSData deviceToken,
);
typedef ApplicationDidReceiveRemoteNotificationFetchCompletionHandler = void
Function(
UIApplication application,
Map userInfo,
);
typedef ApplicationOpenURLOptions = void Function(
UIApplication application,
NSURL url,
Map<String, dynamic> options,
);
typedef ApplicationHandleOpenURL = void Function(
UIApplication application,
NSURL url,
);
typedef ApplicationOpenURLSourceApplicationAnnotation = void Function(
UIApplication application,
NSURL url,
String sourceApplication,
NSObject annotation,
);
typedef ApplicationPerformActionForShortcutItemCompletionHandler = void
Function(
UIApplication application,
UIApplicationShortcutItem shortcutItem,
);
typedef ApplicationHandleEventsForBackgroundURLSessionCompletionHandler = void
Function(
UIApplication application,
String identifier,
);
typedef ApplicationPerformFetchWithCompletionHandler = void Function(
UIApplication application,
);
typedef ApplicationContinueUserActivityRestorationHandler = void Function(
UIApplication application,
NSUserActivity userActivity,
);

View File

@ -0,0 +1,22 @@
import 'package:foundation_fluttify/foundation_fluttify.dart';
import 'package:foundation_fluttify/src/object/obejcts.dart';
import 'package:foundation_fluttify/src/type/platform/android_type/android/content/context.dart';
import 'package:foundation_fluttify/src/type/platform/android_type/android/content/intent.dart';
// ignore_for_file: non_constant_identifier_names, camel_case_types, missing_return, unused_import
class android_app_Activity extends android_content_Context {
@override
final String tag__ = 'platform';
static Future<android_app_Activity> get() async {
final result =
await kMethodChannel.invokeMethod<Ref>('android.app.Activity::get');
return android_app_Activity()..refId = result?.refId;
}
Future<android_content_Intent> get intent async {
final result = await kMethodChannel.invokeMethod<Ref>(
'android.app.Activity::getIntent', {'__this__': this});
return android_content_Intent()..refId = result?.refId;
}
}

View File

@ -0,0 +1,15 @@
import 'package:foundation_fluttify/foundation_fluttify.dart';
import 'package:foundation_fluttify/src/object/obejcts.dart';
import 'package:foundation_fluttify/src/type/platform/android_type/android/content/context.dart';
// ignore_for_file: non_constant_identifier_names, camel_case_types, missing_return, unused_import
class android_app_Application extends android_content_Context {
@override
final String tag__ = 'platform';
static Future<android_app_Application> get() async {
final result =
await kMethodChannel.invokeMethod<Ref>('android.app.Application::get');
return android_app_Application()..refId = result?.refId;
}
}

View File

@ -0,0 +1,35 @@
import 'package:flutter/cupertino.dart';
import 'package:foundation_fluttify/foundation_fluttify.dart';
import 'package:foundation_fluttify/src/object/obejcts.dart';
import 'package:foundation_fluttify/src/type/platform/android_type/android/content/context.dart';
import 'package:foundation_fluttify/src/type/platform/android_type/android/content/intent.dart';
// ignore_for_file: non_constant_identifier_names, camel_case_types, missing_return, unused_import
class android_app_Notification extends java_lang_Object {
@override
final String tag__ = 'platform';
static Future<android_app_Notification> create({
required String contentTitle,
required String contentText,
int? when,
required String channelId,
required String channelName,
bool enableLights = true,
bool showBadge = true,
}) async {
final result = await kMethodChannel.invokeMethod<Ref>(
'android.app.Notification::create',
{
'contentTitle': contentTitle,
'contentText': contentText,
'when': when ?? DateTime.now().millisecondsSinceEpoch,
'channelId': channelId,
'channelName': channelName,
'enableLights': enableLights,
'showBadge': showBadge,
},
);
return android_app_Notification()..refId = result?.refId;
}
}

View File

@ -0,0 +1,11 @@
import 'package:foundation_fluttify/foundation_fluttify.dart';
import 'package:foundation_fluttify/src/object/obejcts.dart';
import 'package:foundation_fluttify/src/type/platform/android_type/android/content/context.dart';
import 'package:foundation_fluttify/src/type/platform/android_type/android/content/intent.dart';
// ignore_for_file: non_constant_identifier_names, camel_case_types, missing_return, unused_import
class android_app_PendingIntent extends java_lang_Object
with android_os_Parcelable {
@override
final String tag__ = 'platform';
}

View File

@ -0,0 +1,37 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/services.dart';
import 'package:foundation_fluttify/foundation_fluttify.dart';
import 'package:foundation_fluttify/src/object/obejcts.dart';
import 'package:foundation_fluttify/src/type/platform/android_type/java/lang/object.dart';
import 'intent.dart';
// ignore_for_file: non_constant_identifier_names, camel_case_types, missing_return, unused_import
class android_content_BroadcastReceiver extends java_lang_Object {
@override
final String tag__ = 'platform';
Future<android_content_BroadcastReceiver> create(
ValueChanged<android_content_Intent> onReceive,
) async {
final result = await kMethodChannel.invokeMethod<Ref>(
'android.content.Context::registerReceiver',
{
'__this__': this,
'broadcastReceiver': '',
'intentFilter': '',
},
);
MethodChannel('android.content.BroadcastReceiver::create::Callback')
.setMethodCallHandler((call) async {
if (call.method ==
'Callback::android.content.BroadcastReceiver::onReceive') {
final intentRefId = call.arguments['intent'] as String;
final intent = android_content_Intent()..refId = intentRefId;
onReceive(intent);
}
});
return android_content_BroadcastReceiver()..refId = result?.refId;
}
}

View File

@ -0,0 +1,9 @@
import 'package:foundation_fluttify/src/type/platform/android_type/java/lang/object.dart';
// ignore_for_file: non_constant_identifier_names, camel_case_types, missing_return, unused_import
class android_content_ContentProvider extends java_lang_Object {
@override
final String tag__ = 'platform';
}

View File

@ -0,0 +1,28 @@
import 'package:foundation_fluttify/foundation_fluttify.dart';
import 'package:foundation_fluttify/src/object/obejcts.dart';
import 'package:foundation_fluttify/src/type/platform/android_type/java/lang/object.dart';
import 'broadcast_receiver.dart';
import 'intent.dart';
import 'intent_filter.dart';
// ignore_for_file: non_constant_identifier_names, camel_case_types, missing_return, unused_import
class android_content_Context extends java_lang_Object {
@override
final String tag__ = 'platform';
Future<android_content_Intent> registerReceiver(
android_content_BroadcastReceiver receiver,
android_content_IntentFilter intentFilter,
) async {
final result = await kMethodChannel.invokeMethod<Ref>(
'android.content.Context::registerReceiver',
{
'__this__': this,
'broadcastReceiver': receiver,
'intentFilter': intentFilter,
},
);
return android_content_Intent()..refId = result?.refId;
}
}

View File

@ -0,0 +1,23 @@
import 'package:foundation_fluttify/src/object/obejcts.dart';
import 'package:foundation_fluttify/src/type/platform/android_type/android/os/bundle.dart';
import 'package:foundation_fluttify/src/type/platform/android_type/java/lang/object.dart';
// ignore_for_file: non_constant_identifier_names, camel_case_types, missing_return, unused_import
class android_content_Intent extends java_lang_Object {
@override
final String tag__ = 'platform';
Future<Map<String, dynamic>?> get bundle async {
final result = await kMethodChannel.invokeMapMethod<String, dynamic>(
'android.content.Intent::getBundle', {'__this__': this});
return result;
}
Future<String?> get action async {
final result = await kMethodChannel
.invokeMethod('android.content.Intent::getAction', {'__this__': this});
return result;
}
}

View File

@ -0,0 +1,19 @@
import 'package:foundation_fluttify/foundation_fluttify.dart';
import 'package:foundation_fluttify/src/object/obejcts.dart';
import 'package:foundation_fluttify/src/type/platform/android_type/java/lang/object.dart';
import 'intent.dart';
// ignore_for_file: non_constant_identifier_names, camel_case_types, missing_return, unused_import
class android_content_IntentFilter extends java_lang_Object {
@override
final String tag__ = 'platform';
Future<android_content_IntentFilter> create(String action) async {
final result = await kMethodChannel.invokeMethod<Ref>(
'android.content.IntentFilter::create',
{'__this__': this, 'action': action},
);
return android_content_IntentFilter()..refId = result?.refId;
}
}

View File

@ -0,0 +1,57 @@
// ignore_for_file: non_constant_identifier_names, camel_case_types, missing_return, unused_import
import 'dart:typed_data';
import 'package:foundation_fluttify/foundation_fluttify.dart';
import 'package:foundation_fluttify/src/object/obejcts.dart';
import 'package:foundation_fluttify/src/type/platform/android_type/java/lang/object.dart';
class android_graphics_Bitmap extends java_lang_Object {
@override
final String tag__ = 'platform';
static Future<android_graphics_Bitmap> create(Uint8List bitmapBytes) async {
final result = await kMethodChannel.invokeMethod<Ref>(
'android.graphics.Bitmap::create', {'bitmapBytes': bitmapBytes});
return android_graphics_Bitmap()..refId = result?.refId;
}
static Future<android_graphics_Bitmap> createWithDrawable(
String drawableId,
) async {
final result = await kMethodChannel.invokeMethod<Ref>(
'android.graphics.Bitmap::createWithDrawable',
{'drawableId': drawableId},
);
return android_graphics_Bitmap()..refId = result?.refId;
}
static Future<List<android_graphics_Bitmap>?> create_batch(
List<Uint8List> bitmapBytesBatch,
) async {
final resultBatch = await kMethodChannel.invokeListMethod<Ref>(
'android.graphics.Bitmap::create_batch',
[
for (final bitmapBytes in bitmapBytesBatch) {'bitmapBytes': bitmapBytes}
],
);
return resultBatch
?.map((it) => android_graphics_Bitmap()..refId = it.refId)
.toList();
}
Future<Uint8List?> get data {
return kMethodChannel
.invokeMethod('android.graphics.Bitmap::getData', {'__this__': this});
}
Future<void> recycle() {
return kMethodChannel
.invokeMethod('android.graphics.Bitmap::recycle', {'__this__': this});
}
Future<bool?> get isRecycled {
return kMethodChannel.invokeMethod(
'android.graphics.Bitmap::isRecycled', {'__this__': this});
}
}

View File

@ -0,0 +1,7 @@
// ignore_for_file: non_constant_identifier_names, camel_case_types, missing_return, unused_import
import 'package:foundation_fluttify/src/type/platform/android_type/java/lang/object.dart';
class android_graphics_drawable_Drawable extends java_lang_Object {
@override
final String tag__ = 'platform';
}

View File

@ -0,0 +1,28 @@
// ignore_for_file: non_constant_identifier_names, camel_case_types, missing_return, unused_import
import 'dart:typed_data';
import 'package:foundation_fluttify/foundation_fluttify.dart';
import 'package:foundation_fluttify/src/object/obejcts.dart';
import 'package:foundation_fluttify/src/type/platform/android_type/java/lang/object.dart';
class android_graphics_Point extends java_lang_Object {
@override
final String tag__ = 'platform';
static Future<android_graphics_Point> create(int x, int y) async {
final result = await kMethodChannel
.invokeMethod<Ref>('android.graphics.Point::create', {'x': x, 'y': y});
return android_graphics_Point()..refId = result?.refId;
}
Future<int?> get x {
return kMethodChannel
.invokeMethod('android.graphics.Point::getX', {'__this__': this});
}
Future<int?> get y {
return kMethodChannel
.invokeMethod('android.graphics.Point::getY', {'__this__': this});
}
}

View File

@ -0,0 +1,7 @@
// ignore_for_file: non_constant_identifier_names, camel_case_types, missing_return, unused_import
import 'package:foundation_fluttify/src/type/platform/android_type/java/lang/object.dart';
class android_graphics_PointF extends java_lang_Object {
@override
final String tag__ = 'platform';
}

View File

@ -0,0 +1,88 @@
// ignore_for_file: non_constant_identifier_names, camel_case_types, missing_return, unused_import
import 'package:foundation_fluttify/foundation_fluttify.dart';
import 'package:foundation_fluttify/src/object/obejcts.dart';
import 'package:foundation_fluttify/src/type/platform/android_type/java/lang/object.dart';
class android_location_Location extends java_lang_Object {
static Future<android_location_Location> create(String provider) async {
final result = await kMethodChannel.invokeMethod<Ref>(
'android.location.Location::create', {'provider': provider});
return android_location_Location()..refId = result?.refId;
}
@override
final String tag__ = 'platform';
Future<double?> get latitude {
return kMethodChannel.invokeMethod(
'android.location.Location::getLatitude', {'__this__': this});
}
Future<double?> get longitude {
return kMethodChannel.invokeMethod(
'android.location.Location::getLongitude', {'__this__': this});
}
Future<double?> get bearing {
return kMethodChannel.invokeMethod(
'android.location.Location::getBearing', {'__this__': this});
}
Future<double?> get altitude {
return kMethodChannel.invokeMethod(
'android.location.Location::getAltitude', {'__this__': this});
}
Future<double?> get accuracy {
return kMethodChannel.invokeMethod(
'android.location.Location::getAccuracy', {'__this__': this});
}
Future<double?> get speed {
return kMethodChannel.invokeMethod(
'android.location.Location::getSpeed', {'__this__': this});
}
Future<void> setLatitude(double latitude) async {
return kMethodChannel.invokeMethod(
'android.location.Location::setLatitude',
{'__this__': this, 'latitude': latitude},
);
}
Future<void> setLongitude(double longitude) async {
return kMethodChannel.invokeMethod(
'android.location.Location::setLongitude',
{'__this__': this, 'longitude': longitude},
);
}
Future<void> setBearing(double bearing) async {
return kMethodChannel.invokeMethod(
'android.location.Location::setBearing',
{'__this__': this, 'bearing': bearing},
);
}
Future<void> setAltitude(double altitude) async {
return kMethodChannel.invokeMethod(
'android.location.Location::setAltitude',
{'__this__': this, 'altitude': altitude},
);
}
Future<void> setAccuracy(double accuracy) async {
return kMethodChannel.invokeMethod(
'android.location.Location::setAccuracy',
{'__this__': this, 'accuracy': accuracy},
);
}
Future<void> setSpeed(double speed) async {
return kMethodChannel.invokeMethod(
'android.location.Location::setSpeed',
{'__this__': this, 'speed': speed},
);
}
}

View File

@ -0,0 +1,6 @@
import 'package:foundation_fluttify/foundation_fluttify.dart';
class android_opengl_GLSurfaceView extends android_view_SurfaceView {
@override
final String tag__ = 'platform';
}

View File

@ -0,0 +1,7 @@
// ignore_for_file: non_constant_identifier_names, camel_case_types, missing_return, unused_import
import 'package:foundation_fluttify/src/type/platform/android_type/java/lang/object.dart';
class android_os_Binder extends java_lang_Object {
@override
final String tag__ = 'platform';
}

View File

@ -0,0 +1,59 @@
import 'package:foundation_fluttify/foundation_fluttify.dart';
import 'package:foundation_fluttify/src/object/obejcts.dart';
import 'package:foundation_fluttify/src/type/platform/android_type/java/lang/object.dart';
// ignore_for_file: non_constant_identifier_names, camel_case_types, missing_return, unused_import
class android_os_Bundle extends java_lang_Object {
static Future<android_os_Bundle> create() async {
final result =
await kMethodChannel.invokeMethod<Ref>('android.os.Bundle::create');
return android_os_Bundle()..refId = result?.refId;
}
@override
final String tag__ = 'platform';
Future<void> putString(String key, String value) {
return kMethodChannel.invokeMethod('android.os.Bundle::putString', {
'__this__': this,
'key': key,
'value': value,
});
}
Future<void> putInt(String key, int value) {
return kMethodChannel.invokeMethod('android.os.Bundle::putInt', {
'__this__': this,
'key': key,
'value': value,
});
}
Future<String?> getString(String key) {
return kMethodChannel.invokeMethod<String>(
'android.os.Bundle::getString',
{'__this__': this, 'key': key},
);
}
Future<int?> getInt(String key) {
return kMethodChannel.invokeMethod<int>(
'android.os.Bundle::getInt',
{'__this__': this, 'key': key},
);
}
Future<int?> getDouble(String key) {
return kMethodChannel.invokeMethod<int>(
'android.os.Bundle::getDouble',
{'__this__': this, 'key': key},
);
}
Future<int?> getFloat(String key) {
return kMethodChannel.invokeMethod<int>(
'android.os.Bundle::getFloat',
{'__this__': this, 'key': key},
);
}
}

View File

@ -0,0 +1,14 @@
// ignore_for_file: non_constant_identifier_names, camel_case_types, missing_return, unused_import
import 'package:foundation_fluttify/src/type/platform/android_type/java/lang/object.dart';
class _android_os_Parcelable_SUB extends java_lang_Object
with android_os_Parcelable {}
mixin android_os_Parcelable on java_lang_Object {
@override
final String tag__ = 'platform';
static android_os_Parcelable subInstance() {
return _android_os_Parcelable_SUB();
}
}

View File

@ -0,0 +1,21 @@
// ignore_for_file: non_constant_identifier_names, camel_case_types, missing_return, unused_import
import 'package:foundation_fluttify/src/object/obejcts.dart';
import 'package:foundation_fluttify/src/type/platform/android_type/java/lang/object.dart';
class android_util_Pair extends java_lang_Object {
@override
final String tag__ = 'platform';
Future<Object?> get first {
return kMethodChannel
.invokeMethod('android.util.Pair::getFirst', {'__this__': this});
}
Future<Object?> get second {
return kMethodChannel
.invokeMethod('android.util.Pair::getSecond', {'__this__': this});
}
}

View File

@ -0,0 +1,7 @@
// ignore_for_file: non_constant_identifier_names, camel_case_types, missing_return, unused_import
import 'package:foundation_fluttify/src/type/platform/android_type/java/lang/object.dart';
class android_view_MotionEvent extends java_lang_Object {
@override
final String tag__ = 'platform';
}

View File

@ -0,0 +1,71 @@
import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';
import 'package:foundation_fluttify/foundation_fluttify.dart';
class _android_view_SurfaceHolder_SUB extends java_lang_Object
with android_view_SurfaceHolder {}
mixin android_view_SurfaceHolder on java_lang_Object {
static android_view_SurfaceHolder subInstance() =>
_android_view_SurfaceHolder_SUB();
@override
final String tag__ = 'platform';
Future<void> addCallback(
android_view_SurfaceHolder_Callback callback,
) async {
// invoke native method
await kMethodChannel.invokeMethod(
'android.view.SurfaceHolder::addCallback',
{'__this__': this, 'callback': callback},
);
// handle native call
MethodChannel(
'android.view.SurfaceHolder::addCallback::Callback',
kMethodCodec,
).setMethodCallHandler((methodCall) async {
try {
final args = methodCall.arguments as Map?;
switch (methodCall.method) {
case 'Callback::android.view.SurfaceHolder.Callback::surfaceCreated':
callback.surfaceCreated(args!['var1']);
break;
case 'Callback::android.view.SurfaceHolder.Callback::surfaceChanged':
callback.surfaceChanged(
args!['var1'],
args['var2'],
args['var3'],
args['var4'],
);
break;
case 'Callback::android.view.SurfaceHolder.Callback::surfaceDestroyed':
callback.surfaceDestroyed(args!['var1']);
break;
default:
throw MissingPluginException('方法${methodCall.method}未实现');
}
} catch (e) {
debugPrint(e.toString());
rethrow;
}
});
}
}
mixin android_view_SurfaceHolder_Callback on java_lang_Object {
@override
final String tag__ = 'platform';
void surfaceCreated(android_view_SurfaceHolder? var1) {}
void surfaceChanged(
android_view_SurfaceHolder? var1,
int? var2,
int? var3,
int? var4,
) {}
void surfaceDestroyed(android_view_SurfaceHolder? var1) {}
}

View File

@ -0,0 +1,28 @@
import 'package:foundation_fluttify/foundation_fluttify.dart';
class android_view_SurfaceView extends android_view_View {
@override
final String tag__ = 'platform';
Future<android_view_SurfaceHolder> getHolder() async {
final result = await kMethodChannel.invokeMethod<Ref>(
'android.view.SurfaceView::getHolder',
{'__this__': this},
);
return android_view_SurfaceHolder.subInstance()..refId = result?.refId;
}
Future<void> setZOrderOnTop(bool onTop) async {
await kMethodChannel.invokeMethod(
'android.view.SurfaceView::setZOrderOnTop',
{'__this__': this, 'onTop': onTop},
);
}
Future<void> setZOrderMediaOverlay(bool isMediaOverlay) async {
await kMethodChannel.invokeMethod(
'android.view.SurfaceView::setZOrderMediaOverlay',
{'__this__': this, 'isMediaOverlay': isMediaOverlay},
);
}
}

View File

@ -0,0 +1,42 @@
// ignore_for_file: non_constant_identifier_names, camel_case_types, missing_return, unused_import
import 'package:foundation_fluttify/src/object/obejcts.dart';
import 'package:foundation_fluttify/src/type/platform/android_type/java/lang/object.dart';
class android_view_View extends java_lang_Object {
@override
final String tag__ = 'platform';
}
class _android_view_View_OnApplyWindowInsetsListener_SUB
extends java_lang_Object
with android_view_View_OnApplyWindowInsetsListener {
@override
final String tag__ = 'platform';
}
mixin android_view_View_OnApplyWindowInsetsListener on java_lang_Object {
static android_view_View_OnApplyWindowInsetsListener subInstance() =>
_android_view_View_OnApplyWindowInsetsListener_SUB();
@override
final String tag__ = 'platform';
}
class _android_view_View_OnClickListener_SUB extends java_lang_Object
with android_view_View_OnClickListener {}
mixin android_view_View_OnClickListener on java_lang_Object {
static android_view_View_OnClickListener subInstance() =>
_android_view_View_OnClickListener_SUB();
@override
final String tag__ = 'platform';
}
class _android_view_View_OnTouchListener_SUB extends java_lang_Object
with android_view_View_OnTouchListener {}
mixin android_view_View_OnTouchListener on java_lang_Object {
static android_view_View_OnTouchListener subInstance() =>
_android_view_View_OnTouchListener_SUB();
@override
final String tag__ = 'platform';
}

View File

@ -0,0 +1,22 @@
// ignore_for_file: non_constant_identifier_names, camel_case_types, missing_return, unused_import
import 'package:foundation_fluttify/src/object/obejcts.dart';
import 'package:foundation_fluttify/src/type/platform/android_type/android/view/view.dart';
class android_view_ViewGroup extends android_view_View {
@override
final String tag__ = 'platform';
Future<void> addView(android_view_View child) {
return kMethodChannel.invokeMethod(
'android.view.ViewGroup::addView',
{'__this__': this, 'child': child},
);
}
Future<void> removeAllViews() {
return kMethodChannel.invokeMethod(
'android.view.ViewGroup::removeAllViews',
{'__this__': this},
);
}
}

View File

@ -0,0 +1,7 @@
// ignore_for_file: non_constant_identifier_names, camel_case_types, missing_return, unused_import
import 'package:foundation_fluttify/src/type/platform/android_type/android/view/view_group.dart';
class android_widget_FrameLayout extends android_view_ViewGroup {
@override
final String tag__ = 'platform';
}

View File

@ -0,0 +1,18 @@
// ignore_for_file: non_constant_identifier_names, camel_case_types, missing_return, unused_import
import 'package:foundation_fluttify/foundation_fluttify.dart';
import 'package:foundation_fluttify/src/type/platform/android_type/android/view/view.dart';
class android_widget_ImageView extends android_view_View {
@override
final String tag__ = 'platform';
static Future<android_widget_ImageView> createWithBitmap(
android_graphics_Bitmap bitmap,
) async {
final result = await kMethodChannel.invokeMethod<Ref>(
'android.widget.ImageView::createWithBitmap',
{'bitmap': bitmap},
);
return android_widget_ImageView()..refId = result?.refId;
}
}

View File

@ -0,0 +1,7 @@
// ignore_for_file: non_constant_identifier_names, camel_case_types, missing_return, unused_import
import 'package:foundation_fluttify/src/type/platform/android_type/android/view/view_group.dart';
class android_widget_LinearLayout extends android_view_ViewGroup {
@override
final String tag__ = 'platform';
}

View File

@ -0,0 +1,7 @@
// ignore_for_file: non_constant_identifier_names, camel_case_types, missing_return, unused_import
import 'package:foundation_fluttify/src/type/platform/android_type/android/view/view_group.dart';
class android_widget_RelativeLayout extends android_view_ViewGroup {
@override
final String tag__ = 'platform';
}

View File

@ -0,0 +1,7 @@
// ignore_for_file: non_constant_identifier_names, camel_case_types, missing_return, unused_import
import 'package:foundation_fluttify/src/type/platform/android_type/android/view/view.dart';
class android_widget_TextView extends android_view_View {
@override
final String tag__ = 'platform';
}

View File

@ -0,0 +1,16 @@
import 'package:foundation_fluttify/foundation_fluttify.dart';
// ignore_for_file: non_constant_identifier_names, camel_case_types, missing_return, unused_import
class _java_io_Closeable_SUB extends java_lang_Object with java_io_Closeable {
@override
final String tag__ = 'platform';
}
mixin java_io_Closeable on java_lang_Object {
static java_io_Closeable subInstance() {
return _java_io_Closeable_SUB();
}
@override
final String tag__ = 'platform';
}

View File

@ -0,0 +1,13 @@
import 'package:foundation_fluttify/foundation_fluttify.dart';
// ignore_for_file: non_constant_identifier_names, camel_case_types, missing_return, unused_import
class java_io_File extends java_lang_Object {
@override
final String tag__ = 'platform';
static Future<java_io_File> create(String path) async {
final result = await kMethodChannel
.invokeMethod<Ref>('java.io.File::create', {'path': path});
return java_io_File()..refId = result?.refId;
}
}

View File

@ -0,0 +1,17 @@
import 'package:foundation_fluttify/foundation_fluttify.dart';
// ignore_for_file: non_constant_identifier_names, camel_case_types, missing_return, unused_import
class _java_io_Serializable_SUB extends java_lang_Object
with java_io_Serializable {
@override
final String tag__ = 'platform';
}
mixin java_io_Serializable on java_lang_Object {
static java_io_Serializable subInstance() {
return _java_io_Serializable_SUB();
}
@override
final String tag__ = 'platform';
}

View File

@ -0,0 +1,7 @@
import 'package:foundation_fluttify/src/type/core/ref.dart';
// ignore_for_file: non_constant_identifier_names, camel_case_types, missing_return, unused_import
class java_lang_Object extends Ref {
@override
final String tag__ = 'platform';
}

View File

@ -0,0 +1,7 @@
import 'package:foundation_fluttify/src/type/core/ref.dart';
// ignore_for_file: non_constant_identifier_names, camel_case_types, missing_return, unused_import
class java_lang_Throwable extends Ref {
@override
final String tag__ = 'platform';
}

View File

@ -0,0 +1,7 @@
import 'package:foundation_fluttify/src/type/platform/android_type/java/lang/object.dart';
// ignore_for_file: non_constant_identifier_names, camel_case_types, missing_return, unused_import
class org_json_JSONObject extends java_lang_Object {
@override
final String tag__ = 'platform';
}

View File

@ -0,0 +1,26 @@
//typedef NS_OPTIONS(NSUInteger, AVAudioSessionCategoryOptions)
//{
// /* MixWithOthers is only valid with AVAudioSessionCategoryPlayAndRecord, AVAudioSessionCategoryPlayback, and AVAudioSessionCategoryMultiRoute */
// AVAudioSessionCategoryOptionMixWithOthers = 0x1,
// /* DuckOthers is only valid with AVAudioSessionCategoryAmbient, AVAudioSessionCategoryPlayAndRecord, AVAudioSessionCategoryPlayback, and AVAudioSessionCategoryMultiRoute */
// AVAudioSessionCategoryOptionDuckOthers = 0x2,
// /* AllowBluetooth is only valid with AVAudioSessionCategoryRecord and AVAudioSessionCategoryPlayAndRecord */
// AVAudioSessionCategoryOptionAllowBluetooth API_UNAVAILABLE(tvos, watchos, macos) = 0x4,
// /* DefaultToSpeaker is only valid with AVAudioSessionCategoryPlayAndRecord */
// AVAudioSessionCategoryOptionDefaultToSpeaker API_UNAVAILABLE(tvos, watchos, macos) = 0x8,
// /* InterruptSpokenAudioAndMixWithOthers is only valid with AVAudioSessionCategoryPlayAndRecord, AVAudioSessionCategoryPlayback, and AVAudioSessionCategoryMultiRoute */
// AVAudioSessionCategoryOptionInterruptSpokenAudioAndMixWithOthers API_AVAILABLE(ios(9.0), watchos(2.0), tvos(9.0)) API_UNAVAILABLE(macos) = 0x11,
// /* AllowBluetoothA2DP is only valid with AVAudioSessionCategoryPlayAndRecord */
// AVAudioSessionCategoryOptionAllowBluetoothA2DP API_AVAILABLE(ios(10.0), watchos(3.0), tvos(10.0)) API_UNAVAILABLE(macos) = 0x20,
// /* AllowAirPlay is only valid with AVAudioSessionCategoryPlayAndRecord */
// AVAudioSessionCategoryOptionAllowAirPlay API_AVAILABLE(ios(10.0), tvos(10.0)) API_UNAVAILABLE(watchos, macos) = 0x40,
//};
enum AVAudioSessionCategoryOptions {
AVAudioSessionCategoryOptionMixWithOthers,
AVAudioSessionCategoryOptionDuckOthers,
AVAudioSessionCategoryOptionAllowBluetooth,
AVAudioSessionCategoryOptionDefaultToSpeaker,
AVAudioSessionCategoryOptionInterruptSpokenAudioAndMixWithOthers,
AVAudioSessionCategoryOptionAllowBluetoothA2DP,
AVAudioSessionCategoryOptionAllowAirPlay
}

View File

@ -0,0 +1,7 @@
// ignore_for_file: non_constant_identifier_names
import 'package:foundation_fluttify/foundation_fluttify.dart';
mixin CAAction on NSObject {
@override
final String tag__ = 'platform';
}

View File

@ -0,0 +1,9 @@
// ignore_for_file: non_constant_identifier_names
import 'package:foundation_fluttify/foundation_fluttify.dart';
import 'ca_media_timing.dart';
class CAAnimation extends NSObject with NSCopying, CAMediaTiming {
@override
final String tag__ = 'platform';
}

View File

@ -0,0 +1,18 @@
// ignore_for_file: non_constant_identifier_names
import 'ca_property_animation.dart';
class CABasicAnimation extends CAPropertyAnimation {
CABasicAnimation(this.fromValue, this.toValue, this.byValue);
@override
final String tag__ = 'platform';
final dynamic fromValue;
final dynamic toValue;
final dynamic byValue;
@override
String toString() {
return 'CABasicAnimation{fromValue: $fromValue, toValue: $toValue, byValue: $byValue}';
}
}

View File

@ -0,0 +1,52 @@
// ignore_for_file: non_constant_identifier_names
import 'package:foundation_fluttify/foundation_fluttify.dart';
mixin CAMediaTiming on NSObject {
@override
final String tag__ = 'platform';
/// The begin time of the object, in relation to its parent object, if
/// applicable. Defaults to 0.
double? beginTime;
/// The basic duration of the object. Defaults to 0.
double? duration;
/// The rate of the layer. Used to scale parent time to local time, e.g.
/// if rate is 2, local time progresses twice as fast as parent time.
/// Defaults to 1.
double? speed;
/// Additional offset in active local time. i.e. to convert from parent
/// time tp to active local time t: t = (tp - begin) * speed + offset.
/// One use of this is to "pause" a layer by setting `speed' to zero and
/// `offset' to a suitable value. Defaults to 0. */
double? timeOffset;
/// The repeat count of the object. May be fractional. Defaults to 0.
double? repeatCount;
/// The repeat duration of the object. Defaults to 0.
double? repeatDuration;
/// When true, the object plays backwards after playing forwards. Defaults
/// to NO.
bool? autoreverses;
/// Defines how the timed object behaves outside its active duration.
/// Local time may be clamped to either end of the active duration, or
/// the element may be removed from the presentation. The legal values
/// are `backwards', `forwards', `both' and `removed'. Defaults to
/// `removed'.
bool? fillMode;
}
enum CAMediaTimingFillMode {
backwards,
forwards,
both,
removed,
}

View File

@ -0,0 +1,7 @@
// ignore_for_file: non_constant_identifier_names
import 'ca_animation.dart';
class CAPropertyAnimation extends CAAnimation {
@override
final String tag__ = 'platform';
}

View File

@ -0,0 +1,54 @@
// ignore_for_file: non_constant_identifier_names
import 'dart:math';
import 'package:foundation_fluttify/foundation_fluttify.dart';
import 'package:foundation_fluttify/src/object/obejcts.dart';
class CGPoint extends Ref {
@override
final String tag__ = 'platform';
static Future<CGPoint> create(double x, double y) async {
final result = await kMethodChannel
.invokeMethod<Ref>('CGPoint::create', {'x': x, 'y': y});
return CGPoint()..refId = result?.refId;
}
static Future<CGPoint> createWithPoint(Point point) async {
final result = await kMethodChannel
.invokeMethod<Ref>('CGPoint::create', {'x': point.x, 'y': point.y});
return CGPoint()..refId = result?.refId;
}
static Future<List<CGPoint>> create_batch(
List<double> x,
List<double> y,
) async {
final resultBatch = await kMethodChannel
.invokeListMethod<Ref>('CGPoint::create_batch', {'x': x, 'y': y});
return [
for (final item in resultBatch ?? []) CGPoint()..refId = item.refId
];
}
Future<double?> get x {
return kMethodChannel.invokeMethod('CGPoint::getX', {'__this__': this});
}
Future<double?> get y {
return kMethodChannel.invokeMethod('CGPoint::getY', {'__this__': this});
}
}
extension CGPointListX on List<CGPoint> {
Future<List<double>?> get x_batch {
return kMethodChannel
.invokeMethod('CGPoint::getX_batch', {'__this__': this});
}
Future<List<double>?> get y_batch {
return kMethodChannel
.invokeMethod('CGPoint::getY_batch', {'__this__': this});
}
}

View File

@ -0,0 +1,39 @@
// ignore_for_file: non_constant_identifier_names
import 'package:foundation_fluttify/foundation_fluttify.dart';
class CGRect extends Ref {
@override
final String tag__ = 'platform';
static Future<CGRect> create(
double x,
double y,
double width,
double height,
) async {
final result = await kMethodChannel.invokeMethod<Ref>('CGRect::create', {
'x': x,
'y': y,
'width': width,
'height': height,
});
return CGRect()..refId = result?.refId;
}
Future<double?> get x {
return kMethodChannel.invokeMethod('CGRect::getX', {'__this__': this});
}
Future<double?> get y {
return kMethodChannel.invokeMethod('CGRect::getY', {'__this__': this});
}
Future<double?> get width {
return kMethodChannel.invokeMethod('CGRect::getWidth', {'__this__': this});
}
Future<double?> get height {
return kMethodChannel.invokeMethod('CGRect::getHeight', {'__this__': this});
}
}

View File

@ -0,0 +1,27 @@
// ignore_for_file: non_constant_identifier_names
import 'package:foundation_fluttify/foundation_fluttify.dart';
class CGSize extends Ref {
@override
final String tag__ = 'platform';
static Future<CGSize> create(
double width,
double height,
) async {
final result = await kMethodChannel.invokeMethod<Ref>('CGSize::create', {
'width': width,
'height': height,
});
return CGSize()..refId = result?.refId;
}
Future<double?> get width {
return kMethodChannel.invokeMethod('CGSize::getWidth', {'__this__': this});
}
Future<double?> get height {
return kMethodChannel.invokeMethod('CGSize::getHeight', {'__this__': this});
}
}

View File

@ -0,0 +1,12 @@
// ignore_for_file: non_constant_identifier_names
import 'ns_object.dart';
// ignore: camel_case_types
class _NSCoding_SUB extends NSObject with NSCoding {}
mixin NSCoding on NSObject {
@override
final String tag__ = 'platform';
static NSCoding subInstance() => _NSCoding_SUB();
}

View File

@ -0,0 +1,12 @@
// ignore_for_file: non_constant_identifier_names
import 'ns_object.dart';
// ignore: camel_case_types
class _NSCopying_SUB extends NSObject with NSCopying {}
mixin NSCopying on NSObject {
@override
final String tag__ = 'platform';
static NSCopying subInstance() => _NSCopying_SUB();
}

View File

@ -0,0 +1,24 @@
// ignore_for_file: non_constant_identifier_names
import 'dart:typed_data';
import 'package:foundation_fluttify/foundation_fluttify.dart';
import 'package:foundation_fluttify/src/object/obejcts.dart';
class NSData extends NSObject {
@override
final String tag__ = 'platform';
static Future<NSData> createWithUint8List(Uint8List data) async {
final result = await kMethodChannel
.invokeMethod<Ref>('NSData::createWithUint8List', {'data': data});
return NSData()..refId = result?.refId;
}
Future<Uint8List?> getData() {
return kMethodChannel.invokeMethod<Uint8List>(
'NSData::getData',
{'__this__': this},
);
}
}

View File

@ -0,0 +1,19 @@
// ignore_for_file: non_constant_identifier_names
import 'package:foundation_fluttify/foundation_fluttify.dart';
import 'package:foundation_fluttify/src/object/obejcts.dart';
class NSDate extends NSObject {
@override
final String tag__ = 'platform';
/// 时间戳 单位秒
Future<double?> get timeIntervalSince1970 {
return kMethodChannel.invokeMethod<double>(
'NSDate::get_timeIntervalSince1970',
{'__this__': this},
);
}
}

View File

@ -0,0 +1,24 @@
// ignore_for_file: non_constant_identifier_names
import 'package:foundation_fluttify/foundation_fluttify.dart';
import 'ns_object.dart';
class NSError extends NSObject {
@override
final String tag__ = 'platform';
Future<int?> get code async {
final int? errorCode = await kMethodChannel
.invokeMethod('NSError::getCode', {'__this__': this});
return errorCode;
}
Future<String?> get description async {
final String? description = await kMethodChannel
.invokeMethod('NSError::getDescription', {'__this__': this});
return description;
}
}

View File

@ -0,0 +1,11 @@
// ignore_for_file: non_constant_identifier_names
import 'ns_object.dart';
class _NSMutableCopying_SUB extends NSObject with NSMutableCopying {}
mixin NSMutableCopying on NSObject {
static NSMutableCopying subInstance() => _NSMutableCopying_SUB();
@override
final String tag__ = 'platform';
}

View File

@ -0,0 +1,10 @@
// ignore_for_file: non_constant_identifier_names
import 'package:foundation_fluttify/foundation_fluttify.dart';
class NSObject extends Ref {
@override
final String tag__ = 'platform';
}
extension NSObjectListX on List<NSObject> {}

View File

@ -0,0 +1,7 @@
// ignore_for_file: non_constant_identifier_names
import 'ns_object.dart';
class NSOperation extends NSObject {
@override
final String tag__ = 'platform';
}

View File

@ -0,0 +1,7 @@
// ignore_for_file: non_constant_identifier_names
import 'package:foundation_fluttify/foundation_fluttify.dart';
class NSURL extends NSObject {
@override
final String tag__ = 'platform';
}

View File

@ -0,0 +1,7 @@
// ignore_for_file: non_constant_identifier_names
import 'package:foundation_fluttify/foundation_fluttify.dart';
class NSUserActivity extends NSObject {
@override
final String tag__ = 'platform';
}

View File

@ -0,0 +1,7 @@
// ignore_for_file: non_constant_identifier_names
import 'package:foundation_fluttify/foundation_fluttify.dart';
class NSValue extends NSObject with NSCopying {
@override
final String tag__ = 'platform';
}

View File

@ -0,0 +1,7 @@
// ignore_for_file: non_constant_identifier_names
import 'package:foundation_fluttify/foundation_fluttify.dart';
class UIApplication extends NSObject {
@override
final String tag__ = 'platform';
}

View File

@ -0,0 +1,7 @@
// ignore_for_file: non_constant_identifier_names
import 'package:foundation_fluttify/foundation_fluttify.dart';
class UIApplicationShortcutItem extends NSObject {
@override
final String tag__ = 'platform';
}

View File

@ -0,0 +1,4 @@
enum UIBarStyle {
UIBarStyleDefault,
UIBarStyleBlack,
}

View File

@ -0,0 +1,19 @@
// ignore_for_file: non_constant_identifier_names
import 'dart:ui';
import 'package:foundation_fluttify/foundation_fluttify.dart';
import 'package:foundation_fluttify/src/object/obejcts.dart';
import 'ns_object.dart';
class UIColor extends NSObject {
@override
final String tag__ = 'platform';
static Future<UIColor> create(Color color) async {
final result = await kMethodChannel
.invokeMethod<Ref>('UIColor::create', {'colorValue': color.value});
return UIColor()..refId = result?.refId;
}
}

View File

@ -0,0 +1,7 @@
// ignore_for_file: non_constant_identifier_names
import 'ns_object.dart';
class UIControl extends NSObject {
@override
final String tag__ = 'platform';
}

View File

@ -0,0 +1,45 @@
// ignore_for_file: non_constant_identifier_names
import 'package:foundation_fluttify/foundation_fluttify.dart';
import 'package:foundation_fluttify/src/object/obejcts.dart';
class UIEdgeInsets extends Ref {
@override
final String tag__ = 'platform';
static Future<UIEdgeInsets> create(
double top,
double left,
double bottom,
double right,
) async {
final result =
await kMethodChannel.invokeMethod<Ref>('UIEdgeInsets::create', {
'top': top,
'left': left,
'bottom': bottom,
'right': right,
});
return UIEdgeInsets()..refId = result?.refId;
}
Future<double?> get top {
return kMethodChannel
.invokeMethod('UIEdgeInsets::getTop', {'__this__': this});
}
Future<double?> get left {
return kMethodChannel
.invokeMethod('UIEdgeInsets::getLeft', {'__this__': this});
}
Future<double?> get bottom {
return kMethodChannel
.invokeMethod('UIEdgeInsets::getBottom', {'__this__': this});
}
Future<double?> get right {
return kMethodChannel
.invokeMethod('UIEdgeInsets::getRight', {'__this__': this});
}
}

View File

@ -0,0 +1,53 @@
// ignore_for_file: non_constant_identifier_names, camel_case_types, missing_return, unused_import
import 'dart:typed_data';
import 'package:foundation_fluttify/foundation_fluttify.dart';
import 'package:foundation_fluttify/src/object/obejcts.dart';
import 'ns_object.dart';
class UIImage extends NSObject {
@override
final String tag__ = 'platform';
static Future<UIImage> create(Uint8List bitmapBytes) async {
final result = await kMethodChannel.invokeMethod<Ref>(
'UIImage::createUIImage',
{'bitmapBytes': bitmapBytes},
);
return UIImage()..refId = result?.refId;
}
static Future<UIImage> createWithPath(
String resource,
String type,
String fileName,
) async {
final result = await kMethodChannel.invokeMethod<Ref>(
'UIImage::createWithPath',
{
'resource': resource,
'type': type,
'fileName': fileName,
},
);
return UIImage()..refId = result?.refId;
}
static Future<List<UIImage>> create_batch(
List<Uint8List> bitmapBytesBatch,
) async {
final resultBatch = await kMethodChannel.invokeListMethod<Ref>(
'UIImage::createUIImage_batch',
[
for (final bitmapBytes in bitmapBytesBatch) {'bitmapBytes': bitmapBytes}
],
);
return resultBatch?.map((it) => UIImage()..refId = it.refId).toList() ?? [];
}
Future<Uint8List?> get data {
return kMethodChannel.invokeMethod('UIImage::getData', {'__this__': this});
}
}

View File

@ -0,0 +1,19 @@
// ignore_for_file: non_constant_identifier_names
import 'package:foundation_fluttify/foundation_fluttify.dart';
import 'package:foundation_fluttify/src/object/obejcts.dart';
import 'ui_view.dart';
class UIImageView extends UIView {
@override
final String tag__ = 'platform';
static Future<UIImageView> create(UIImage image) async {
final result = await kMethodChannel.invokeMethod<Ref>(
'UIImageView::create',
{'image': image},
);
return UIImageView()..refId = result?.refId;
}
}

View File

@ -0,0 +1,5 @@
enum UIStatusBarStyle {
UIStatusBarStyleDefault,
UIStatusBarStyleLightContent,
UIStatusBarStyleDarkContent,
}

View File

@ -0,0 +1,7 @@
// ignore_for_file: non_constant_identifier_names
import 'package:foundation_fluttify/foundation_fluttify.dart';
class UIUserNotificationSettings extends NSObject {
@override
final String tag__ = 'platform';
}

View File

@ -0,0 +1,163 @@
// ignore_for_file: non_constant_identifier_names
import 'dart:math';
import 'package:foundation_fluttify/foundation_fluttify.dart';
import 'package:foundation_fluttify/src/object/obejcts.dart';
import 'package:foundation_fluttify/src/type/platform/ios_type/cg_point.dart';
import 'cg_rect.dart';
import 'ns_object.dart';
class UIView extends NSObject {
@override
final String tag__ = 'platform';
static Future<UIView> create() async {
final result = await kMethodChannel.invokeMethod<Ref>('UIView::create');
return UIView()..refId = result?.refId;
}
/// 旋转
///
/// 单位为度
Future<void> rotate(double angle) async {
await kMethodChannel.invokeMethod('UIView::rotate', {
'__this__': this,
'angle': angle,
});
}
/// 执行缩放动画
Future<void> scaleWithDuration({
Duration duration = const Duration(seconds: 1),
double fromValue = 0,
required double toValue,
int repeatCount = 0,
int repeatMode = 1,
}) async {
assert(fromValue >= 0);
assert(toValue >= 0);
await kMethodChannel.invokeMethod('UIView::scaleWithDuration', {
'__this__': this,
'duration': duration.inMilliseconds / 1000,
'fromValue': fromValue,
'toValue': toValue,
'repeatCount': repeatCount,
'repeatMode': repeatMode,
});
}
/// 执行移动动画
Future<void> translateWithDuration({
Duration duration = const Duration(seconds: 1),
required CGPoint toValue,
int repeatCount = 0,
int repeatMode = 1,
}) async {
await kMethodChannel.invokeMethod('UIView::translateWithDuration', {
'__this__': this,
'duration': duration.inMilliseconds / 1000,
'toX': await toValue.x,
'toY': await toValue.y,
'repeatCount': repeatCount,
'repeatMode': repeatMode,
});
}
/// 执行透明度动画
///
/// 范围为0-1
Future<void> alphaWithDuration({
Duration duration = const Duration(seconds: 1),
double fromValue = 0,
required double toValue,
int repeatCount = 0,
int repeatMode = 0,
}) async {
assert(fromValue >= 0 && fromValue <= 1);
assert(toValue >= 0 && toValue <= 1);
await kMethodChannel.invokeMethod('UIView::alphaWithDuration', {
'__this__': this,
'duration': duration.inMilliseconds / 1000,
'fromValue': fromValue,
'toValue': toValue,
'repeatCount': repeatCount,
'repeatMode': repeatMode,
});
}
/// 执行旋转动画
///
/// 单位为度, 逆时针旋转
Future<void> rotateWithDuration({
Duration duration = const Duration(seconds: 1),
double fromValue = 0,
required double toValue,
int repeatCount = 0,
int repeatMode = 0,
}) async {
await kMethodChannel.invokeMethod('UIView::rotateWithDuration', {
'__this__': this,
'duration': duration.inMilliseconds / 1000,
'fromValue': fromValue / 180 * pi,
'toValue': -toValue / 180 * pi,
'repeatCount': repeatCount,
'repeatMode': repeatMode,
});
}
/// 执行组合动画
///
/// [keyPath]为构造CABasicAnimation时的[CABasicAnimation animationWithKeyPath:keyPath];
/// 缩放为`transform.scale`, 透明度为`opacity`, 旋转为`transform.rotation`
///
/// [fromValue], [toValue]和[keyPath]的长度必须相等
Future<void> groupWithDuration({
Duration duration = const Duration(seconds: 1),
required List<double> fromValue,
required List<double> toValue,
required List<String> keyPath,
int repeatCount = 0,
int repeatMode = 0,
}) async {
assert(fromValue.length == toValue.length);
assert(toValue.length == keyPath.length);
await kMethodChannel.invokeMethod('UIView::groupWithDuration', {
'__this__': this,
'duration': duration.inMilliseconds / 1000,
'fromValue': [for (final item in fromValue) item / 180 * pi],
'toValue': [for (final item in fromValue) -item / 180 * pi],
'keyPath': keyPath,
'repeatCount': repeatCount,
'repeatMode': repeatMode,
});
}
Future<CGRect> get frame async {
final result = await kMethodChannel
.invokeMethod<Ref>('UIView::getFrame', {'__this__': this});
return CGRect()..refId = result?.refId;
}
Future<bool?> get hidden async {
final result = await kMethodChannel
.invokeMethod('UIView::getHidden', {'__this__': this});
return result;
}
Future<void> setHidden(bool hidden) async {
await kMethodChannel.invokeMethod('UIView::setHidden', {
'__this__': this,
'hidden': hidden,
});
}
Future<void> setAnchorPoint(double anchorU, double anchorV) async {
await kMethodChannel.invokeMethod('UIView::setAnchorPoint', {
'__this__': this,
'anchorU': anchorU,
'anchorV': anchorV,
});
}
}

View File

@ -0,0 +1,16 @@
// ignore_for_file: non_constant_identifier_names
import 'package:foundation_fluttify/foundation_fluttify.dart';
import 'ns_object.dart';
class UIViewController extends NSObject {
@override
final String tag__ = 'platform';
static Future<UIViewController> get() async {
final result =
await kMethodChannel.invokeMethod<Ref>('UIViewController::get');
return UIViewController()..refId = result?.refId;
}
}

View File

@ -0,0 +1,75 @@
// ignore_for_file: non_constant_identifier_names, camel_case_types, missing_return, unused_import
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:foundation_fluttify/foundation_fluttify.dart';
import 'package:foundation_fluttify/src/type/platform/ios_type/ui_view.dart';
typedef _OnViewCreated = Future<void> Function(
android_opengl_GLSurfaceView? controller,
);
typedef _OnViewDispose = Future<void> Function();
class android_opengl_GLSurfaceViewWidget extends StatefulWidget {
const android_opengl_GLSurfaceViewWidget({
Key? key,
this.onGLSurfaceViewCreated,
this.onDispose,
this.gestureRecognizers,
}) : super(key: key);
final _OnViewCreated? onGLSurfaceViewCreated;
final _OnViewDispose? onDispose;
final Set<Factory<OneSequenceGestureRecognizer>>? gestureRecognizers;
@override
_android_opengl_GLSurfaceViewWidgetState createState() =>
_android_opengl_GLSurfaceViewWidgetState();
}
class _android_opengl_GLSurfaceViewWidgetState
extends State<android_opengl_GLSurfaceViewWidget> {
android_opengl_GLSurfaceView? _view;
@override
Widget build(BuildContext context) {
if (Platform.isAndroid) {
final gestureRecognizers = widget.gestureRecognizers ??
<Factory<OneSequenceGestureRecognizer>>{
Factory<OneSequenceGestureRecognizer>(
() => EagerGestureRecognizer()),
};
final messageCodec = FluttifyMessageCodec(tag: 'platform');
return AndroidView(
viewType: 'me.yohom/foundation_fluttify/android.opengl.GLSurfaceView',
creationParamsCodec: messageCodec,
gestureRecognizers: gestureRecognizers,
onPlatformViewCreated: (viewId) async {
final refId = await viewId2RefId((2147483647 - viewId).toString());
_view = android_opengl_GLSurfaceView()
..refId = 'android.opengl.GLSurfaceView:$refId';
if (widget.onGLSurfaceViewCreated != null) {
await widget.onGLSurfaceViewCreated!(_view);
}
},
);
} else {
return Center(child: Text('不支持的平台'));
}
}
@override
void dispose() {
if (widget.onDispose != null) {
widget.onDispose!().then((_) => _view!.release__());
} else {
_view!.release__();
}
super.dispose();
}
}

View File

@ -0,0 +1,128 @@
// ignore_for_file: non_constant_identifier_names, camel_case_types, missing_return, unused_import
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:foundation_fluttify/foundation_fluttify.dart';
import 'package:foundation_fluttify/src/type/platform/ios_type/ui_view.dart';
typedef _OnViewCreated = Future<void> Function(
android_view_SurfaceView? controller,
);
typedef _OnViewDispose = Future<void> Function();
class android_view_SurfaceViewWidget extends StatefulWidget {
const android_view_SurfaceViewWidget({
Key? key,
this.onSurfaceViewCreated,
this.surfaceCreated,
this.surfaceChanged,
this.surfaceDestroyed,
this.onDispose,
this.gestureRecognizers,
}) : super(key: key);
final _OnViewCreated? onSurfaceViewCreated;
final ValueChanged<android_view_SurfaceHolder>? surfaceCreated;
final void Function(android_view_SurfaceHolder, int?, int?, int?)?
surfaceChanged;
final ValueChanged<android_view_SurfaceHolder>? surfaceDestroyed;
final _OnViewDispose? onDispose;
final Set<Factory<OneSequenceGestureRecognizer>>? gestureRecognizers;
@override
_android_view_SurfaceViewWidgetState createState() =>
_android_view_SurfaceViewWidgetState();
}
class _android_view_SurfaceViewWidgetState
extends State<android_view_SurfaceViewWidget> {
android_view_SurfaceView? _view;
@override
void initState() {
super.initState();
MethodChannel(
'android.view.SurfaceHolder::addCallback::Callback',
kMethodCodec,
).setMethodCallHandler((methodCall) async {
try {
final args = methodCall.arguments as Map?;
switch (methodCall.method) {
case 'Callback::android.view.SurfaceHolder.Callback::surfaceCreated':
if (widget.surfaceCreated != null) {
final ref = args!['holder'] as Ref;
widget.surfaceCreated!(
android_view_SurfaceHolder.subInstance()..refId = ref.refId,
);
}
break;
case 'Callback::android.view.SurfaceHolder.Callback::surfaceChanged':
if (widget.surfaceChanged != null) {
final ref = args!['holder'] as Ref;
widget.surfaceChanged!(
android_view_SurfaceHolder.subInstance()..refId = ref.refId,
args['format'],
args['width'],
args['height'],
);
}
break;
case 'Callback::android.view.SurfaceHolder.Callback::surfaceDestroyed':
if (widget.surfaceDestroyed != null) {
final ref = args!['holder'] as Ref;
widget.surfaceDestroyed!(
android_view_SurfaceHolder.subInstance()..refId = ref.refId,
);
}
break;
default:
throw MissingPluginException('方法${methodCall.method}未实现');
}
} catch (e) {
debugPrint(e.toString());
rethrow;
}
});
}
@override
Widget build(BuildContext context) {
if (Platform.isAndroid) {
final gestureRecognizers = widget.gestureRecognizers ??
<Factory<OneSequenceGestureRecognizer>>{
Factory<OneSequenceGestureRecognizer>(
() => EagerGestureRecognizer()),
};
final messageCodec = FluttifyMessageCodec();
return AndroidView(
viewType: 'me.yohom/foundation_fluttify/android.view.SurfaceView',
creationParamsCodec: messageCodec,
gestureRecognizers: gestureRecognizers,
onPlatformViewCreated: (viewId) async {
final refId = await viewId2RefId((2147483647 - viewId).toString());
_view = android_view_SurfaceView()
..refId = 'android.view.SurfaceView:$refId';
if (widget.onSurfaceViewCreated != null) {
await widget.onSurfaceViewCreated!(_view);
}
},
);
} else {
return Center(child: Text('不支持的平台'));
}
}
@override
void dispose() {
if (widget.onDispose != null) {
widget.onDispose!().then((_) => _view!.release__());
} else {
_view!.release__();
}
super.dispose();
}
}

View File

@ -0,0 +1,74 @@
// ignore_for_file: non_constant_identifier_names, camel_case_types, missing_return, unused_import
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:foundation_fluttify/foundation_fluttify.dart';
import 'package:foundation_fluttify/src/type/platform/ios_type/ui_view.dart';
typedef _OnViewCreated = Future<void> Function(
android_widget_FrameLayout? controller);
typedef _OnViewDispose = Future<void> Function();
class android_view_FrameLayoutWidget extends StatefulWidget {
const android_view_FrameLayoutWidget({
Key? key,
this.onFrameLayoutCreated,
this.onDispose,
this.gestureRecognizers,
}) : super(key: key);
final _OnViewCreated? onFrameLayoutCreated;
final _OnViewDispose? onDispose;
final Set<Factory<OneSequenceGestureRecognizer>>? gestureRecognizers;
@override
_android_view_FrameLayoutWidgetState createState() =>
_android_view_FrameLayoutWidgetState();
}
class _android_view_FrameLayoutWidgetState
extends State<android_view_FrameLayoutWidget> {
android_widget_FrameLayout? _view;
@override
Widget build(BuildContext context) {
if (Platform.isAndroid) {
final gestureRecognizers = widget.gestureRecognizers ??
<Factory<OneSequenceGestureRecognizer>>{
Factory<OneSequenceGestureRecognizer>(
() => EagerGestureRecognizer()),
};
final messageCodec = FluttifyMessageCodec();
return AndroidView(
viewType: 'me.yohom/foundation_fluttify/android.widget.FrameLayout',
creationParamsCodec: messageCodec,
gestureRecognizers: gestureRecognizers,
onPlatformViewCreated: (viewId) async {
final refId = await viewId2RefId((2147483647 - viewId).toString());
_view = android_widget_FrameLayout()
..refId = 'android.widget.FrameLayout:$refId';
if (widget.onFrameLayoutCreated != null) {
await widget.onFrameLayoutCreated!(_view);
}
},
);
} else {
return Center(child: Text('不支持的平台'));
}
}
@override
void dispose() {
if (widget.onDispose != null) {
widget.onDispose!().then((_) => _view!.release__());
} else {
_view!.release__();
}
super.dispose();
}
}

View File

@ -0,0 +1,52 @@
import 'package:flutter/material.dart';
import 'package:foundation_fluttify/foundation_fluttify.dart';
import 'package:foundation_fluttify/src/type/core/ref.dart';
class ScopedReleasePool extends StatefulWidget {
const ScopedReleasePool({
Key? key,
required this.child,
required this.tag,
}) : super(key: key);
final Widget child;
/// 标记一类对象
///
/// 如果设置了, 则释放时根据这个tag进行释放, 防止误伤
final String tag;
@override
ScopedReleasePoolState createState() => ScopedReleasePoolState();
}
class ScopedReleasePoolState extends State<ScopedReleasePool> {
final Set<Ref> _releasePool = <Ref>{};
@override
void initState() {
super.initState();
gReleasePoolStack.push(this);
}
@override
Widget build(BuildContext context) {
return widget.child;
}
@override
void dispose() {
log('ScopedReleasePool释放对象: $_releasePool');
gReleasePoolStack.pop();
_releasePool
// 过滤出tag为目标tag的对象进行释放 或 tag为null表示不过滤
.where((e) => e.tag__ == widget.tag)
.release_batch()
.then((value) => _releasePool.clear());
super.dispose();
}
void add(Ref ref) {
_releasePool.add(ref);
}
}

View File

@ -0,0 +1,65 @@
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:foundation_fluttify/foundation_fluttify.dart';
typedef OnUIViewCreated = Future<void> Function(UIView? controller);
typedef _OnUiKitViewDispose = Future<void> Function();
class UIViewWidget extends StatefulWidget {
const UIViewWidget({
Key? key,
this.onUIViewCreated,
this.onDispose,
this.gestureRecognizers,
}) : super(key: key);
final OnUIViewCreated? onUIViewCreated;
final _OnUiKitViewDispose? onDispose;
final Set<Factory<OneSequenceGestureRecognizer>>? gestureRecognizers;
@override
_UIViewWidgetState createState() => _UIViewWidgetState();
}
class _UIViewWidgetState extends State<UIViewWidget> {
UIView? _view;
@override
Widget build(BuildContext context) {
if (Platform.isIOS) {
final gestureRecognizers = widget.gestureRecognizers ??
<Factory<OneSequenceGestureRecognizer>>{
Factory<OneSequenceGestureRecognizer>(
() => EagerGestureRecognizer()),
};
final messageCodec = FluttifyMessageCodec();
return UiKitView(
viewType: 'me.yohom/foundation_fluttify/UIView',
creationParamsCodec: messageCodec,
gestureRecognizers: gestureRecognizers,
onPlatformViewCreated: (viewId) async {
final refId = await viewId2RefId((2147483647 - viewId).toString());
_view = UIView()..refId = 'UIView:$refId';
if (widget.onUIViewCreated != null) {
await widget.onUIViewCreated!(_view);
}
},
);
} else {
return Center(child: Text('不支持的平台'));
}
}
@override
void dispose() {
if (widget.onDispose != null) {
widget.onDispose!().then((_) => _view?.release__());
} else {
_view?.release__();
}
super.dispose();
}
}