一尘不染

Flutter-用户移动到其他(预览)屏幕时如何正确暂停相机?

flutter

当我移到导航器树上的另一个屏幕时,我需要 暂停 相机以节省电池和性能。

我尝试使用dispose()cameraController,但是当flutter从另一个屏幕返回时,它不会重新初始化状态(尽管很明显)。

我使用相机的主要代码:

 @override
  void initState() {
    super.initState();
    availableCameras().then((cameras) {
      setState(() {
        _firstCamera = cameras.first;
        _controller = CameraController(_firstCamera, ResolutionPreset.high);

        _initializeControllerFuture = _controller.initialize();
      });
    });
  }

  @override
  void dispose() {
    _controller?.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      key: _scaffoldKey,
      body: Stack(
        children: <Widget>[
          FutureBuilder<void>(
            future: _initializeControllerFuture,
            builder: (context, snapshot) {

              if (snapshot.connectionState == ConnectionState.done) {
                return Stack(
                  alignment: FractionalOffset.center,
                  children: <Widget>[
                    new Positioned.fill(
                      child: _getCameraPreview(context),
                    ),
                    ...                    
                  ],
                );
              } else {
                return Center(child: CircularProgressIndicator());
              }
            },
          ),
          Align(
            alignment: Alignment.bottomCenter,
            child: BottomAppBar(
              color: Color.fromARGB(0, 0, 0, 0),
              child: _getBottomAppBarRow(context),
            ),
          ),
        ],
      ),
    );
  }

  _getCameraPreview(BuildContext context) {
    final size = MediaQuery.of(context).size;
    final deviceRatio = size.width / size.height;
    return Transform.scale(
      scale: _controller.value.aspectRatio / deviceRatio,
      child: Center(
        child: AspectRatio(
          aspectRatio: _controller.value.aspectRatio,
          child: CameraPreview(_controller),
        ),
      ),
    );
  }

阅读 528

收藏
2020-08-13

共1个答案

一尘不染

具有类似_cameraOn = true的变量。如果为true,则显示CameraPreview,否则为false。导航到另一个屏幕时,将其设置为false

您可以在单独的小部件中拥有与相机相关的功能。因此,每次显示时都会对其进行初始化,而在不显示时将对其进行处理。

一个简单的工作示例

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:camera/camera.dart';

List<CameraDescription> cameras;

Future<void> main() async {
  cameras = await availableCameras();
  runApp(MaterialApp(
    home: CameraApp(),
  ));
}

class CameraApp extends StatefulWidget {
  @override
  _CameraAppState createState() => _CameraAppState();
}

class _CameraAppState extends State<CameraApp> {
  bool _cameraOn = true;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        children: <Widget>[
          Expanded(
            child: _cameraOn ? Camera() : Container(),
          ),
          FlatButton(
            onPressed: () {
              setState(() {
                _cameraOn = false;
              });
              Navigator.push(
                  context,
                  MaterialPageRoute(
                      builder: (BuildContext context) => Post())).then((res) {
                setState(() {
                  _cameraOn = true;
                });
              }).catchError((err) {
                print(err);
              });
            },
            child: Text("NEXT PAGE"),
          ),
        ],
      ),
    );
  }
}

class Camera extends StatefulWidget {
  @override
  _CameraState createState() => _CameraState();
}

class _CameraState extends State<Camera> {
  CameraController controller;

  @override
  void initState() {
    super.initState();
    controller = CameraController(cameras[0], ResolutionPreset.medium);
    controller.initialize().then((_) {
      if (!mounted) {
        return;
      }
      setState(() {});
    });
  }

  @override
  Widget build(BuildContext context) {
    if (!controller.value.isInitialized) {
      return Container();
    }

    return AspectRatio(
      aspectRatio: controller.value.aspectRatio,
      child: CameraPreview(controller),
    );
  }

  @override
  void dispose() {
    controller?.dispose();
    super.dispose();
  }
}

class Post extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Text("Post"),
    );
  }
}
2020-08-13