【发布时间】:2020-03-24 14:39:00
【问题描述】:
我正在尝试将当前选择的相机保存到 SharedPreferences。当应用程序重新启动时,我希望最初使用相同的相机。如果用户切换到另一个摄像头,则会保存该摄像头。
当我在 initState 中有以下代码时,我得到“在 null 上调用了 getter 'value'”。错误信息。在相机开始工作之前,红色/黄色错误消息也会快速显示并消失。
@override
void initState() {
try {
SharedPreferencesHelper prefs = SharedPreferencesHelper();
prefs.getCameraSelected().then((String answer) {
if (answer != null) {
if (answer == 'back') {
onCameraSelected(widget.cameras[0]);
} else {
onCameraSelected(widget.cameras[1]);
}
} else {
print('answer is null');
onCameraSelected(widget.cameras[1]);
}
});
} catch (e) {
print(e.toString());
}
super.initState();
}
如果我将 initState 替换回原始状态,一切都会按预期进行
@override
void initState() {
try {
onCameraSelected(widget.cameras[0]);
} catch (e) {
print(e.toString());
}
super.initState();
}
下面是 CameraHomeScreen.dart 文件的完整代码:
import 'dart:async';
import 'dart:io';
import 'package:camera/camera.dart';
import 'package:path_provider/path_provider.dart';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
class CameraHomeScreen extends StatefulWidget {
List<CameraDescription> cameras;
CameraHomeScreen(this.cameras);
@override
State<StatefulWidget> createState() {
return _CameraHomeScreenState();
}
}
class _CameraHomeScreenState extends State<CameraHomeScreen> {
String imagePath;
bool _toggleCamera = false;
String _currentCamera = 'back';
CameraController controller;
@override
void initState() {
try {
SharedPreferencesHelper prefs = SharedPreferencesHelper();
prefs.getCameraSelected().then((String answer) {
if (answer != null) {
print('here');
print(answer);
if (answer == 'back') {
onCameraSelected(widget.cameras[0]);
} else {
onCameraSelected(widget.cameras[1]);
}
} else {
print('answer is null');
onCameraSelected(widget.cameras[1]);
}
});
} catch (e) {
print(e.toString());
}
super.initState();
}
@override
void dispose() {
controller?.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
if (widget.cameras.isEmpty) {
return Container(
alignment: Alignment.center,
padding: EdgeInsets.all(16.0),
child: Text(
'No Camera Found',
style: TextStyle(
fontSize: 16.0,
color: Colors.white,
),
),
);
}
if (!controller.value.isInitialized) {
return Container();
}
return AspectRatio(
aspectRatio: controller.value.aspectRatio,
child: Container(
child: Stack(
children: <Widget>[
CameraPreview(controller),
Align(
alignment: Alignment.bottomCenter,
child: Container(
width: double.infinity,
height: 120.0,
padding: EdgeInsets.all(20.0),
color: Color.fromRGBO(00, 00, 00, 0.7),
child: Stack(
children: <Widget>[
Align(
alignment: Alignment.center,
child: Material(
color: Colors.transparent,
child: InkWell(
borderRadius: BorderRadius.all(Radius.circular(50.0)),
onTap: () {
_captureImage();
},
child: Container(
padding: EdgeInsets.all(4.0),
child: Image.asset(
'assets/images/ic_shutter_1.png',
width: 72.0,
height: 72.0,
),
),
),
),
),
Align(
alignment: Alignment.centerRight,
child: Material(
color: Colors.transparent,
child: InkWell(
borderRadius: BorderRadius.all(Radius.circular(50.0)),
onTap: () {
if (!_toggleCamera) {
SharedPreferencesHelper prefs =
SharedPreferencesHelper();
prefs.setCameraSelected('front');
onCameraSelected(widget.cameras[1]);
setState(() {
_toggleCamera = true;
});
} else {
SharedPreferencesHelper prefs =
SharedPreferencesHelper();
prefs.setCameraSelected('back');
onCameraSelected(widget.cameras[0]);
setState(() {
_toggleCamera = false;
});
}
},
child: Container(
padding: EdgeInsets.all(4.0),
child: Image.asset(
'assets/images/ic_switch_camera_3.png',
color: Colors.grey[200],
width: 42.0,
height: 42.0,
),
),
),
),
),
],
),
),
),
],
),
),
);
}
void onCameraSelected(CameraDescription cameraDescription) async {
if (controller != null) await controller.dispose();
controller = CameraController(cameraDescription, ResolutionPreset.medium);
controller.addListener(() {
if (mounted) setState(() {});
if (controller.value.hasError) {
showMessage('Camera Error: ${controller.value.errorDescription}');
}
});
try {
await controller.initialize();
} on CameraException catch (e) {
showException(e);
}
if (mounted) setState(() {});
}
String timestamp() => new DateTime.now().millisecondsSinceEpoch.toString();
void _captureImage() {
takePicture().then((String filePath) {
if (mounted) {
setState(() {
imagePath = filePath;
});
if (filePath != null) {
showMessage('Picture saved to $filePath');
setCameraResult();
}
}
});
}
void setCameraResult() {
Navigator.pop(context, imagePath);
}
Future<String> takePicture() async {
if (!controller.value.isInitialized) {
showMessage('Error: select a camera first.');
return null;
}
final Directory extDir = await getApplicationDocumentsDirectory();
final String dirPath = '${extDir.path}/FlutterDevs/Camera/Images';
await new Directory(dirPath).create(recursive: true);
final String filePath = '$dirPath/${timestamp()}.jpg';
if (controller.value.isTakingPicture) {
// A capture is already pending, do nothing.
return null;
}
try {
await controller.takePicture(filePath);
} on CameraException catch (e) {
showException(e);
return null;
}
return filePath;
}
void showException(CameraException e) {
logError(e.code, e.description);
showMessage('Error: ${e.code}\n${e.description}');
}
void showMessage(String message) {
print(message);
}
void logError(String code, String message) =>
print('Error: $code\nMessage: $message');
}
class SharedPreferencesHelper {
///
/// Instantiation of the SharedPreferences library
///
final String _nameKey = "cameraSelected";
/// ------------------------------------------------------------
/// Method that returns the user decision on sorting order
/// ------------------------------------------------------------
Future<String> getCameraSelected() async {
final SharedPreferences prefs = await SharedPreferences.getInstance();
return prefs.getString(_nameKey) ?? 'name';
}
/// ----------------------------------------------------------
/// Method that saves the user decision on sorting order
/// ----------------------------------------------------------
Future<bool> setCameraSelected(String value) async {
final SharedPreferences prefs = await SharedPreferences.getInstance();
return prefs.setString(_nameKey, value);
}
}
【问题讨论】:
-
在您的初始代码中,try 和 catch 不会运行,因为您没有执行“await onCameraSelected(widget.cameras[0]);”
标签: flutter camera save sharedpreferences settings