我正在尝试将当前选择的摄像机保存到SharedPreferences。当应用重新启动时,我希望最初使用同一台相机。如果用户切换到其他摄像机,该摄像机将被保存。
当我在initState中包含以下代码时,我得到“在null上调用getter'值'”。错误信息。同样,红色/黄色错误消息会显示并在相机开始工作之前迅速消失。
@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,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,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: 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);
}
}