質問をすることでしか得られない、回答やアドバイスがある。

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

新規登録して質問してみよう
ただいま回答率
85.48%
Flutter

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

Dart

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

Q&A

解決済

2回答

1535閲覧

The argument type 'Null' can't be assigned to the parameter type 'Widget'.

ituking

総合スコア80

Flutter

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

Dart

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

0グッド

0クリップ

投稿2023/02/08 13:47

実現したいこと

  • The argument type 'Null' can't be assigned to the parameter type 'Widget'.を解決させて理想的な挙動を実現させる。

前提

FlutterのUI構築及びレスポンシブ対応の仕方を勉強するにあたり、Youtubeの動画を真似して勉強しています。

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

The argument type 'Null' can't be assigned to the parameter type 'Widget'.

該当のソースコード

home_screen.dart

1import 'package:facebook_clone/config/palette.dart'; 2import 'package:facebook_clone/data/data.dart'; 3import 'package:facebook_clone/widgets/circle_button.dart'; 4import 'package:flutter/material.dart'; 5import 'package:material_design_icons_flutter/material_design_icons_flutter.dart'; 6import 'package:facebook_clone/widgets/widgets.dart'; 7 8import '../models/models.dart'; 9 10class HomeScreen extends StatelessWidget { 11 const HomeScreen({super.key}); 12 13 @override 14 Widget build(BuildContext context) { 15 return GestureDetector( 16 onTap: () => FocusScope.of(context).unfocus(), 17 child: Scaffold( 18 body: Responsive( 19 mobile: _HomeScreenMobile(), 20 desktop: _HomeScreenDesktop(), 21 tablet: null, 22 ), 23 ), 24 ); 25 } 26} 27 28class _HomeScreenMobile extends StatelessWidget { 29 const _HomeScreenMobile({super.key}); 30 31 @override 32 Widget build(BuildContext context) { 33 return CustomScrollView( 34 slivers: [ 35 SliverAppBar( 36 brightness: Brightness.light, 37 backgroundColor: Colors.white, 38 title: Text( 39 "facebook", 40 style: TextStyle( 41 color: Palette.facebookBlue, 42 fontSize: 28.0, 43 fontWeight: FontWeight.bold, 44 letterSpacing: -1.2, 45 ), 46 ), 47 centerTitle: false, 48 floating: true, 49 actions: [ 50 CircleButton( 51 icon: Icons.search, 52 iconSize: 30.0, 53 onPressed: () => print("Search"), 54 ), 55 CircleButton( 56 icon: MdiIcons.facebookMessenger, 57 iconSize: 30.0, 58 onPressed: () => print("Messenger"), 59 ), 60 ], 61 ), 62 SliverToBoxAdapter( 63 child: CreatePostContainer(currentUser: currentUser), 64 ), 65 SliverPadding( 66 padding: const EdgeInsets.fromLTRB(0.0, 10.0, 0.0, 5.0), 67 sliver: SliverToBoxAdapter( 68 child: Rooms(onlineUsers: onlineUsers), 69 ), 70 ), 71 SliverPadding( 72 padding: const EdgeInsets.fromLTRB(0.0, 5.0, 0.0, 5.0), 73 sliver: SliverToBoxAdapter( 74 child: Stories( 75 currentUser: currentUser, 76 stories: stories, 77 ), 78 ), 79 ), 80 SliverList( 81 delegate: SliverChildBuilderDelegate( 82 (context, index) { 83 final Post post = posts[index]; 84 return PostContainer(post: post); 85 }, 86 childCount: posts.length, 87 ), 88 ), 89 ], 90 ); 91 } 92} 93 94class _HomeScreenDesktop extends StatelessWidget { 95 const _HomeScreenDesktop({super.key}); 96 97 @override 98 Widget build(BuildContext context) { 99 return Row( 100 children: [ 101 Flexible( 102 flex: 2, 103 child: Container( 104 color: Colors.orange, 105 ), 106 ), 107 Spacer(), 108 Container( 109 width: 600.0, 110 color: Colors.red, 111 ), 112 Spacer(), 113 Flexible( 114 flex: 2, 115 child: Container( 116 color: Colors.blue, 117 ), 118 ), 119 ], 120 ); 121 } 122} 123

responsive.dart

1import 'package:flutter/material.dart'; 2 3class Responsive extends StatelessWidget { 4 final Widget mobile; 5 final Widget tablet; 6 final Widget desktop; 7 const Responsive({ 8 super.key, 9 required this.mobile, 10 required this.tablet, 11 required this.desktop, 12 }); 13 14 static bool isMobile(BuildContext context) => 15 MediaQuery.of(context).size.width < 800; 16 17 static bool isTablet(BuildContext context) => 18 MediaQuery.of(context).size.width >= 800 && 19 MediaQuery.of(context).size.width < 1200; 20 21 static bool isDesktop(BuildContext context) => 22 MediaQuery.of(context).size.width >= 1200; 23 24 @override 25 Widget build(BuildContext context) { 26 return LayoutBuilder( 27 builder: (context, constraints) { 28 if (constraints.maxWidth >= 1200) { 29 return desktop; 30 } else if (constraints.maxWidth >= 800) { 31 return tablet; 32 } else { 33 return mobile; 34 } 35 }, 36 ); 37 } 38}

