Как открыть новый MaterialPageRoute как дочерний элемент в дереве виджетов во Flutter - PullRequest
1 голос
/ 20 апреля 2020

В приведенном ниже примере, когда я пу sh new MaterialPageRoute, он создается на том же уровне, что и виджет Home в дереве виджетов Flutter. Я бы хотел, чтобы он был дочерним для виджета Home, чтобы Home был родительским элементом для виджета Child.

Вот полный код:

import 'package:flutter/material.dart';

void main() {
  runApp(MaterialApp(
    home: Home(),
  ));
}

class Home extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        children: <Widget>[
          Center(
            child: Text("This is home"),
          ),
          RaisedButton(
            child: Text("Open child view"),
            onPressed: () {
              Navigator.of(context)
                  .push(MaterialPageRoute(builder: (context) => Child()));
            },
          )
        ],
      ),
    );
  }
}

class Child extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Container(
      child: Text("Child view"),
    ));
  }
}

Вот как выглядит дерево виджета. выглядит как

enter image description here

Я хочу добиться этого, потому что я хотел бы инициализировать ScopedModel в виджете Home и иметь его в каждом новом создаваемом MaterialPageRoute.

Ответы [ 2 ]

0 голосов
/ 24 апреля 2020

Я решил свою проблему, используя вложенный Навигатор.

Вот пример:

import 'package:flutter/material.dart';

void main() {
  runApp(MaterialApp(
    home: Home(),
  ));
}

var homeNavigatorKey = GlobalKey<NavigatorState>();

class Home extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Navigator(
        key: homeNavigatorKey,
        onGenerateRoute: (settings) {
          /*dirty code for illustration purposes only*/
          if (settings.name == '/child') {
            return MaterialPageRoute(builder: (context) => Child());
          } else {
            return MaterialPageRoute(
                builder: (context) => Column(
                      children: <Widget>[
                        Center(
                          child: Text("This is home"),
                        ),
                        RaisedButton(
                          child: Text("Open child view"),
                          onPressed: () {
                            homeNavigatorKey.currentState.pushNamed('/child');
                          },
                        )
                      ],
                    ));
          }
        },
      ),
    );
  }
}

class Child extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Container(
      child: RaisedButton(
        onPressed: () => Navigator.of(context).pop(),
        child: Text("Back to home"),
      ),
    ));
  }
}

Дерево выглядит так

enter image description here

и позволяет проходить данные из дома каждому ребенку.

Не стесняйтесь комментировать или публиковать ответы, если у вас есть более простое решение.

0 голосов
/ 20 апреля 2020

Navigator.of(context).push() заменит ваш Home экран новым (при сохранении в памяти экрана Home, чтобы вы могли go вернуться к нему). Они находятся на одном уровне в дереве виджетов, единственный способ их вложить - использовать вложенные Navigators Я думаю.

Но, учитывая, чего вы хотите достичь: почему бы не инициализировать ScopedModel на один уровень выше и предоставить в root вашего дерева виджетов? Таким образом, вы можете получить доступ к своей модели как на экране Home, так и на экране Child.

Ниже описано, как вы можете это сделать, я добавил простую ScopedModel и могу получить к ней доступ text свойство внутри экрана Child.

import 'package:flutter/material.dart';
import 'package:scoped_model/scoped_model.dart';
import 'package:tryout/model.dart';

void main() {
  runApp(
    ScopedModel<TestModel>(
      model: TestModel(),
      child: MaterialApp(
        home: Home(),
      ),
    )
  );
}

class Home extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        children: <Widget>[
          Center(
            child: Text("This is home"),
          ),
          RaisedButton(
            child: Text("Open child view"),
            onPressed: () {
              Navigator.of(context)
                  .push(MaterialPageRoute(builder: (context) => Child()));
            },
          )
        ],
      ),
    );
  }
}

class Child extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Container(
      child: Text("${ScopedModel.of<TestModel>(context).text}"),
    ));
  }
}

А вот класс TestModel:

import 'package:scoped_model/scoped_model.dart';

class TestModel extends Model {
  String _text = "Test to see if this works!";
  String get text => _text;
}
...