【问题标题】:Flutter camera frame drops when switching between pages在页面之间切换时颤动相机帧丢失
【发布时间】:2018-12-12 17:54:58
【问题描述】:

我尝试将 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 版本的模拟器上测试。

【问题讨论】:

  • 这仅适用于调试版本还是也适用于发布版本?
  • 在发布和调试版本中发生
  • 那么用允许重现的信息创建一个错误报告可能是个好主意。
  • 好的,谢谢
  • @LeonP 您是否创建了错误报告?

标签: dart flutter


【解决方案1】:

我通过在初始化相机之前添加延迟解决了类似的问题:

Future.delayed(Duration(seconds: 1), () {
  initCameras();
});

这样在页面导航动画完成后调用initCameras()。您可以显示CircularProgressIndicator() 以使此延迟对用户更友好。 我确信有一种更简洁的方法可以解决这个问题,但这似乎是最简单的解决方案。

【讨论】:

  • 可能是一个有效的解决方法,但肯定不理想。添加定时延迟以便其他内容可以正确加载似乎从来都不是一个好主意。但这基本上就是你已经说过的......
【解决方案2】:

如果您想在不同页面中使用图像路径而不是将图像路径存储为全局变量,并在您想要的地方使用它。

【讨论】:

  • 对不起,我不知道您指的是哪个图像路径。澄清一下,我正在尝试显示实时相机预览,而不是已捕获的图像。您能否提供更多信息来说明您的意思?
猜你喜欢
  • 2020-02-18
  • 1970-01-01
  • 2016-08-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-06
  • 2016-01-17
相关资源
最近更新 更多