我尝试将Flutter camera plugin(0.2.1)与PageView和BottomNavigationBar结合使用,但是每次切换页面时,都会跳过几帧,并且UI冻结一秒钟。
对于这个示例,我简化了代码库:
import 'package:flutter/material.dart';
import 'package:camera/camera.dart';
void main() => runApp(new Pages());
class Pages extends StatefulWidget {
@override
_PagesState createState() => _PagesState();
}
class _PagesState extends State<Pages> {
PageController _pageController;
int _page = 0;
@override
void initState() {
_pageController = new PageController();
super.initState();
}
void navTapped(int page) {
_pageController.animateToPage(page,
duration: const Duration(milliseconds: 300), curve: Curves.ease);
}
void onPageChanged(int page) {
setState(() {
this._page = page;
});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: new Text("CameraTest"),
),
body: PageView(
children: <Widget>[Feed(), Camera(), Profile()],
controller: _pageController,
onPageChanged: onPageChanged,
),
bottomNavigationBar: new BottomNavigationBar(
items: [
new BottomNavigationBarItem(
icon: new Icon(Icons.home), title: new Text("Feed")),
new BottomNavigationBarItem(
icon: new Icon(Icons.camera), title: new Text("Capture")),
new BottomNavigationBarItem(
icon: new Icon(Icons.person), title: new Text("Profile"))
],
onTap: navTapped,
currentIndex: _page,
),
),
);
}
}
class Camera extends StatefulWidget {
@override
_CameraState createState() => _CameraState();
}
class _CameraState extends State<Camera> {
List<CameraDescription> _cameras;
CameraController _controller;
initCameras() async{
_cameras = await availableCameras();
_controller = new CameraController(_cameras[0], ResolutionPreset.medium);
await _controller.initialize();
setState(() {});
}
@override
void initState() {
initCameras();
super.initState();
}
@override
void dispose() {
_controller?.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
if (_controller == null || !_controller.value.isInitialized) {
return new Center(
child: new Text("Waiting for camera...", style: TextStyle(color: Colors.grey),),
);
}
return new AspectRatio(
aspectRatio: _controller.value.aspectRatio,
child: new CameraPreview(_controller));
}
}
//just placeholder widgets
class Feed extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(child: new Text("Feed"));
}
}
class Profile extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(child: new Text("Profile"));
}
}
基本上有三页,中间一页显示摄像机预览 (how it's supposed to look),但切换到相机并从相机切换回this时会发生。这确实很烦人,因为它破坏了用户体验,并且一点也不流畅。当调用initCameras()或放置摄像机控制器时,会出现延迟。我尝试将initCameras()与FutureBuilder结合使用,后者根本没有帮助,并在单独的隔离中运行该方法,但是似乎仅允许在主要隔离上进行平台调用。对我来说有点奇怪,因为打开相机并不需要太多的cpu功能,因此异步方法应该没问题。我知道有一个image-picker plugin,但我想直接在应用程序中预览。我还考虑过在应用程序启动时运行initCameras(),但是当用户仅使用应用程序的另一个页面时,我并不想一直运行相机。
是否有任何方法可以改善initCameras()或使用其他实现来解决口吃?我什至都不在乎是否需要一秒钟来加载,但我不希望任何帧跳越。
我遵循了相机页面底部的example。
在不同的Android版本的物理设备和仿真器上进行了测试。
答案 0 :(得分:0)
如果要在与将图像路径存储为全局变量不同的页面中使用图像路径,请在所需位置使用它。
答案 1 :(得分:0)
我通过在初始化相机之前添加延迟来解决了类似的问题:
Future.delayed(Duration(seconds: 1), () {
initCameras();
});
这样,在页面导航动画完成后调用initCameras()
。您可以显示CircularProgressIndicator()
以使此延迟更加人性化。
我敢肯定有更整洁的方法来解决此问题,但这似乎是最简单的解决方案。