Как дождаться инициализации камеры? - PullRequest
0 голосов
/ 11 июля 2020

Я все время получал ошибку от camera.dart, что "name" вызывается для нулевого объекта.

Через некоторое время я понял, что проблема в том, что метод сборки вызывается перед asyn c код в моем состоянии инициализации завершен (я немного горжусь тем, что, по крайней мере, понял проблему:))

Я пробовал много разных способов правильно инициализировать мою камеру, но не смог. Это последняя итерация моего кода.

Какой идиоматический c способ справиться с этим будущим?

  class _PicturePreviewState extends State<PicturePreview> {
  List<CameraDescription> cameras;
  CameraDescription camera;
  CameraController cameraController;
  Future<void> initializeController;

  Future<void> getCameras() async {
    try {
      cameras = await availableCameras();     
    } catch(e) {print(e);}
    camera = cameras.last;
    print(camera);
  }

  @override
  void initState() {
    super.initState();
    // getCameras();
    availableCameras().then((availableCameras) {
      cameras = availableCameras;
      camera = cameras.first;
      cameraController = CameraController(
      camera,
      ResolutionPreset.low,
    );
    initializeController = cameraController.initialize();
    print(cameraController.value.isInitialized);
    });
    
    // cameraController = CameraController(
    //   camera,
    //   ResolutionPreset.low,
    // );
    // initializeController = cameraController.initialize();
    // print(cameraController.value.isInitialized);
  }

  @override
  void dispose() {
    cameraController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: FutureBuilder<void>(
        future: initializeController,
        builder: (context, snapshot) {
          if (snapshot.connectionState == ConnectionState.done) {
            // If the Future is complete, display the preview.
              return CameraPreview(cameraController);
          }
          else {
            // Otherwise, display a loading indicator.
            print(snapshot.connectionState);
            return Center(child: CircularProgressIndicator());
          }
        },
      ),

Я полагался на эту страницу , чтобы использовать пакет камеры, но я не мог использовать его дословно, потому что я не могу продолжать передавать объект камеры вниз по дереву виджетов.

Ответы [ 2 ]

0 голосов
/ 11 июля 2020

Я исправил. Я поместил инициализацию объекта камеры в родительский элемент виджета.

class _TakeReceiptPictureState extends State<TakeReceiptPicture> {
  List<CameraDescription> cameras;
  CameraDescription camera;

  @override
  void initState() { 
    super.initState();
    availableCameras().then((availableCameras) {
      cameras = availableCameras;
      camera = cameras.first;
    });       
  }

Затем сделал виджет, который делает снимок, параметром типа CameraDescription.

class PicturePreview extends StatefulWidget {
  final CameraDescription camera;
  const PicturePreview(this.camera, {Key key}) : super(key: key);

  @override
  _PicturePreviewState createState() => _PicturePreviewState();
}

Затем передал камеру, инициализированную в родительском виджете изображения

        onTap: () {
          Navigator.of(context).push(
             PageTransition(
                  type: PageTransitionType.transferRight,
                  child: PicturePreview(camera)),
            );
        }),

, к моменту запуска метода сборки дочернего виджета объект камеры уже инициализирован и готов к go.

Сейчас состояние дочернего элемента имеет только две переменные: контроллер камеры и будущий контроллер инициализации.

  CameraController cameraController;
  Future<void> initializeController;

  @override
  void initState() {
    super.initState();    
    cameraController = CameraController(
      widget.camera,
      ResolutionPreset.low,
    );
    initializeController = cameraController.initialize();
  }

TL; DR: пусть за инициализацию объекта камеры отвечает родитель виджета.

0 голосов
/ 11 июля 2020

Попробовать

cameraController != null && cameraController.value.isInitialized?
CameraPreview(cameraController):Container()
...