試したこと

警告メッセージはhome_screen.dart内の21行目tablet: null, で発生しており、responsive.dart内で定義したResponsiveクラス内に変数tabletとして定義しているが、home_screen.dart内ではnullになっているために発生したエラーです。
Responsiveクラスの定義内でmobile, tablet, desktopに対してnull check operatorを使用しているので、mobile, tablet, やdesktopは必須である(必ず引数として渡される)前提のロジックです。ここでの最適な解決法(変数宣言時にnullを許容したり)をググったり、試したりというのを20分ほど試行錯誤しましたが解決に至らなかったので有識者の方にご教示していただきたいです。さらなる情報提供依頼はコメントにてよろしくお願いします。responsive.dartはwidgets.dartにexportされ、home_screen.dartがwidgets.dartをimportする形となっています。よろしくお願いします。

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

[✓] Flutter (Channel stable, 3.3.10, on macOS 13.0.1
22A400 darwin-x64, locale ja-JP)
[✓] Android toolchain - develop for Android devices
(Android SDK version 32.1.0-rc1)
[✓] Xcode - develop for iOS and macOS (Xcode 14.2)
[✓] Chrome - develop for the web
[✓] Android Studio (version 2021.2)
[✓] VS Code (version 1.74.3)
[✓] Connected device (3 available)
[✓] HTTP Host Availability

参考にしている動画
https://www.youtube.com/watch?v=HvLb5gdUfDE&t=62s

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

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

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

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

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

guest

回答2

0

提示されたyoutubeチャンネルとそれにリンクするgithubのソースを見ると以下の様になってます。

https://github.com/MarcusNg/flutter_facebook_responsive_ui/blob/master/lib/widgets/responsive.dart

Null対応されていませんがもし対応するとしたら以下の様な感じになるのでしょうか。

dart

1import 'package:flutter/material.dart'; 2 3class Responsive extends StatelessWidget { 4 final Widget mobile; 5 final Widget? tablet;// これがnull許容な変数 6 final Widget desktop; 7 8 const Responsive({ 9 Key? key, 10 required this.mobile, 11 this.tablet, // null許容なので必須パラメータではない 12 required this.desktop, 13 }) : super(key: key); 14 15 static bool isMobile(BuildContext context) => 16 MediaQuery.of(context).size.width < 800; 17 18 static bool isTablet(BuildContext context) => 19 MediaQuery.of(context).size.width >= 800 && 20 MediaQuery.of(context).size.width < 1200; 21 22 static bool isDesktop(BuildContext context) => 23 MediaQuery.of(context).size.width >= 1200; 24 25 26 Widget build(BuildContext context) { 27 return LayoutBuilder( 28 builder: (context, constraints) { 29 if (constraints.maxWidth >= 1200) { 30 return desktop; 31 } else if (constraints.maxWidth >= 800) { 32 return tablet ?? mobile; // tabletがnullならmobileを使う 33 } else { 34 return mobile; 35 } 36 }, 37 ); 38 } 39}

tabletがnull許容でnullだったらmobileを充当するという実装になってます。

オリジナルのソースもしくは動画をきちんと見てれば、とりあえず違いは分かるのでは?
まあ、それ以前にnull許容非対応のソースを参考にするのは、初心者の教育用としてはどうかとは思いますが。

投稿2023/02/09 08:13

ta.fu

総合スコア1667

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

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

0

ベストアンサー

まず「アプリをどういう挙動にしたいのか」という要求があって、その要求に対する最適な解決法が決まる、ということですよね。
とりあえずエラーが出ないようにするには、nullを渡さずに下記のように非null値を渡したら良いと思います。

body: Responsive( mobile: _HomeScreenMobile(), desktop: _HomeScreenDesktop(), tablet: _HomeScreenTablet(), //←非null値を渡す ),
class _HomeScreenTablet extends StatelessWidget { //必要な定義用コード //... }

あるいは、tabletは不要、ということならResponsiveクラスのtabletフィールドと関連するロジック箇所を削除することになりますよね。

投稿2023/02/09 03:32

moriman

総合スコア615

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

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

ituking

2023/02/09 04:04

回答ありがとうございます。 確かにnullでエラーメッセージが出るなら、最初の定義時にtabletフィールドは定義しないということも考えましたが、参考動画では定義したままエラーが発生せずに進んでいたので、とりあえずクラスなども定義せずにエラーメッセージも出てこない簡単な解決法などがあるのかな?という認識でした。
ituking

2023/02/10 09:35

適切な回答ありがとうございました。基本に対してぼんやりしているところがあったので、それに対しての明示的な回答をいただくことができ解決できました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問