# platformViewLink method

Widget platformViewLink({

1. dynamic onIdentify(
   1. dynamic
   )?,
2. dynamic onPercentageChanged(
   1. dynamic
   )?,
3. dynamic onPushing(
   1. dynamic
   )?,
4. dynamic onCompleted(
   1. dynamic
   )?,
5. dynamic onFailed(
   1. dynamic
   )?,
6. dynamic onCountdownStarted(
   1. dynamic
   )?,
7. dynamic onLiveness(
   1. dynamic
   )?,
8. dynamic onFps(
   1. dynamic
   )?,
9. Widget? onLoadingWidget,
10. Widget? faceMaskOverlay,
11. required Widget builder(
    1. Widget,
    2. FlutterSmartfacePlatformCameraController
    ),
12. Widget customPermissionBuilder(
    1. Future (
       1. BuildContext
       )
    )?,
13. Map<String, dynamic> creationParams = const {},
14. 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)? onIdentify,
      Function(dynamic)? onPercentageChanged,
      Function(dynamic)? onPushing,
      Function(dynamic)? onCompleted,
      Function(dynamic)? onFailed,
      Function(dynamic)? onCountdownStarted,
      Function(dynamic)? onLiveness,
      Function(dynamic)? onFps,
      Widget? onLoadingWidget,
      Widget? faceMaskOverlay,
      required Widget Function(
        Widget,
        FlutterSmartfacePlatformCameraController,
      ) builder,
      Widget Function(
        Future<dynamic> Function(BuildContext),
      )? customPermissionBuilder,
      Map<String, dynamic> creationParams = const {},
      required String viewType,
    }) {
      MethodChannel methodChannel = MethodChannel('${viewType}_method_channel');

      registerCallback("onIdentify", onIdentify ?? (_) {});
      registerCallback("onPercentageChanged", onPercentageChanged ?? (_) {});
      registerCallback("onPushing", onPushing ?? (_) {});
      registerCallback("onCompleted", onCompleted ?? (_) {});
      registerCallback("onFailed", onFailed ?? (_) {});
      registerCallback("onCountdownStarted", onCountdownStarted ?? (_) {});
      registerCallback("onLiveness", onLiveness ?? (_) {});
      registerCallback("fps", onFps ?? (_) {});

      final isLoadingValueNotifier = ValueNotifier<bool>(true);
      registerCallback("isLoading", (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,
                FlutterSmartfacePlatformCameraController(
                  setLivenessThreshold: (threshold) async {
                    if (isDetachedValueNotifier.value) {
                      return;
                    }
                    await methodChannel.invokeMethod('setLivenessThreshold', {
                      'threshold': threshold,
                    });
                  },
                  closeAndPop: () async {
                    if (isDetachedValueNotifier.value) {
                      return;
                    }
                    isDetachedValueNotifier.value = true;
                    await methodChannel.invokeMethod('detach');
                    await Future.delayed(const Duration(seconds: 1));
                  },
                  switchCamera: () async {
                    if (isDetachedValueNotifier.value) {
                      return;
                    }
                    return await methodChannel.invokeMethod('switchCamera');
                  },
                ));
          } 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);
            }
          }
        },
      );
    }