Flutter 更新继承的小部件的变量值

Flutter 更新继承的小部件的变量值,flutter,authentication,jwt,inherited-widget,Flutter,Authentication,Jwt,Inherited Widget,这是我正在制作的应用程序的登录代码。我想更新发布请求后获得的parent_inherit(继承的小部件)中的令牌。但如果没有构建方法或parent_inherit小部件,我无法理解如何更新继承的小部件显式变量的值。我想更改继承的小部件(parent_inherit)中的令牌值 Future attemptLogIn(字符串用户名、字符串密码、BuildContext上下文)异步{ 字符串parentToken=parent_inherit.of(上下文); SharedReferences pr

这是我正在制作的应用程序的登录代码。我想更新发布请求后获得的parent_inherit(继承的小部件)中的令牌。但如果没有构建方法或parent_inherit小部件,我无法理解如何更新继承的小部件显式变量的值。我想更改继承的小部件(parent_inherit)中的令牌值

Future attemptLogIn(字符串用户名、字符串密码、BuildContext上下文)异步{
字符串parentToken=parent_inherit.of(上下文);
SharedReferences prefs=等待SharedReferences.getInstance();
打印(“$username$password”);
final http.Response res=wait http.post(
“……路线……”,
标题:{
“内容类型”:“应用程序/json;字符集=UTF-8”,
},
正文:JSONECODE({
“电子邮件”:用户名,
“密码”:密码
}),
);
如果(res.statusCode==200){
首选设置字符串(“jwt”,res.body);
var value=prefs.getString('jwt');
Map valueMap=jsonDecode(值);
TokenClass token=TokenClass.fromJson(valueMap);
parentToken=token.token;//我尝试过类似的方法,但似乎不起作用
Navigator.of(context.pushNamed('/home');
}
否则{
返回_showmydialogin(上下文,res.statusCode);
}
}
另外,在上面的文件中,当我在上面声明parentToken并停止使用它时,它仍然显示上面声明的parentToken未被使用。当我将鼠标悬停在上面时,它也会显示警告。为什么

父级_.dart

class parent_inherit extends InheritedWidget {
  final String token;

  const parent_inherit({
    Key key,
    @required this.token,
    Widget child})
      :super(key:key,child: child);

  @override
  bool updateShouldNotify(parent_inherit oldWidget) =>true;

  static String of(BuildContext context) => context.dependOnInheritedWidgetOfExactType<parent_inherit>().token;
}

class parent\u inherit扩展了InheritedWidget{
最终字符串标记;
const parent_inherit({
关键点,
@需要这个.token,
窗口小部件(子对象})
:super(key:key,child:child);
@凌驾
bool updateShouldNotify(parent_inherit oldWidget)=>true;
(BuildContext context)=>context.dependOnInheritedWidgetOfExactType()的静态字符串。令牌;
}
飞镖

class TokenClass{
  final String token;

  TokenClass(this.token);

  TokenClass.fromJson(Map<String,dynamic> json)
  : token=json['token'];

}
class标记类{
最终字符串标记;
TokenClass(this.token);
TokenClass.fromJson(映射json)
:token=json['token'];
}
My main function-在main function中,令牌值存在问题,它无法在继承的小部件内部和外部正确更新和获取值。有时它也使用以前的令牌值

主飞镖

bool checkingKey;
String tokenName;
TokenClass token;

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  Paint.enableDithering = true;
  const defaultJson = '{}';
  var prefs = await SharedPreferences.getInstance();
  checkingKey = prefs.containsKey("jwt");
  

  tokenName=prefs.getString('jwt');
  
  Map<String, dynamic> valueMap = jsonDecode(tokenName??defaultJson);
  token=TokenClass.fromJson(valueMap);
 
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return parent_inherit(
      token: checkingKey==false?'':token.token,
      child: MaterialApp(
        home: AnnotatedRegion<SystemUiOverlayStyle>(
          value: SystemUiOverlayStyle(
            statusBarColor: Colors.transparent,
          ),
          child: Scaffold(
            resizeToAvoidBottomInset: false,
            body: Container(
              color: Color(0xffccffcc),
              child: !checkingKey ? LoginPage() : mainPage(),
            ),
          ),
        ),
        routes: <String,WidgetBuilder>{
          '/home':(BuildContext context) => mainPage(),
          '/login':(BuildContext context) => LoginPage(),
        },
      ),
    );
  }
}
bool检查键;
字符串标记名;
令牌类令牌;
void main()异步{
WidgetsFlutterBinding.ensureInitialized();
Paint.Enable抖动=真;
const defaultJson='{}';
var prefs=await SharedPreferences.getInstance();
checkingKey=prefs.containsKey(“jwt”);
tokenName=prefs.getString('jwt');
Map valueMap=jsonDecode(标记名??默认JSON);
token=TokenClass.fromJson(valueMap);
runApp(MyApp());
}
类MyApp扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
返回父对象\u继承(
token:checkingKey==false?“”:token.token,
孩子:MaterialApp(
家:德雷吉翁(
值:SystemUIOverlyStyle(
statusBarColor:Colors.transparent,
),
孩子:脚手架(
resizeToAvoidBottomInset:false,
主体:容器(
颜色:颜色(0xffccffcc),
子项:!checkingKey?LoginPage():mainPage(),
),
),
),
路线:{
“/home”:(BuildContext上下文)=>mainPage(),
“/login”:(BuildContext上下文)=>LoginPage(),
},
),
);
}
}

