【问题标题】:Showing the error Incorrect use of ParentDataWidget. any solutions显示错误 ParentDataWidget 的使用不正确。任何解决方案
【发布时间】:2021-06-08 01:46:42
【问题描述】:
import 'dart:io';

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:camera/camera.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:shoutout_studio/views/camera/profile_screen.dart';
import 'package:video_player/video_player.dart';

class CameraScreen extends StatefulWidget {
  @override
  _CameraScreenState createState() => _CameraScreenState();
}

bool isRecording = false;

class _CameraScreenState extends State<CameraScreen>
    with WidgetsBindingObserver {
  final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();

  CameraController controller;
  List cameras;
  int selectedCameraIdx;
  XFile videoFile;
  XFile imageFile;
  VideoPlayerController videoController;
  VoidCallback videoPlayerListener;
  bool enableAudio = true;

  @override
  void initState() {
    super.initState();

    availableCameras().then((availableCameras) {
      cameras = availableCameras;
      if (cameras.length > 0) {
        setState(() {
          selectedCameraIdx = 0;
        });
        _initCameraController(cameras[selectedCameraIdx]).then((void v) {});
      } else {
        print('NO Camera Available');
      }
    }).catchError((err) {
      print('Error: $err.code\nError Message: $err.message');
    });
  }

  Future _initCameraController(CameraDescription cameraDescription) async {
    if (controller != null) {
      await controller.dispose();
    }

    controller = CameraController(cameraDescription, ResolutionPreset.high);

    controller.addListener(() {
      if (mounted) {
        setState(() {});
      }
      if (controller.value.hasError) {
        print('Camera error ${controller.value.errorDescription}');
      }
    });

    try {
      await controller.initialize();
    } on CameraException catch (e) {
      _showCameraException(e);
    }
    if (mounted) {
      setState(() {});
    }
  }

  @override
  Widget build(BuildContext context) {
    var size = MediaQuery.of(context).size;

    return Scaffold(
      body: Stack(
        children: <Widget>[
          Container(
            height: MediaQuery.of(context).size.height,
            child: _cameraPreviewWidget(),
          ),
          Container(
            height: MediaQuery.of(context).size.height * 0.27,
            color: Colors.black.withOpacity(0.58),
            child: Column(
              children: [
                Padding(
                  padding: EdgeInsets.only(
                    top: size.height * 0.015,
                    right: size.width * 0.05,
                    left: size.width * 0.05,
                  ),
                  child: Row(
                    children: [
                      Column(
                        children: [
                          SizedBox(
                            height: size.height * 0.01,
                          ),
                          GestureDetector(
                            onTap: () {
                              Navigator.of(context).pop();
                              controller.dispose();
                            },
                            child: Image(
                              height: size.height * 0.03,
                              image: AssetImage('assets/icons/back_arrow.png'),
                            ),
                          ),
                        ],
                      ),
                      SizedBox(
                        width: size.width * 0.05,
                      ),
                      Column(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: [
                          SizedBox(
                            height: size.height * 0.02,
                          ),
                          Text(
                            'Identity Verification Script',
                            textAlign: TextAlign.center,
                            style: GoogleFonts.quicksand(
                              fontSize: size.width * 0.048,
                              fontWeight: FontWeight.w500,
                              color: Colors.white,
                            ),
                          ),
                          SizedBox(
                            height: size.height * 0.01,
                          ),
                          Container(
                            height: 3,
                            width: size.width * 0.2,
                            decoration: BoxDecoration(
                              gradient: LinearGradient(
                                  begin: Alignment.topLeft,
                                  end: Alignment.bottomRight,
                                  colors: [
                                    Color(0xffFD0C92),
                                    Color(0xf0FD0C92),
                                    Colors.yellow[200],
                                  ]),
                            ),
                          )
                        ],
                      ),
                    ],
                  ),
                ),
                Padding(
                  padding: const EdgeInsets.all(16.0),
                  child: Text(
                    'Hi',
                    textAlign: TextAlign.center,
                    style: GoogleFonts.quicksand(
                      color: Colors.white,
                      fontSize: size.width * 0.04,
                    ),
                  ),
                ),
              ],
            ),
          ),
          Padding(
            padding: EdgeInsets.only(
              top: MediaQuery.of(context).size.height * 0.52,
              left: MediaQuery.of(context).size.width * 0.84,
            ),
            child: _cameraTogglesRowWidget(),
          ),
          Padding(
            padding: EdgeInsets.only(
              top: MediaQuery.of(context).size.height * 0.8,
            ),
            child: Container(
              decoration: BoxDecoration(
                color: Colors.black.withOpacity(0.58),
                borderRadius: BorderRadius.only(
                  topLeft: Radius.circular(60.0),
                  topRight: Radius.circular(60.0),
                ),
              ),
              child: Padding(
                padding: const EdgeInsets.all(8.0),
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    Padding(
                      padding: const EdgeInsets.symmetric(horizontal: 30.0),
                      child: Column(
                        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                        mainAxisSize: MainAxisSize.max,
                        children: [
                          Text(
                            'Replay',
                            style: GoogleFonts.quicksand(
                              color: Colors.white,
                            ),
                          ),
                          GestureDetector(
                            child: Container(
                              height: size.height * 0.08,
                              width: size.width * 0.13,
                              decoration: BoxDecoration(
                                image: DecorationImage(
                                  image: AssetImage(
                                    'assets/images/replay.png',
                                  ),
                                  fit: BoxFit.fill,
                                ),
                              ),
                            ),
                            onTap: () {
                              //_startVideoPlayer();
                            },
                          ),
                        ],
                      ),
                    ),
                    Padding(
                      padding: const EdgeInsets.symmetric(horizontal: 20.0),
                      child: _captureControlRowWidget(context),
                    ),
                    Padding(
                      padding: const EdgeInsets.symmetric(horizontal: 30.0),
                      child: Column(
                        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                        mainAxisSize: MainAxisSize.max,
                        children: [
                          Text(
                            'Upload',
                            style: GoogleFonts.quicksand(
                              color: Colors.white,
                            ),
                          ),
                          GestureDetector(
                            child: Container(
                              height: size.height * 0.08,
                              width: size.width * 0.13,
                              decoration: BoxDecoration(
                                image: DecorationImage(
                                  image: AssetImage(
                                    'assets/images/upload.png',
                                  ),
                                  fit: BoxFit.fill,
                                ),
                              ),
                            ),
                            onTap: () {
                              Navigator.push(
                                context,
                                MaterialPageRoute(
                                  builder: (context) => ProfilePicture(),
                                ),
                              );
                              controller.dispose();
                            },
                          ),
                        ],
                      ),
                    ),
                  ],
                ),
              ),
            ),
          ),
          SizedBox(height: 20.0)
        ],
      ),
    );
  }

  Widget _cameraPreviewWidget() {
    if (controller == null || !controller.value.isInitialized) {
      return const Text(
        'Loading',
        style: TextStyle(
          color: Colors.white,
          fontSize: 20.0,
          fontWeight: FontWeight.w900,
        ),
      );
    }

    return AspectRatio(
      aspectRatio: controller.value.aspectRatio,
      child: CameraPreview(controller),
    );
  }

  Widget _captureControlRowWidget(context) {
    return Expanded(
      child: Align(
        alignment: Alignment.center,
        child: Column(
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
          mainAxisSize: MainAxisSize.max,
          children: [
            Text(
              'Record',
              style: GoogleFonts.quicksand(
                color: Colors.white,
              ),
            ),
            GestureDetector(
              child: CircleAvatar(
                backgroundColor: Colors.white,
                radius: 30,
                child: Icon(
                  isRecording ? Icons.pause : Icons.fiber_manual_record_rounded,
                  color: Colors.red,
                  size: 35,
                ),
              ),
              onTap: () => isRecording
                  ? onStopButtonPressed()
                  : onVideoRecordButtonPressed(),
            ),
          ],
        ),
      ),
    );
  }

  Widget _cameraTogglesRowWidget() {
    if (cameras == null || cameras.isEmpty) {
      return Spacer();
    }

    return Expanded(
      child: Align(
        alignment: Alignment.centerLeft,
        child: GestureDetector(
          onTap: () => _onSwitchCamera(),
          child: Container(
            height: 25,
            width: 25,
            decoration: BoxDecoration(
              image: DecorationImage(
                image: AssetImage(
                  'assets/images/reverse.png',
                ),
                fit: BoxFit.fill,
              ),
            ),
          ),
        ),
      ),
    );
  }

  void _onSwitchCamera() {
    selectedCameraIdx =
        selectedCameraIdx < cameras.length - 1 ? selectedCameraIdx + 1 : 0;
    CameraDescription selectedCamera = cameras[selectedCameraIdx];
    _initCameraController(selectedCamera);
  }

  void onVideoRecordButtonPressed() {
    isRecording = true;
    startVideoRecording().then((_) {
      if (mounted) setState(() {});
    });
  }

  void onStopButtonPressed() {
    isRecording = false;
    stopVideoRecording().then((file) {
      if (mounted) setState(() {});
      if (file != null) {
        showInSnackBar('Video recorded to ${file.path}');
        videoFile = file;
      }
    }, onError: (e) {
      print(e);
    });
  }

  Future<void> startVideoRecording() async {
    if (!controller.value.isInitialized) {
      showInSnackBar('Error: select a camera first.');
      return;
    }

    if (controller.value.isRecordingVideo) {
      // A recording is already started, do nothing.
      return;
    }
    try {
      await controller.startVideoRecording();
    } on CameraException catch (e) {
      _showCameraException(e);
      return;
    }
  }

  Future<XFile> stopVideoRecording() async {
    if (!controller.value.isRecordingVideo) {
      return null;
    }

    try {
      return controller.stopVideoRecording();
    } on CameraException catch (e) {
      _showCameraException(e);
      return null;
    }
  }

  Future<void> _startVideoPlayer() async {
    final VideoPlayerController vController =
        VideoPlayerController.file(File(videoFile.path));
    videoPlayerListener = () {
      if (videoController != null && videoController.value.size != null) {
        // Refreshing the state to update video player with the correct ratio.
        if (mounted) setState(() {});
        videoController.removeListener(videoPlayerListener);
      }
    };
    vController.addListener(videoPlayerListener);
    await vController.setLooping(false);
    await vController.initialize();
    await videoController?.dispose();
    if (mounted) {
      setState(() {
        imageFile = null;
        videoController = vController;
      });
    }
    await vController.play();
  }

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

  void _showCameraException(CameraException e) {
    String errorText = 'Error: ${e.code}\nError Message: ${e.description}';
    print(errorText);

    print('Error: ${e.code}\n${e.description}');
  }
}

