【问题标题】:flutter Image is not capturing onTap button unless doing hot reload除非进行热重载,否则颤动图像不会捕获 onTap 按钮
【发布时间】:2022-01-21 12:24:12
【问题描述】:

我试图在点击 InkWell 按钮时捕捉图像,但没有捕捉到任何东西,但它只有在热重新加载应用程序后才能正常工作。我不明白错误在哪里。谁能帮我在不进行热重载的情况下捕获图像?提前谢谢你。 pubspec.yaml

environment:
  sdk: ">=2.12.0 <3.0.0"

dependencies:
  flutter:
    sdk: flutter

  cupertino_icons: ^1.0.2
  camera: ^0.9.4+5
  path_provider: ^2.0.0
  video_player: ^2.1.4

main.dart

import 'dart:async';
import 'dart:io';
import 'package:camera_screen/camera_captured_preview.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:camera/camera.dart';
import 'package:video_player/video_player.dart';

List<CameraDescription> ? cameras;

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();

  cameras = await availableCameras();
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({Key? key}) : super(key: key);

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

class _MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: CameraApp(),
    );
  }
}


class CameraApp extends StatefulWidget {
  @override
  _CameraAppState createState() => _CameraAppState();
}

class _CameraAppState extends State<CameraApp> {
   CameraController? controller;
  late Future  <void>  cameraValue;
   XFile? imageFile;
   VideoPlayerController? videoController;

  @override
  void initState() {
    super.initState();
    controller = CameraController(cameras![0], ResolutionPreset.high);
    cameraValue = controller!.initialize();
  }

  @override
  void dispose() {
    controller!.dispose();
    super.dispose();
  }

   final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();

  @override
  Widget build(BuildContext context) {
    final size = MediaQuery.of(context).size;
    final deviceRatio = size.width / size.height;
    return Scaffold(
      body: Stack(
        children: [
          FutureBuilder(
            future: cameraValue,
            builder: (context, snapshot) =>
            snapshot.connectionState == ConnectionState.done
                ? Transform.scale(
              scale: controller!.value.aspectRatio/deviceRatio,
                child: Center(
                    child: AspectRatio(
                      aspectRatio: controller!.value.aspectRatio,
                        child: CameraPreview(controller!),),),)
                : Center(child: CircularProgressIndicator(),),
          ),
          Positioned(
            top: 25.0,
            child: Container(
              width: MediaQuery.of(context).size.width,
              child: Row(
                mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                crossAxisAlignment: CrossAxisAlignment.center,
                mainAxisSize: MainAxisSize.max,
                children: [
                  IconButton(
                    onPressed: () {},
                    icon: Icon(
                      Icons.flash_off,
                      color: Colors.white,
                      size: 28,
                    ),),
                  IconButton(
                    onPressed: () {},
                    icon: Icon(
                      Icons.clear,
                      color: Colors.white,
                      size: 28,
                    ),),
                ],
              ),
            ),
          ),
          Positioned(
            bottom: 0.0,
            child: Container(
              color: Colors.black,
              width: MediaQuery.of(context).size.width,
              child: Row(
                mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                crossAxisAlignment: CrossAxisAlignment.center,
                mainAxisSize: MainAxisSize.max,
                children: [
                  IconButton(
                    onPressed: () {},
                    icon: Icon(
                      Icons.collections,
                      color: Colors.white,
                      size: 28,
                    ),),
                  _thumbnailWidget(),
                  captureControlWidget(),
                  IconButton(
                    onPressed: () {},
                    icon: Icon(
                      Icons.flip_camera_android,
                      color: Colors.white,
                      size: 28,
                    ),),
                ],
              ),
            ),
          ),
        ],
      ),
    );
  }

/// Display the control bar with buttons to take pictures and record videos.
   Widget captureControlWidget(){
    final CameraController? cameraController = controller;
    logError("cameracontroller", "");
    return InkWell(
      child: const Icon(Icons.panorama_fish_eye,color: Colors.white,size: 68,),
      onTap: cameraController != null &&
          cameraController.value.isInitialized &&
          !cameraController.value.isRecordingVideo
          ? onTakePictureButtonPressed
          : null,
    );
}

   void onTakePictureButtonPressed() {
    logError("onTakePictureButtonPressed", "");
     takePicture().then((XFile? file) async {
       if (mounted) {
         setState(() {
           imageFile = file;
           videoController?.dispose();
           videoController = null;
         });
         ///await Navigator.push(context, MaterialPageRoute(builder: (builder) => CameraCapturedPreview(imagePath:imageFile!)));
         if (file != null) showInSnackBar('Picture saved to ${file.path}');
         await Navigator.push(context, MaterialPageRoute(builder: (builder) => CameraCapturedPreview(imagePath:imageFile)));
       }
     });
     ///Navigator.push(context, MaterialPageRoute(builder: (builder) => CameraCapturedPreview(imagePath:imageFile!)));
   }

