🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Flutter

Flutterは、iOSとAndroidのアプリを同じコードで開発するためのフレームワークです。オープンソースで開発言語はDart。双方のプラットフォームにおける高度な実行パフォーマンスと開発効率を提供することを目的としています。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Dart

Dartは、Googleによって開発されたJavaScriptの代替となることを目的に作られた、ウェブ向けのプログラミング言語である。

Q&A

解決済

1回答

1549閲覧

【Flutter】画面遷移先のエラーを無くしたい

cocona15531

総合スコア6

Flutter

Flutterは、iOSとAndroidのアプリを同じコードで開発するためのフレームワークです。オープンソースで開発言語はDart。双方のプラットフォームにおける高度な実行パフォーマンスと開発効率を提供することを目的としています。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Dart

Dartは、Googleによって開発されたJavaScriptの代替となることを目的に作られた、ウェブ向けのプログラミング言語である。

0グッド

0クリップ

投稿2021/03/03 02:39

前提・実現したいこと

Flutterでカメラについての記事を参考にさせて頂きながら、カメラアプリを作っています。
「カメラを起動」を押すとカメラを起動するようにしたいのですが、"_cameraNotAvailable"で引っかかってしまいカメラが起動できない状況です。

イメージ説明

Githubのリンク先

発生している問題・エラーメッセージ

E/flutter (28742): [ERROR:flutter/lib/ui/ui_dart_state.cc(177)] Unhandled Exception: NoSuchMethodError: The method '[]' was called on null.

該当箇所

