FutureBuilder 和相机
FutureBuilder and Camera
我是 Flutter 的新手,我仍然在为 Future 的某些方面苦苦挣扎。
我有一个底部导航栏,页面之间的切换是通过 PageView 完成的。
问题是当我切换到我的“照片”页面时,它永远显示一个循环进度指示器。我有点迷茫,老实说我不知道我做错了什么,看起来未来的建设者永远不会获得价值。
只是为了提供更多信息:如果我进行热刷新,相机将开始工作并出现图片。
这是 PhotoScreen 页面:
import 'dart:async';
import 'dart:io';
import 'package:camera/camera.dart';
import 'package:flutter/material.dart';
// A screen that allows users to take a picture using a given camera.
class PhotoScreen extends StatefulWidget {
const PhotoScreen({
Key key,
}) : super(key: key);
@override
PhotoScreenState createState() => PhotoScreenState();
}
class PhotoScreenState extends State<PhotoScreen> {
CameraDescription camera;
CameraController _controller;
Future<void> _initializeControllerFuture;
@override
void initState() {
super.initState();
// Obtain a list of the available cameras on the device.
inizializza();
}
@override
void dispose() {
// Dispose of the controller when the widget is disposed.
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Take a picture')),
// Wait until the controller is initialized before displaying the
// camera preview. Use a FutureBuilder to display a loading spinner
// until the controller has finished initializing.
body: FutureBuilder<void>(
future: _initializeControllerFuture,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
// If the Future is complete, display the preview.
return CameraPreview(_controller);
} else {
// Otherwise, display a loading indicator.
return Center(child: CircularProgressIndicator());
}
},
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.camera_alt),
// Provide an onPressed callback.
onPressed: () async {
// Take the Picture in a try / catch block. If anything goes wrong,
// catch the error.
try {
// Ensure that the camera is initialized.
await _initializeControllerFuture;
// Attempt to take a picture and get the file `image`
// where it was saved.
final image = await _controller.takePicture();
} catch (e) {
// If an error occurs, log the error to the console.
print(e);
}
},
),
);
}
void inizializza() async {
final cameras = await availableCameras();
// Get a specific camera from the list of available cameras.
final firstCamera = cameras.first;
// To display the current output from the Camera,
// create a CameraController.
_controller = CameraController(
// Get a specific camera from the list of available cameras.
firstCamera,
// Define the resolution to use.
ResolutionPreset.medium,
);
// Next, initialize the controller. This returns a Future.
_initializeControllerFuture = _controller.initialize();
}
}
inizializza 方法实际上是异步的,您在 initState() 中执行它,但事实并非如此。
我认为你的 inizializza 方法应该是这样的:
Future<void> inizializza() async {
final cameras = await availableCameras();
// Get a specific camera from the list of available cameras.
final firstCamera = cameras.first;
// To display the current output from the Camera,
// create a CameraController.
_controller = CameraController(
// Get a specific camera from the list of available cameras.
firstCamera,
// Define the resolution to use.
ResolutionPreset.medium,
);
// Next, initialize the controller. This returns a Future.
await _controller.initialize();
}
这就是 FutureBuilder 接收的 Future,而不是在 initState() 中执行它
FutureBuilder<void>(
future: inizializza(),
...
)
我是 Flutter 的新手,我仍然在为 Future 的某些方面苦苦挣扎。 我有一个底部导航栏,页面之间的切换是通过 PageView 完成的。 问题是当我切换到我的“照片”页面时,它永远显示一个循环进度指示器。我有点迷茫,老实说我不知道我做错了什么,看起来未来的建设者永远不会获得价值。 只是为了提供更多信息:如果我进行热刷新,相机将开始工作并出现图片。
这是 PhotoScreen 页面:
import 'dart:async';
import 'dart:io';
import 'package:camera/camera.dart';
import 'package:flutter/material.dart';
// A screen that allows users to take a picture using a given camera.
class PhotoScreen extends StatefulWidget {
const PhotoScreen({
Key key,
}) : super(key: key);
@override
PhotoScreenState createState() => PhotoScreenState();
}
class PhotoScreenState extends State<PhotoScreen> {
CameraDescription camera;
CameraController _controller;
Future<void> _initializeControllerFuture;
@override
void initState() {
super.initState();
// Obtain a list of the available cameras on the device.
inizializza();
}
@override
void dispose() {
// Dispose of the controller when the widget is disposed.
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Take a picture')),
// Wait until the controller is initialized before displaying the
// camera preview. Use a FutureBuilder to display a loading spinner
// until the controller has finished initializing.
body: FutureBuilder<void>(
future: _initializeControllerFuture,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
// If the Future is complete, display the preview.
return CameraPreview(_controller);
} else {
// Otherwise, display a loading indicator.
return Center(child: CircularProgressIndicator());
}
},
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.camera_alt),
// Provide an onPressed callback.
onPressed: () async {
// Take the Picture in a try / catch block. If anything goes wrong,
// catch the error.
try {
// Ensure that the camera is initialized.
await _initializeControllerFuture;
// Attempt to take a picture and get the file `image`
// where it was saved.
final image = await _controller.takePicture();
} catch (e) {
// If an error occurs, log the error to the console.
print(e);
}
},
),
);
}
void inizializza() async {
final cameras = await availableCameras();
// Get a specific camera from the list of available cameras.
final firstCamera = cameras.first;
// To display the current output from the Camera,
// create a CameraController.
_controller = CameraController(
// Get a specific camera from the list of available cameras.
firstCamera,
// Define the resolution to use.
ResolutionPreset.medium,
);
// Next, initialize the controller. This returns a Future.
_initializeControllerFuture = _controller.initialize();
}
}
inizializza 方法实际上是异步的,您在 initState() 中执行它,但事实并非如此。 我认为你的 inizializza 方法应该是这样的:
Future<void> inizializza() async {
final cameras = await availableCameras();
// Get a specific camera from the list of available cameras.
final firstCamera = cameras.first;
// To display the current output from the Camera,
// create a CameraController.
_controller = CameraController(
// Get a specific camera from the list of available cameras.
firstCamera,
// Define the resolution to use.
ResolutionPreset.medium,
);
// Next, initialize the controller. This returns a Future.
await _controller.initialize();
}
这就是 FutureBuilder 接收的 Future,而不是在 initState() 中执行它
FutureBuilder<void>(
future: inizializza(),
...
)