Disposing Camera preview in CupertinoTabBar when switched in Flutter

862 views Asked by At

I am building a QR code scanner app with a couple of tabs wrapped up within CupertinoTabBar in a CupertinoTabScaffold. I have a CupertinoTabController to take care of the switching between the tabs. One of this tabs has a CameraPreview widget from the Camera plugin of Flutter along with a proper dispose mechanism. However, whenever the tab are switched, the Camera stream still persists, causing the phone to heat up and also causes janky UX. Now I read that the BottomNavigationBar from Material widgets does not persist in this way. Any idea on how to achieve the same behaviour with CupertinoTabBar?

1

There are 1 answers

0
OpannapO On

You can use the StatefulWidget for each a page of the tabs and then try to listening AppLifecycleState. Disponse controller if state inactive/paused.

In my case it's working fine.

class Example extends StatefulWidget {
  @override
  ExampleState createState() => ExampleState();
}


//Implement WidgetsBindingObserver to listen Lifecycle State
class ExampleState extends State<Example> with WidgetsBindingObserver {
  late CameraController _controller;
  ...
  ...

  @override
  void initState() {
    super.initState();

    // Add Listener (Lifecycle State)
    WidgetsBinding.instance!.addObserver(this); 
  }
 

  Future<void> _setupController() async {
    //todo setup/init controller
  }

  //Implements this method to listen Lifecycle State
  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    if (state == AppLifecycleState.resumed) {
      _controller.dispose();
      _setupCameraAndControllerFuture = _setupController();
    }
    if (state == AppLifecycleState.inactive) {
      _controller.dispose();
    } else if (state == AppLifecycleState.paused) {
      _controller.dispose();
    }
  }

  @override
  void dispose() { 
    // Remove Listener (Lifecycle State)
    WidgetsBinding.instance!.removeObserver(this);

    // dispose controller
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      ...
      ...
    ); 
  }  
}