也欢迎其他建议…

更新
继承小部件的一种方法是使用
通知

首先,我们有通知类:

类登录通知扩展通知{
最终令牌类令牌;
登录通知(this.token);
}
然后,我们用通知侦听器包装
parent\u inherit

类MyApp扩展StatefulWidget{
@凌驾
_MyAppState createState()=>\u MyAppState();
}
类MyAppState扩展了状态{
@凌驾
小部件构建(构建上下文){
返回通知侦听器(
onNotification:(登录通知){
设置状态(){
token=loginNotification.token;
checkingKey=true;
});
返回true;
},
子:父\继承(
令牌:checkingKey?令牌。令牌:“”,
孩子:MaterialApp(
家:德雷吉翁(
值:SystemUIOverlyStyle(
statusBarColor:Colors.transparent,
),
孩子:脚手架(
resizeToAvoidBottomInset:false,
主体:容器(
颜色:颜色(0xffccffcc),
子项:checkingKey?主页():登录页(),
),
),
),
路线:{
“/home”:(BuildContext上下文)=>MainPage(),
“/login”:(BuildContext上下文)=>LoginPage(),
},
),
),
);
}
}
attemptLogIn
方法中,您只需要发送一个通知:

未来登录(
字符串用户名、字符串密码、BuildContext(上下文)异步{
SharedReferences prefs=等待SharedReferences.getInstance();
如果(kDebugMode)打印(“$username$password”);
final http.Response res=wait http.post(
“……路线……”,
标题:{
“内容类型”:“应用程序/json;字符集=UTF-8”,
},
正文:jsonEncode({“email”:username,“password”:password}),
);
如果(res.statusCode==200){
//首先检查登录是否有效
//...
首选设置字符串(“jwt”,res.body);
var value=prefs.getString('jwt');
Map valueMap=jsonDecode(值);
TokenClass token=TokenClass.fromJson(valueMap);
//向LoginNotification侦听器发送通知
登录通知(令牌)。发送(上下文);
Navigator.of(context.pushNamed('/home');
}否则{
return\u showMyDialoglogin(上下文,res.stat
bool checkingKey;
String tokenName;
TokenClass token;

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  Paint.enableDithering = true;
  const defaultJson = '{}';
  var prefs = await SharedPreferences.getInstance();
  checkingKey = prefs.containsKey("jwt");
  

  tokenName=prefs.getString('jwt');
  
  Map<String, dynamic> valueMap = jsonDecode(tokenName??defaultJson);
  token=TokenClass.fromJson(valueMap);
 
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return parent_inherit(
      token: checkingKey==false?'':token.token,
      child: MaterialApp(
        home: AnnotatedRegion<SystemUiOverlayStyle>(
          value: SystemUiOverlayStyle(
            statusBarColor: Colors.transparent,
          ),
          child: Scaffold(
            resizeToAvoidBottomInset: false,
            body: Container(
              color: Color(0xffccffcc),
              child: !checkingKey ? LoginPage() : mainPage(),
            ),
          ),
        ),
        routes: <String,WidgetBuilder>{
          '/home':(BuildContext context) => mainPage(),
          '/login':(BuildContext context) => LoginPage(),
        },
      ),
    );
  }
}