platformViewLink method
Widget
platformViewLink({
- dynamic onSafetyDetection(
- dynamic
- dynamic onDetectionComplete(
- dynamic
- dynamic onBoundingBox(
- dynamic
- dynamic fps(
- dynamic
- dynamic error(
- dynamic
- dynamic cameraStatus(
- dynamic
- dynamic loading(
- dynamic
- dynamic disposed(
- dynamic
- dynamic filterUpdated(
- dynamic
- dynamic cameraSwitch(
- dynamic
- Widget? onLoadingWidget,
- Widget? faceMaskOverlay,
- required Widget builder(),
- Widget customPermissionBuilder(
- Future ()
- Map<
String, dynamic> creationParams = const {}, - required String viewType,
Creates a platform view link widget with various callback functions for handling different events and optional widgets for loading and face mask overlay.
The following parameters are available:
onIdentify: Callback function triggered when identification occurs.onPercentageChanged: Callback function triggered when the percentage changes.onPushing: Callback function triggered when pushing occurs.onCompleted: Callback function triggered when the process is completed.onFailed: Callback function triggered when the process fails.onCountdownStarted: Callback function triggered when the countdown starts.onLiveness: Callback function triggered for liveness detection events.onFps: Callback function triggered for FPS (frames per second) updates.onLoadingWidget: Optional widget to display while loading.faceMaskOverlay: Optional widget to display as a face mask overlay.required Widget Function: A required function that returns a widget.
Implementation
Widget platformViewLink({
Function(dynamic)? onSafetyDetection,
Function(dynamic)? onDetectionComplete,
Function(dynamic)? onBoundingBox,
Function(dynamic)? fps,
Function(dynamic)? error,
Function(dynamic)? cameraStatus,
Function(dynamic)? loading,
Function(dynamic)? disposed,
Function(dynamic)? filterUpdated,
Function(dynamic)? cameraSwitch,
Widget? onLoadingWidget,
Widget? faceMaskOverlay,
required Widget Function(
Widget,
FlutterSafetyPlatformCameraController,
) builder,
Widget Function(
Future<dynamic> Function(BuildContext),
)? customPermissionBuilder,
Map<String, dynamic> creationParams = const {},
required String viewType,
}) {
MethodChannel methodChannel = MethodChannel('${viewType}_method_channel');
// Register all callbacks
registerCallback("error", error ?? (_) {});
registerCallback("fps", fps ?? (_) {});
registerCallback("detectionResult", onSafetyDetection ?? (_) {});
registerCallback("boundingBoxes", onBoundingBox ?? (_) {});
registerCallback("detectionComplete", onDetectionComplete ?? (_) {});
registerCallback("cameraStatus", cameraStatus ?? (_) {});
registerCallback("loading", loading ?? (_) {});
registerCallback("disposed", disposed ?? (_) {});
registerCallback("filterUpdated", filterUpdated ?? (_) {});
registerCallback("cameraSwitch", cameraSwitch ?? (_) {});
final isLoadingValueNotifier = ValueNotifier<bool>(true);
registerCallback("loading", (isLoading) {
isLoadingValueNotifier.value = isLoading as bool;
});
final isDetachedValueNotifier = ValueNotifier<bool>(false);
return FutureBuilder<bool>(
future: Permission.camera.status.isGranted,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return SizedBox.expand(
child: Container(color: Colors.black),
);
}
if (snapshot.data == true) {
final widgetPlatformViewLink = PlatformViewLink(
viewType: viewType,
surfaceFactory: (
BuildContext context,
PlatformViewController controller,
) {
return ValueListenableBuilder(
valueListenable: isDetachedValueNotifier,
builder: (context, isDetached, _) {
return ValueListenableBuilder(
valueListenable: isLoadingValueNotifier,
builder: (context, isLoading, child) {
return Stack(
children: [
isDetached
? const SizedBox.shrink()
: PlatformViewSurface(
controller: controller,
gestureRecognizers: const <Factory<
OneSequenceGestureRecognizer>>{},
hitTestBehavior:
PlatformViewHitTestBehavior.opaque,
),
faceMaskOverlay ?? const SizedBox.shrink(),
isLoading || isDetached
? onLoadingWidget ??
const Center(
child: CircularProgressIndicator())
: const SizedBox.shrink(),
],
);
},
);
});
},
onCreatePlatformView: (PlatformViewCreationParams params) {
return PlatformViewsService.initExpensiveAndroidView(
id: params.id,
viewType: viewType,
layoutDirection: TextDirection.ltr,
creationParams: creationParams,
creationParamsCodec: const StandardMessageCodec(),
onFocus: () {
params.onFocusChanged(true);
},
)
..addOnPlatformViewCreatedListener(params.onPlatformViewCreated)
..create();
},
);
return builder(
widgetPlatformViewLink,
FlutterSafetyPlatformCameraController(
setLivenessThreshold: ({double? threshold}) async {
if (isDetachedValueNotifier.value) {
return;
}
try {
return await methodChannel
.invokeMethod('setLivenessThreshold', {
'threshold': threshold,
});
} catch (e) {
debugPrint('Error setting liveness threshold: $e');
return null;
}
},
closeAndPop: () async {
if (isDetachedValueNotifier.value) {
return false;
}
isDetachedValueNotifier.value = true;
try {
await methodChannel.invokeMethod('detach');
await Future.delayed(const Duration(seconds: 1));
return true;
} catch (e) {
debugPrint('Error detaching camera: $e');
return false;
}
},
switchCamera: () async {
if (isDetachedValueNotifier.value) {
return;
}
try {
return await methodChannel.invokeMethod('switchCamera');
} catch (e) {
debugPrint('Error switching camera: $e');
return null;
}
},
updateFilters: (Map<String, dynamic> filters) async {
if (isDetachedValueNotifier.value) {
return;
}
try {
return await methodChannel.invokeMethod(
'updateFilters', filters);
} catch (e) {
debugPrint('Error updating filters: $e');
return null;
}
},
));
} else {
Future<dynamic> requestPermission(BuildContext context) async {
final status = await Permission.camera.request();
if (status.isGranted) {
(context as Element).markNeedsBuild();
}
return status;
}
if (customPermissionBuilder != null) {
return customPermissionBuilder(requestPermission);
} else {
return defaultPermissionUI(context, requestPermission);
}
}
},
);
}