if (_cameraNotAvailable) { final center = Center( child: Text('Camera not available /_\'), );

main.dart

dart

1import 'dart:async'; 2import 'dart:io'; 3 4import 'package:flutter/material.dart'; 5import 'package:camera/camera.dart'; 6import 'package:path_provider/path_provider.dart'; 7import 'camera.dart'; 8 9void main() { 10 runApp(new MyApp()); 11} 12 13class MyApp extends StatelessWidget { 14 15 Widget build (BuildContext context){ 16 return MaterialApp( 17 title: 'camera', 18 theme: ThemeData( 19 primarySwatch:Colors.blue, 20 ), 21 home: MyHomePage() 22 ); 23 } 24} 25class MyHomePage extends StatelessWidget{ 26 Widget build(BuildContext context){ 27 return Scaffold( 28 appBar:AppBar( 29 title: const Text('camera'), 30 actions: <Widget>[ 31 IconButton(icon: Icon(Icons.settings), 32 onPressed:(){}, 33 ) 34 ] 35 ), 36 body: Center( 37 child: RaisedButton(onPressed: () { 38 Navigator.push( 39 context, 40 MaterialPageRoute( 41 builder: (context) => TabCamera()), 42 ); 43 }, child: Text('カメラを起動')) 44 ), 45 ); 46 } 47}

該当のソースコード(camera.dart)

dart

1import 'dart:async'; 2import 'dart:io'; 3import 'package:flutter/material.dart'; 4import 'package:camera/camera.dart'; 5import 'package:path_provider/path_provider.dart'; 6import 'package:video_player/video_player.dart'; 7import 'main.dart'; 8 9List<CameraDescription> cameras; 10 11Future<void> main() async { 12 WidgetsFlutterBinding.ensureInitialized(); 13 cameras = await availableCameras(); 14 final firstCamera = cameras.first; 15 runApp(TabCamera()); 16} 17 18class TabCamera extends StatefulWidget { 19 final bool needScaffold; 20 21 TabCamera({this.needScaffold = false}); 22 23 24 _TabCameraState createState() => _TabCameraState(); 25} 26 27class _TabCameraState extends State<TabCamera> { 28 CameraController controller; 29 int _cameraIndex = 0; 30 bool _cameraNotAvailable = false; 31 32 final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>(); 33 34 void _showInSnackBar(String message) { 35 _scaffoldKey.currentState.showSnackBar(SnackBar(content: Text(message))); 36 } 37 38 void _initCamera(int index) async { 39 if (controller != null) { 40 await controller.dispose(); 41 } 42 controller = CameraController(cameras[index], ResolutionPreset.high); 43 44 // If the controller is updated then update the UI. 45 controller.addListener(() { 46 if (mounted) setState(() {}); 47 if (controller.value.hasError) { 48 _showInSnackBar('Camera error ${controller.value.errorDescription}'); 49 } 50 }); 51 52 try { 53 await controller.initialize(); 54 } on CameraException catch (e) { 55 _showCameraException(e); 56 } 57 58 if (mounted) { 59 setState(() { 60 _cameraIndex = index; 61 }); 62 } 63 } 64 65 void _onSwitchCamera() { 66 if (controller == null || 67 !controller.value.isInitialized || 68 controller.value.isTakingPicture) { 69 return; 70 } 71 final newIndex = _cameraIndex + 1 == cameras.length ? 0 : _cameraIndex + 1; 72 _initCamera(newIndex); 73 } 74 75 void _onTakePictureButtonPress() { 76 _takePicture().then((filePath) { 77 if (filePath != null) { 78 // _showInSnackBar('Picture saved to $filePath'); 79 Navigator.push(context, MaterialPageRoute(builder: (context) { 80 return Scaffold( 81 appBar: AppBar( 82 backgroundColor: Colors.black, 83 actions: <Widget>[ 84 IconButton( 85 icon: Icon(Icons.crop_rotate), 86 onPressed: () {}, 87 ), 88 IconButton( 89 icon: Icon(Icons.insert_emoticon), 90 onPressed: () {}, 91 ), 92 IconButton( 93 icon: Icon(Icons.text_fields), 94 onPressed: () {}, 95 ), 96 IconButton( 97 icon: Icon(Icons.edit), 98 onPressed: () {}, 99 ), 100 ], 101 ), 102 body: Container( 103 color: Colors.black, 104 child: Center( 105 child: Image.file(File(filePath)), 106 ), 107 ), 108 ); 109 })); 110 } 111 }); 112 } 113 114 String _timestamp() => DateTime.now().millisecondsSinceEpoch.toString(); 115 116 Future<String> _takePicture() async { 117 if (!controller.value.isInitialized || controller.value.isTakingPicture) { 118 return null; 119 } 120 final Directory extDir = await getApplicationDocumentsDirectory(); 121 final String dirPath = '${extDir.path}/Pictures/whatsapp_clone'; 122 await Directory(dirPath).create(recursive: true); 123 final String filePath = '$dirPath/${_timestamp()}.jpg'; 124 125 try { 126 await controller.takePicture(filePath); 127 } on CameraException catch (e) { 128 _showCameraException(e); 129 return null; 130 } 131 return filePath; 132 } 133 134 void _showCameraException(CameraException e) { 135 _showInSnackBar('Error: ${e.code}\n${e.description}'); 136 } 137 138 Widget _buildGalleryBar() { 139 final barHeight = 90.0; 140 final vertPadding = 10.0; 141 142 return Container( 143 height: barHeight, 144 child: ListView.builder( 145 padding: EdgeInsets.symmetric(vertical: vertPadding), 146 scrollDirection: Axis.horizontal, 147 itemBuilder: (BuildContext context, int _) { 148 return Container( 149 padding: EdgeInsets.only(right: 5.0), 150 width: 70.0, 151 height: barHeight - vertPadding * 2, 152 child: Image( 153 fit: BoxFit.cover, 154 ), 155 ); 156 }, 157 ), 158 ); 159 } 160 161 Widget _buildControlBar() { 162 return Row( 163 mainAxisAlignment: MainAxisAlignment.spaceAround, 164 children: <Widget>[ 165 IconButton( 166 color: Colors.white, 167 icon: Icon(Icons.flash_auto), 168 onPressed: () {}, 169 ), 170 GestureDetector( 171 onTap: _onTakePictureButtonPress, 172 child: Container( 173 height: 80.0, 174 width: 80.0, 175 decoration: BoxDecoration( 176 shape: BoxShape.circle, 177 border: Border.all( 178 color: Colors.white, 179 width: 5.0, 180 ), 181 ), 182 ), 183 ), 184 IconButton( 185 color: Colors.white, 186 icon: Icon(Icons.switch_camera), 187 onPressed: _onSwitchCamera, 188 ), 189 ], 190 ); 191 } 192 193 194 void initState() { 195 super.initState(); 196 if (cameras == null || cameras.isEmpty) { 197 setState(() { 198 _cameraNotAvailable = true; 199 }); 200 } 201 _initCamera(_cameraIndex); 202 } 203 204 205 Widget build(BuildContext context) { 206 if (_cameraNotAvailable) { 207 final center = Center( 208 child: Text('Camera not available /_\'), 209 ); 210 211 if (widget.needScaffold) { 212 return Scaffold( 213 appBar: AppBar(), 214 body: center, 215 ); 216 } 217 218 return center; 219 } 220 221 final stack = Stack( 222 children: <Widget>[ 223 Container( 224 color: Colors.black, 225 child: Center( 226 child: controller.value.isInitialized 227 ? AspectRatio( 228 aspectRatio: controller.value.aspectRatio, 229 child: CameraPreview(controller), 230 ) 231 : Text('Loading camera...'), 232 ), 233 ), 234 Column( 235 mainAxisAlignment: MainAxisAlignment.end, 236 children: <Widget>[ 237 _buildGalleryBar(), 238 _buildControlBar(), 239 Container( 240 padding: EdgeInsets.symmetric(vertical: 10.0), 241 child: Text( 242 'Tap for photo', 243 style: Theme.of(context) 244 .textTheme 245 .subhead 246 .copyWith(color: Colors.white), 247 ), 248 ) 249 ], 250 ) 251 ], 252 ); 253 254 if (widget.needScaffold) { 255 return Scaffold( 256 body: stack, 257 ); 258 } 259 260 return stack; 261 } 262 263 264 void dispose() { 265 super.dispose(); 266 if (controller != null) { 267 controller.dispose(); 268 } 269 } 270}

試したこと

・"_cameraNotAvailable"の該当箇所を消してみても、今度は"value"がnullになってしまうエラーが発生してしまいます。

・if文を消したりしてみても上記と同様のエラーが発生してしまいます。

補足情報(FW/ツールのバージョンなど)

pubsec.yamlの該当パッケージのバージョンです。

camera: ^0.4.2
custom_image_picker: ^0.0.5
path_provider: ^1.6.27
video_player: ^1.0.1

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

E/flutter (28742): [ERROR:flutter/lib/ui/ui_dart_state.cc(177)] Unhandled Exception: NoSuchMethodError: The method '[]' was called on null.

おそらく
List<CameraDescription> cameras;のインスタンスが生成される前に呼び出されてエラーになっているように思います。

camerasのインスタンスが生成されているのは、

dart

1Future<void> main() async { 2 WidgetsFlutterBinding.ensureInitialized(); 3 cameras = await availableCameras(); 4 final firstCamera = cameras.first; 5 runApp(TabCamera()); 6}

この中だけであって、
その後のTabCamera classの方にはcamerasは渡されていません。
main関数の中で生成されたcamerasのインスタンスは、main関数の中のスコープでのみで使用できます。
引数としてcamerasを外部へと渡していく必要があると思います。
参考:https://teratail.com/questions/325618

投稿2021/03/03 05:12

Rassy

総合スコア44

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

cocona15531

2021/03/05 02:07

ご回答ありがとうございます。回答を基に試行錯誤してみたところ解決しました。また機会があれば宜しくお願い致します。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問