问题描述
当我移到导航器树上的另一个屏幕时,我需要暂停相机,以节省电池和性能.
I need to pause camera when I move to another screen on the navigator tree in order to save battery and performance.
我尝试dispose()
cameraController,但是当flutter从另一个屏幕返回时(虽然很明显),它不会重新初始化状态.
I tried to dispose()
cameraController, but flutter doesn't re-initialize the state when it returns from another screen (which is obvious, though).
我与相机配合使用的主要代码:
My main code to work with a camera:
@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),
),
),
);
}
推荐答案
具有类似_cameraOn = true的变量.如果为true,则显示CameraPreview,如果为false,则不显示.导航到另一个屏幕时,将其设置为false
Have a variable like _cameraOn = true. Show CameraPreview when it is true and not when it is false. While navigating to another screen set it to false
您可以在单独的小部件中拥有与相机相关的功能.因此,每次显示时都会对其进行初始化,而在不显示时将其丢弃.
You could have the camera related functionality in a separate widget. So every time it is displayed it is initialized, and when it is not it's disposed.
一个简单的工作示例
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"),
);
}
}
这篇关于Flutter-用户移动到其他(预览)屏幕时如何正确暂停相机?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!