我正在创建一个摄像头记录页面,这就是我所做的,但我收到了这个错误,但我不知道如何解决这个问题。我以为这是由于相机预览小部件造成的,但我搜索了此异常并找到此链接incorrect use of parent data widget. expanded widgets must be placed inside flex widgets

【问题讨论】:

    标签: flutter flutter-layout


    【解决方案1】:

    特别是,在使用堆栈时,您不能相对于子级的大小或堆栈自身的大小来定位子级。 Stack 小部件的每个子项要么已定位,要么未定位。 Positioned 子对象是那些包装在 Positioned 小部件中的子对象,该小部件至少具有一个非 null 属性。堆栈自己调整大小以包含所有未定位的子项,这些子项根据对齐方式进行定位(在从左到右的环境中默认为左上角,在从右到左的环境中默认为右上角)。然后根据它们的 top、right、bottom 和 left 属性相对于堆栈放置定位的子项。

    Expanded 只能放在 ColumnRowFlex 小部件内。

    【讨论】:

    • ParentDataWidget Expanded(flex: 1) 想要将 FlexParentData 类型的 ParentData 应用于 RenderObject,该 RenderObject 已设置为接受不兼容类型 BoxParentData 的 ParentData。接收到不兼容父数据的 RenderObject 的所有权链为: SizedBox.shrink ← Expanded ← Spacer ← Padding ← Stack ← _BodyBuilder ← MediaQuery ← LayoutId-[<_scaffoldslot.body>] ← CustomMultiChildLayout ← AnimatedBuilder ←⋯
    • 尝试将您的Expanded 小部件包装在Column 中。您将它们放置在 Padding 中
    • 感谢我在容器中插入了一个测试小部件,异常消失了
    猜你喜欢
    • 2021-01-22
    • 2022-11-24
    • 2023-02-22
    • 1970-01-01
    • 2020-11-18
    • 2021-04-14
    • 2017-06-13
    • 2021-01-20
    • 2016-06-21
    相关资源
    最近更新 更多