簡體   English   中英

如何在 Flutter 的小部件樹中將新 MaterialPageRoute 作為子項打開

[英]How to open new MaterialPageRoute as a child in widget tree in Flutter

在下面的示例中,當我推送新的 MaterialPageRoute 時,它與 Flutter 小部件樹中的 Home 小部件在同一級別上創建。 我想將它作為小部件 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"),
    ));
  }
}

這是小部件樹的樣子

在此處輸入圖像描述

我想實現這一點,因為我想在 Home 小部件中初始化 ScopedModel 並讓它在我創建的每個新 MaterialPageRoute 中都可用。

我使用嵌套導航器解決了我的問題。

這是示例:

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"),
      ),
    ));
  }
}

樹長這樣

在此處輸入圖像描述

並允許將數據從家庭傳遞給每個孩子。

如果您有任何更簡單的解決方案,請隨時發表評論或發布答案。

Navigator.of(context).push()將用新屏幕替換您的Home屏幕(同時將Home屏幕保留在 memory 中,以便您可以 go 回到它)。 它們在小部件樹中處於同一級別,我認為嵌套它們的唯一方法是使用嵌套的Navigators

但是,考慮到您想要實現的目標:為什么不將 ScopedModel 向上初始化一級並在小部件樹的根部提供呢? 這樣您就可以在Home屏幕和Child屏幕中訪問您的 model。

下面是如何做到這一點,我添加了一個簡單的 ScopedModel 並且能夠在Child屏幕中訪問它的text屬性。

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 class:

import 'package:scoped_model/scoped_model.dart';

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM