3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Scoped Model を利用した場合の画面遷移でうまくいったコード例(Flutter)

Last updated at Posted at 2019-11-24

最近Flutterをいじり始めました。Scoped Modelを利用するとスッキリ書けるので、そのコードを書いたときの画面遷移時に具体的にどうコードを書くとうまくいったかをレポートします。

[Scoped Model 初めて聞いた方へ]Scoped Model とは

公式のパッケージサイトは下記です。

基礎原理の解説について下記記事が参考になりました。

自分の言葉で書くと、数値や文字列の処理部分とデザインテンプレート部分をModel定義をすることで綺麗に分離ができます。あと、このパッケージは、GoogleのFlutter開発チームが提供してくれているVeggie Seasonsというアプリのコードにも採用されていたので、自分もやってみようと思いました。Veggie Seasonsのコードは以下です。

ページ遷移時の試行錯誤時のエラー解決で得た知見

今回はこちらを共有したいのです。Scoped Modelを使わない場合と比較できるように書いてみました。

#main.dart

//1:route定義をMaterialAppのところで行って、

void main() {

  runApp(MaterialApp(
    title: 'Demo',
    initialRoute: '/',
    routes: {
      '/': (context) => FirstScreen(),
      '/second': (context) => SecondScreen(),
    },
  ));
}

//2:↓最初のページに当たるFirstScreen部分のStatelessWidget記述です。

class FirstScreen extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      appBar: AppBar(
        title: Text('Demo'),
      ),
      body: Center(

      // 中略
      child: RaisedButton(
          padding: EdgeInsets.all(12.0),
          shape: StadiumBorder(),
          child: Text(
            "次のページへ",
            style: TextStyle(fontSize: 20.0, color: Colors.white),
          ),
          color: Colors.green,
          onPressed: () {

            Navigator.pushNamed(context, "/second");
            //3:↑で次のページ"SecondScreen()"へ移動クラス生成です。
          },
        ),

//次の画面(SecondScreen)
class SecondScreen extends StatelessWidget {

   //以下略SecondScreenの表示内容などが書かれています。

}

↑これをScoped Model 活用して記述する際、
下記のように書くとうまくいきました。  

#main.dart
import 'model.dart'; 
/*
↑model(今回はDemoModelという名称です)を別ファイルで定義しました。
このmodelそのものの部分の解説は、
ページ遷移の解説に戻るまでにかなり時間がかかるので割愛します。
※本記事前述の解説などの参考になる記事が複数存在しますので、ご覧ください。
*/

import 'package:scoped_model/scoped_model.dart';
// scoped_modelのパッケージをインポートします。

DemoModel demoModel = DemoModel();
//modelを生成しておきます。

void main() {

  runApp(MaterialApp(
    title: 'Demo',
    home: ScopedModel<DemoModel>(
        model: demoModel,
        child: new FirstScreen()
    )
  ));
}

/*
route指示部分がごっそり無くなっています。書いてみるとエラーになりました。
遷移時に各ボタンなどの実行時のコードに
Scoped Modelの子孫のクラスとなる次のページのクラス生成を指示することになります。
*/

//最初の画面(FirstScreen)
class FirstScreen extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      appBar: AppBar(
        title: Text('Demo'),
      ),
      body: Center(

      // 中略
      child: RaisedButton(
          padding: EdgeInsets.all(12.0),
          shape: StadiumBorder(),
          child: Text(
            "次のページへ",
            style: TextStyle(fontSize: 20.0, color: Colors.white),
          ),
          color: Colors.green,
          onPressed: () {

            

            Navigator.push(
              context,
              new MaterialPageRoute<Null>(
                settings: const RouteSettings(name: "/second"),
                builder: (BuildContext context) {
                    return MaterialApp(
                      home: ScopedModel<DemoModel>(
                        model: quizBrainModel,
                        child: new SecondScreen(),
                      ),
                    );
                  }
              ),
            );

            /*
            ↑ScopedModelを使わない場合、
            Navigator.pushNamed(context, "/second");となっていた部分です。
            */

          },
        ),

//次の画面(SecondScreen)
class SecondScreen extends StatelessWidget {

  SecondScreen();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      appBar: AppBar(
        title: Text("Second Page"),
      ),
      body: 
      
      //中略
      
      new ScopedModelDescendant<DemoModel>(
         builder: (context, child, model) =>
         new Row( children: model.getSomeList())
     )

     /*
     ↑このページは、Scoped Model子孫クラスなので
     new ScopedModelDescendant<Model名称>で
     メソッドや変数が呼び出せます。
     例としてmodelで指定しておいた、
     特定のListを呼び出すメソッドを書いています。
     */

参考になればと思います。他にも書き方があるかもしれません。ご指摘などあればコメントいただければと思います。

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?