2

所以我有一个 InheritedWidget 持有一个令牌。

class TokenHolder extends InheritedWidget {
  final String token;

  const TokenHolder({@required this.token, @required Widget child})
      : assert(child != null),
        super(child: child);

  @override
  bool updateShouldNotify(TokenHolder oldWidget) => oldWidget.token != token;

  static TokenHolder of(BuildContext context) {
    return context.dependOnInheritedWidgetOfExactType<TokenHolder>();
  }
}

然后在我的应用程序的某个高处,我用它来显示MyScreen

...
builder: (context) {
  ...
  return TokenHolder(
     token: token,
     child: MyScreen(),
  );
}

MyScreen按预期工作。它可以正确获取TokenHolder的令牌。

class MyScreen extends StatefulWidget {
  @override
  _MYyScreenState createState() => _MYyScreenState ();
}

class _MYyScreenState extends State<MyScreen > {
  @override
  Widget build(BuildContext context) {
    String token = TokenHolder.of(context).token; // This works

    return RaisedButton(
      onPressed: () {
        Navigator.push(context, builder: (context) => PushedScreen());
      },
      child: Text(token) // This works
    );
  }
}

但是,PushedScreennull我们调用TokenHolder.of(context). 为什么是这样?为什么找不到 TokenHolder?

class PushedScreen extends StatefulWidget {
  @override
  _PushedScreenState createState() => _PushedScreenState ();
}

class _PushedScreenState extends State<PushedScreen > {
  @override
  Widget build(BuildContext context) {
    String token = TokenHolder.of(context).token; // DOES NOT WORK -> null.token

    return Text(token);
  }
}
4

1 回答 1

0

而不是使用“TokenHolder.of(context).token”访问令牌,您可以在推送路由时token传递。argument(我不知道是否需要使用pushNamed,但这就是我使用的)

Navigator.pushNamed(
    context,
    '/pushedScreen', 
    arguments: token
);

然后token在 PushedScreen 中使用:

MaterialApp(
    onGenerateRoute: (settings) { 
        //only needed if their are multiple screens
        if (settings.name == '/pushedScreen') {
            String token = settings.arguments;
        } 
    }
    
)

您也可以尝试(在 pushScreen 内)

@override
Widget build(BuildContext context) {
    String token = ModalRoute.of(context).settings.arguments;
}

要使用 pushNamed:

MaterialApp(
    ...
    initialRoute: '/',
    routes {
        '/': (context) => ARoute(),
        '/pushedScreen': (context) => PushedScreen(),
    }
)
于 2020-07-31T07:59:46.063 回答