   Widget _thumbnailWidget() {
     final VideoPlayerController? localVideoController = videoController;

     return Container(
       child: localVideoController == null && imageFile == null
           ? Container(
         decoration: BoxDecoration(
             border: Border.all(
                 color: Colors.white)),
         width: 50.0,
         height: 50.0,
       )
           : SizedBox(
         child: (localVideoController == null)
             ? (
             // The captured image on the web contains a network-accessible URL
             // pointing to a location within the browser. It may be displayed
             // either with Image.network or Image.memory after loading the image
             // bytes to memory.
             kIsWeb
                 ? Image.network(imageFile!.path)
                 : Image.file(File(imageFile!.path)))
             : Container(
           child: Center(
             child: AspectRatio(
                 aspectRatio:
                 localVideoController.value.size != null
                     ? localVideoController
                     .value.aspectRatio
                     : 1.0,
                 child: VideoPlayer(localVideoController)),
           ),
           decoration: BoxDecoration(
               border: Border.all(
                   color: Colors.black)),
         ),
         width: 64.0,
         height: 64.0,
       ),
     );
   }

   Future<XFile?> takePicture() async {
    logError("takepicture", "");
     final CameraController? cameraController = controller;
     if (cameraController == null || !cameraController.value.isInitialized) {
       showInSnackBar('Error: select a camera first.');
       return null;
     }

     if (cameraController.value.isTakingPicture) {
       // A capture is already pending, do nothing.
       return null;
     }

     try {
       XFile file = await cameraController.takePicture();
       return file;
     } on CameraException catch (e) {
       _showCameraException(e);
       return null;
     }

   }

   void _showCameraException(CameraException e) {
     logError(e.code, e.description);
     showInSnackBar('Error: ${e.code}\n${e.description}');
   }

   void showInSnackBar(String message) {
     // ignore: deprecated_member_use
     _scaffoldKey.currentState?.showSnackBar(SnackBar(content: Text(message)));
   }

   void logError(String code, String? message) {
     if (message != null) {
       print('Error: $code\nError Message: $message');
     } else {
       print('Error: $code');
     }
   }
}

camera_captured_preview.dart

import 'dart:io';
import 'package:camera/camera.dart';
import 'package:flutter/material.dart';

class CameraCapturedPreview extends StatelessWidget {
  const CameraCapturedPreview({Key? key,  this.imagePath }) : super(key: key);
  final XFile? imagePath;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        actions: [
          IconButton(
              onPressed: () {},
              icon: Icon(
                Icons.crop_rotate,
                size: 27,
              ),),
          IconButton(
            onPressed: () {},
            icon: Icon(
              Icons.emoji_emotions_outlined,
              size: 27,
            ),),
          IconButton(
            onPressed: () {},
            icon: Icon(
              Icons.title,
              size: 27,
            ),),
          IconButton(
            onPressed: () {},
            icon: Icon(
              Icons.edit,
              size: 27,
            ),),
        ],
      ),
      body: Container(
        height: MediaQuery.of(context).size.height,
        width: MediaQuery.of(context).size.width,
        child: Stack(
          children: [
            Container(
              height: MediaQuery.of(context).size.height - 150,
              width: MediaQuery.of(context).size.width,
              child: Image.file(File(imagePath!.path),
              fit: BoxFit.cover,
              ),
            ),
          ],
        ),
      ),
    );
  }
}

【问题讨论】:

  • 您提供的代码sn-ps实际上并没有显示您调用与点击相关的任何内容,也没有显示实际捕获预览的方法,因此任何人都很难帮助您回答您的问题。你能提供更多细节吗?
  • 嘿@Bram 抱歉迟到了,这里是void onTakePictureButtonPressed() { takePicture().then((XFile? file) async { if (mounted) { setState(() { imageFile = file; videoController?.dispose(); videoController = null; }); if (file != null) showInSnackBar('Picture saved to ${file.path}'); await Navigator.push(context, MaterialPageRoute(builder: (builder) =&gt; CameraCapturedPreview(imagePath:imageFile))); } }); }

标签: flutter dart flutter-layout flutter-dependencies flutter-state


【解决方案1】:
you can use package image_picker to pick images from camera.
just take a blank file object in your statefull class.
File _imageFile ;

    Future<File> pickImages()async {
   File imageFile ;
   final pickerFile = await  ImagePicker().pickImage(source: 
    ImageSource.camera);
    if (pickedFile != null) {
      setState(() {
        imageFile = File(pickedFile.path);
        print('image' + _imageFile.toString());
        // _avatarBase64 = convertFileToBase64(_imageFile);
      });
    } else {
      print('No image selected.');
    }
   return imageFile ;
    }

    just use this method , it will give you file and then you can display 
    this file to image widget.
// widget part 
  _imageFile != null ?
    Image.file(imageFile) : SizedBox() ,

【讨论】:

    【解决方案2】:

    尝试在初始化状态下添加它 cameras = await availableCameras();

    【讨论】:

    • 我试过一个它给出异常说_CameraAppState.initState() returned a Future.State.initState() must be a void method without an async keyword.
    • 在初始化状态下添加一个方法addCamera();。然后用`addCamera() async{camera = await availableCameras();}定义init外部的方法。 setState((){}); `
    • 我试过 @Kaushik 兄弟,没用,我观察到 cameraController.value.isInitialized 在 captureControlWidget() 中返回 false 即使我初始化为 final CameraController? cameraController = controller; 所以我在三元条件下删除了 cameraController.value.isInitialized它的工作。这是正确的方法吗?我可以那样做吗?
    猜你喜欢
    • 2020-07-03
    • 2020-07-02
    • 2020-12-23
    • 2020-12-07
    • 1970-01-01
    • 1970-01-01
    • 2021-06-11
    • 2019-09-21
    • 2011-12-22
    相关资源
    最近更新 更多