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

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

ただいまの
回答率

88.91%

flutter 画面遷移で値を渡せない。

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 174

otai0811

score 17

画面遷移で
https://flutter.dev/docs/cookbook/navigation/navigate-with-arguments
を参考にして、
1.渡したい変数を保持するclassを作る
2.画面遷移先で、変数を受け取る
3.routetableに画面遷移先を登録する
4.Navigatorをかく。
の手順で、値を渡す画面遷移を実装していたのですが、画面遷移をしようとボタンを押した際に画像のように、
type ScreenArgment is  not subtype of type ...
と言うエラーが出てしまいました。
subtypeは調べてみると、派生型と言うものらしいのですが、超初心者のため、いまいちよくつかめません。
このエラーの意味と対処法を教えていただけると幸いです。

import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutterokyaku/confirm.dart';
import 'package:shared_preferences/shared_preferences.dart';

void main() => runApp((new MyApp()));
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      routes: {
        ExtractArgumentsScreen.routeName: (context) => ExtractArgumentsScreen(),
      },
      title: 'okyaku',
      home: MyHomePage(


      ),
    );
  }
}

class ScreenArguments {
  String name;
  String gender;
  String age;
  String memo;



  ScreenArguments(this.name, this.gender,this.age,this.memo);
}


class MyHomePage extends StatefulWidget {


  @override
  _MyHomePageState createState() => _MyHomePageState();
}
enum gender { male, female }
 enumToString(_gender) {
  return _gender.toString().split('.')[1];
}

class _MyHomePageState extends State<MyHomePage> {
  String seibetu;
  final controller = TextEditingController();
  final controller2 = TextEditingController();
  String dropdownValue = '1';
  gender _gender = gender.male;
  String toshi;
  @override
  Widget build(BuildContext context) {
    print(_gender.toString());
    print(dropdownValue);
    print(controller.text);
    print(controller2.text);









    return Scaffold(
      appBar: AppBar(
        title: Text('お客様入力情報'),
      ),





      body:  Column(
        children: <Widget>[

          Row(
            children: <Widget>[
              Text('性別'),
              Radio(
                value: gender.male,
                groupValue: _gender,
                onChanged: (gender value) {
                  setState(() {
                    _gender = value;

                  });
                },

              ),



              Text('男性'),




              Radio(
                value: gender.female,
                groupValue: _gender,
                onChanged: (gender value) {
                  setState(() {
                    _gender = value;
                  });
                },
              ),
              Text('女性'),




            ],
          ),
          Row(
            children: <Widget>[
              Text('名前'),
              Container( // **
                // **** 例: Container 追加 *****
                width: 200,

                child: TextField(

                  decoration: InputDecoration(hintText: 'お名前を記入してください'),
                  controller: controller,
                ),
              )
            ],


          ),
          Row(
            children: <Widget>[
              Text('年齢'),
              DropdownButton<String>(
                value: dropdownValue,//ここで何番目のボタンかを選択

                icon: Icon(Icons.arrow_downward),
                iconSize: 24,
                elevation: 16,
                style: TextStyle(color: Colors.deepPurple),
                underline: Container(
                  height: 2,
                  color: Colors.deepPurpleAccent,
                ),
                onChanged: (String newValue) {
                  setState(() {
                    dropdownValue = newValue;
                  });
                },
                items: List<String>.generate(100,(int index)=>(index + 1).toString())
                    .map<DropdownMenuItem<String>>((String age) {
                  return DropdownMenuItem<String>(
                    value: age,
                    child: Text(age),
                  );

                }).toList(),






              ),




            ],
          ),
          Row(
            children: <Widget>[
              Text('メモ'),
              Container( // ****** 例: Container 追加 *****
                width: 200,
                child: TextFormField(
                  controller: controller2,
                  decoration: InputDecoration(hintText: 'ご自由にご記入ください'),
                ),
              )

            ],
          ),





          RaisedButton(
            child: Text("Navigate to screen that extracts arguments"),
            onPressed: () {
              // When the user taps the button, navigate to a named route
              // and provide the arguments as an optional parameter.
              Navigator.pushNamed(
                context,
                ExtractArgumentsScreen.routeName,
                arguments: ScreenArguments(
                  controller.text,
                  _gender.toString(),
                  dropdownValue,
                  controller2.text,












                ),
              );
            },
          ),




        ],

      ),

    );


  }
}
class ScreenArguments {
  String name;
  String gender;
  String age;
  String memo;



  ScreenArguments(this.name, this.gender,this.age,this.memo);
}


class ExtractArgumentsScreen extends StatelessWidget {
  static const routeName = '/extractArguments';

  @override
  Widget build(BuildContext context) {
    // Extract the arguments from the current ModalRoute settings and cast
    // them as ScreenArguments.
    final ScreenArguments args = ModalRoute.of(context).settings.arguments;//ここで変数の受け取りをおこな。

    return Scaffold(
      appBar: AppBar(
        title: Text('確認画面'),
      ),
      body: Column(
        children: <Widget>[
          Text('氏名:$args.name'),
          Text('性別:$args.gender'),
          Text('年齢:$args.age'),
          Text('メモ:$args.memo'),

        ],
      ),
    );
  }
}

イメージ説明

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+1

まず、質問文のコードにはScreenArgumentsクラスが二回定義されていますね。
エラーメッセージをみる限り、main.dartconfirm.dartにそれぞれ同じ名前のクラス(ScreenArguments)を定義していませんか?
そうであれば、定義しているファイルが別なので「全く別のクラス」として認識されます。
(ちなみに同じファイルに同じ名前のクラスを記述すると「重複しています」というエラーがでます)
main.dartに記載している定義を削除し、main.dartからconfirm.dartをインポートすれば解決するかと思います。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/07/09 00:57

    いつもご回答頂き、ありがとうございます。
    「定義しているファイルが別ならば違うクラスとして認識される」のですね。自分はどのファイルからもclass を参照できるようにと思って各ファイルに定義していましたが、それが問題だったのですね。
    確かに何重にも定義しなくても、インポートすれば良い話ですね。
    勉強になりました。いつも答えて頂きとても感謝しています。

    キャンセル

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

  • ただいまの回答率 88.91%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る