Prerequisites
- A working Flutter quickstart
- Exactly one mounted
NosmaiCameraPreview - No Flutter
cameracontroller owning the same device
Use the preview owner
NosmaiCameraPreview handles normal application pause and resume internally. For temporary app-owned tab transitions, the public controls are:
final nosmai = NosmaiFlutter.instance; await nosmai.pauseCamera(); await nosmai.resumeCamera();
Do not call both these methods and a second camera plugin for the same screen.
Switch the camera
Await the switch result and keep the button disabled while it is pending:
final switched = await NosmaiFlutter.instance.switchCamera(); if (!switched) return;
The wrapper rejects operational failures and safely ignores rapid concurrent switches.
Navigate away safely
Use NosmaiCameraLifecycleMixin when the route needs an explicit asynchronous exit step:
await cleanupBeforeNavigation(); if (mounted) Navigator.of(context).pop();
The native PlatformView owns final disposal. Do not launch another global cleanup from State.dispose, because it can stop a newly mounted preview.
Verify it worked
Switch lenses, background and foreground the app, then open and close the route ten times. Confirm one preview remains mounted, the camera indicator turns off after exit, and returning does not create a second session.
Common errors
| Symptom | Cause | Fix |
|---|---|---|
| Camera is busy | Another plugin or duplicate preview owns the device | Dispose the old controller and keep one NosmaiCameraPreview |
| New screen closes immediately | Old route cleanup raced with the new PlatformView | Use cleanupBeforeNavigation and do not start global cleanup in dispose |
Switch returns false | A rapid or concurrent switch was safely ignored | Keep the current lens and re-enable the control after the pending call |