在切换到其他窗口小部件组后,保存JSON数据的变量将更改为null
我在这个问题上,我有两个步骤的形式。我加载了一个本地JSON文件,启动状态以在下拉小部件的第二步中使用。但是,当我单击continue按钮并切换到第二种形式时,变量变为null,导致出现错误“方法'map'在null上被调用”。我已经尝试在continueButton小部件的onPressed函数中加载数据,并尝试在创建第二种形式的小部件时再次加载数据。但是我总是得到这样一个错误,map函数被调用为null。请帮忙在切换到其他窗口小部件组后,保存JSON数据的变量将更改为null,json,flutter,Json,Flutter,我在这个问题上,我有两个步骤的形式。我加载了一个本地JSON文件,启动状态以在下拉小部件的第二步中使用。但是,当我单击continue按钮并切换到第二种形式时,变量变为null,导致出现错误“方法'map'在null上被调用”。我已经尝试在continueButton小部件的onPressed函数中加载数据,并尝试在创建第二种形式的小部件时再次加载数据。但是我总是得到这样一个错误,map函数被调用为null。请帮忙 import 'dart:ui'; import 'package:flutt
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:flutter_signin_button/flutter_signin_button.dart';
import 'package:ofepaw/services/auth.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'dart:async' show Future;
import 'package:flutter/services.dart' show rootBundle;
class RegisterPage extends StatefulWidget {
final Function toggleView;
RegisterPage({this.toggleView});
@override
State createState() => RegisterPageState();
}
class RegisterPageState extends State<RegisterPage> {
final AuthService _auth = AuthService();
// store the step we are in
int step = 1;
// Text Field
String emailOrPhone = "";
String pass = "";
String verifyPass = "";
String firstName = "";
String lastName = "";
String department = "";
String arrondissement = "";
String commune = "";
// variable for errors
String error = "";
// array containing the forms
var form1;
var form2;
// Controllers for the Textfields
final _emailOrPhoneController = TextEditingController();
final _passwordController = TextEditingController();
final _verifyPassController = TextEditingController();
final _firstNameController = TextEditingController();
final _lastNameController = TextEditingController();
//final _departmentController = TextEditingController();
//load the geographic division of Haiti json file
var division;
// get the locations data
Future<void> loadDivision() async {
String jsonString = await rootBundle
.loadString('assets/haiti_administrative_district.json');
Map<String, dynamic> map = json.decode(jsonString);
List<dynamic> data = map["departments"];
setState(() {
division = data;
});
}
// function to register user in ofepaw database
Future registerUser(
String id, String fname, String lname, String department) async {
final String url = "url go here";
final response = await http.post(url, body: {
"id": id,
"fname": fname,
"lname": lname,
"department": department
});
if (response.statusCode == 201) {
print("This is the response from the server");
print(response.body);
print("Response passed");
} else {
print("Error occured");
}
print(" The response is : ");
print(response.body.toString());
}
//functions for switching forms
getForm(int form) {
if (form == 1) {
return form1;
} else if (form == 2) {
return form2;
}
}
@override
void initState() {
super.initState();
loadDivision();
print(division);
form1 = <Widget>[
firstForm(),
Text("Or Sign Up with social media"),
SizedBox(
height: 20,
),
socialMediaButtons(),
SizedBox(
height: 50,
),
InkWell(
onTap: () {
widget.toggleView();
},
child: Text("Have an account? Login"))
];
form2 = <Widget>[
secondForm(),
InkWell(
//back button
onTap: () => setState(() => step = 1),
child: Text("Back"))
];
}
// dispose all controllers
// dispose of all TextEditingControllers
@override
void dispose() {
_emailOrPhoneController.dispose();
_passwordController.dispose();
_verifyPassController.dispose();
_firstNameController.dispose();
_lastNameController.dispose();
//_departmentController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Material(
child: Expanded(
child: Stack(
children: <Widget>[
// banner with picture
Positioned(
child: banner(),
),
// Login Elements Container
Positioned(
child: Container(
margin: EdgeInsets.only(top: 300.0),
decoration: BoxDecoration(
color: Colors.white,
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.2),
spreadRadius: 5,
blurRadius: 20,
offset: Offset(0, 0))
],
borderRadius: BorderRadius.only(
topRight: Radius.circular(50),
topLeft: Radius.circular(50))),
child: Center(
child: Column(
children: getForm(step),
),
),
),
)
],
),
),
);
}
Widget banner() {
return Container(
height: 350,
decoration: BoxDecoration(color: Colors.white),
child: Center(
child: Image.network(
"https://image.freepik.com/free-vector/man-using-his-phone-instead-working_23-2148501890.jpg"),
),
);
}
Widget emailField() {
return TextFormField(
controller: _emailOrPhoneController,
decoration: InputDecoration(
contentPadding: EdgeInsets.only(top: 10, left: 20, right: 20),
border: InputBorder.none,
hintText: "Email or Phone Number",
hintStyle: TextStyle(color: Colors.grey[400], fontSize: 15)),
onChanged: (val) {
setState(() => emailOrPhone = val);
},
);
}
Widget firstNameField() {
return TextFormField(
controller: _firstNameController,
decoration: InputDecoration(
contentPadding: EdgeInsets.only(top: 10, left: 20, right: 20),
border: InputBorder.none,
hintText: "First Name",
hintStyle: TextStyle(color: Colors.grey[400], fontSize: 15)),
onChanged: (val) {
setState(() => firstName = val);
},
);
}
Widget lastNameField() {
return TextFormField(
controller: _lastNameController,
decoration: InputDecoration(
contentPadding: EdgeInsets.only(top: 10, left: 20, right: 20),
border: InputBorder.none,
hintText: "Last Name",
hintStyle: TextStyle(color: Colors.grey[400], fontSize: 15)),
onChanged: (val) {
setState(() => lastName = val);
},
);
}
Widget departmentField() {
return DropdownButtonFormField(
items: division.map<DropdownMenuItem<String>>((value) {
return DropdownMenuItem<String>(
value: value["name"],
child: Text(value["name"]),
);
}).toList(),
hint: Text("Choose the department"),
onChanged: (value) {
setState(() {});
},
decoration: InputDecoration(
contentPadding: EdgeInsets.only(top: 10, left: 20, right: 20),
border: InputBorder.none,
hintStyle: TextStyle(color: Colors.grey[400], fontSize: 15)),
);
}
Widget arrondissementField() {
return DropdownButtonFormField(
items: [
DropdownMenuItem(
child: Text("Delmas"),
value: 1,
),
DropdownMenuItem(
child: Text("Petion-Ville"),
value: 2,
)
],
hint: Text("Choose the department"),
onChanged: (int value) {
setState(() {});
},
decoration: InputDecoration(
contentPadding: EdgeInsets.only(top: 10, left: 20, right: 20),
border: InputBorder.none,
hintStyle: TextStyle(color: Colors.grey[400], fontSize: 15)));
}
Widget communeField() {
return DropdownButtonFormField(
items: [
DropdownMenuItem(
child: Text("Delmas"),
value: 1,
),
DropdownMenuItem(
child: Text("Petion-Ville"),
value: 2,
)
],
hint: Text("Choose the department"),
onChanged: (int value) {
setState(() {});
},
decoration: InputDecoration(
contentPadding: EdgeInsets.only(top: 10, left: 20, right: 20),
border: InputBorder.none,
hintStyle: TextStyle(color: Colors.grey[400], fontSize: 15)));
}
Widget passwordField() {
return TextFormField(
controller: _passwordController,
decoration: InputDecoration(
contentPadding: EdgeInsets.only(bottom: 5, left: 20, right: 20),
border: InputBorder.none,
hintText: "Password",
hintStyle: TextStyle(color: Colors.grey[400], fontSize: 15)),
onChanged: (val) {
setState(() => pass = val);
});
}
Widget verifyPasswordField() {
return TextFormField(
controller: _verifyPassController,
decoration: InputDecoration(
contentPadding: EdgeInsets.only(bottom: 5, left: 20, right: 20),
border: InputBorder.none,
hintText: "Reenter Password",
hintStyle: TextStyle(color: Colors.grey[400], fontSize: 15)),
onChanged: (val) {
setState(() => verifyPass = val);
});
}
Widget socialMediaButtons() {
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
SignInButton(Buttons.Facebook,
mini: true, onPressed: () => print("Facebook Sign in ...")),
SignInButton(Buttons.Google,
//mini: true,
onPressed: () => print("Google Sign in ..."))
],
);
}
Widget continueButton() {
return ButtonTheme(
minWidth: 185.0,
height: 48.0,
child: RaisedButton(
color: Colors.black,
textColor: Colors.white,
child: Text("continue"),
shape:
RoundedRectangleBorder(borderRadius: BorderRadius.circular(50.0)),
onPressed: () {
print(division);
setState(() {
step = 2;
});
},
));
}
Widget signUpButton() {
return ButtonTheme(
minWidth: 185.0,
height: 48.0,
child: RaisedButton(
color: Colors.black,
textColor: Colors.white,
child: Text("Sign Up"),
shape:
RoundedRectangleBorder(borderRadius: BorderRadius.circular(50.0)),
onPressed: () async {
dynamic result =
await _auth.registerWithEmailAndPassword(emailOrPhone, pass);
if (result == null) {
setState(() => error = "Email or Password incorrect");
} else {
// Register user ID in the server database
registerUser(result.user.uid, firstName, lastName, department);
}
},
));
}
Widget emailPassField() {
return Container(
// Form input field
margin: EdgeInsets.only(top: 40.0),
width: 320.0,
height: 180.0,
decoration: BoxDecoration(
color: Colors.white,
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.2),
spreadRadius: 0.2,
blurRadius: 5,
offset: Offset(0, 0))
],
borderRadius: BorderRadius.circular(20)),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
emailField(),
Divider(),
passwordField(),
Divider(),
verifyPasswordField()
],
),
);
}
Widget personalInfoField() {
return Container(
// Form input field
margin: EdgeInsets.only(top: 40.0),
width: 320.0,
height: 310.0,
decoration: BoxDecoration(
color: Colors.white,
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.2),
spreadRadius: 0.2,
blurRadius: 5,
offset: Offset(0, 0))
],
borderRadius: BorderRadius.circular(20)),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
firstNameField(),
Divider(),
lastNameField(),
Divider(),
departmentField(),
Divider(),
arrondissementField(),
Divider(),
communeField()
],
),
);
}
Widget firstForm() {
return Column(
children: <Widget>[
emailPassField(),
SizedBox(
height: 50,
),
continueButton(),
SizedBox(
height: 50,
),
],
);
}
Widget secondForm() {
return Column(
children: <Widget>[
personalInfoField(),
SizedBox(
height: 40,
),
signUpButton(),
SizedBox(
height: 40,
),
],
);
}
}
导入“dart:ui”;
进口“包装:颤振/材料.省道”;
进口“包装:颤振符号按钮/颤振符号按钮.省道”;
导入“包:ofepaw/services/auth.dart”;
将“package:http/http.dart”导入为http;
导入“dart:convert”;
导入“dart:async”显示未来;
导入“包:flatter/services.dart”显示根包;
类RegisterPage扩展StatefulWidget{
最终功能切换视图;
注册表页({this.toggleView});
@凌驾
State createState()=>RegisterPageState();
}
类RegisterPageState扩展状态{
最终AuthService_auth=AuthService();
//存储我们所处的步骤
int步长=1;
//文本字段
字符串emailOrPhone=“”;
字符串pass=“”;
字符串verifyPass=“”;
字符串firstName=“”;
字符串lastName=“”;
字符串部门=”;
字符串区域=”;
字符串commune=“”;
//错误变量
字符串错误=”;
//包含表单的数组
var form1;
var form2;
//文本字段的控制器
final _emailOrPhoneController=TextEditingController();
final _passwordController=TextEditingController();
最终_verifyPassController=TextEditingController();
final _firstNameController=TextEditingController();
final _lastNameController=TextEditingController();
//最终_departmentController=TextEditingController();
//加载海地json文件的地理分区
var划分;
//获取位置数据
Future loadDivision()异步{
String jsonString=await rootBundle
.loadString('assets/haidi_administrative_district.json');
Map Map=json.decode(jsonString);
列表数据=地图[“部门”];
设置状态(){
分部=数据;
});
}
//在ofepaw数据库中注册用户的函数
未来登记员(
字符串id、字符串fname、字符串lname、字符串部门)异步{
最终字符串url=“url转到此处”;
最终响应=等待http.post(url,正文:{
“id”:id,
“fname”:fname,
“lname”:lname,
“部门”:部门
});
如果(response.statusCode==201){
打印(“这是来自服务器的响应”);
打印(响应.正文);
打印(“回复通过”);
}否则{
打印(“发生错误”);
}
打印(“回复为:”);
打印(response.body.toString());
}
//交换表格的功能
getForm(int-form){
如果(形式==1){
返回表格1;
}else if(形式==2){
返回表格2;
}
}
@凌驾
void initState(){
super.initState();
负荷分配();
印刷部;
表格1=[
firstForm(),
文本(“或注册社交媒体”),
大小盒子(
身高:20,
),
社会媒体(),
大小盒子(
身高:50,
),
墨水池(
onTap:(){
widget.toggleView();
},
子项:文本(“拥有帐户?登录”))
];
表格2=[
secondForm(),
墨水池(
//后退按钮
onTap:()=>设置状态(()=>步骤=1),
子项:文本(“返回”))
];
}
//处置所有控制器
//处置所有TextEditingController
@凌驾
无效处置(){
_emailOrPhoneController.dispose();
_passwordController.dispose();
_verifyPassController.dispose();
_dispose();
_dispose();
//_departmentController.dispose();
super.dispose();
}
@凌驾
小部件构建(构建上下文){
退货(
儿童:扩大(
子:堆栈(
儿童:[
//带图片的横幅
定位(
子:banner(),
),
//登录元素容器
定位(
子:容器(
边距:仅限边缘集(顶部:300.0),
装饰:盒子装饰(
颜色:颜色,白色,
boxShadow:[
箱形阴影(
颜色:颜色。灰色。不透明度(0.2),
扩展半径:5,
半径:20,
偏移量:偏移量(0,0))
],
borderRadius:仅限borderRadius(
右上角:半径。圆形(50),
左上角:半径。圆形(50)),
儿童:中心(
子:列(
子项:getForm(步骤),
),
),
),
)
],
),
),
);
}
Widget横幅(){
返回容器(
身高:350,
装饰:盒子装饰(颜色:彩色。白色),
儿童:中心(
孩子:Image.network(
"https://image.freepik.com/free-vector/man-using-his-phone-instead-working_23-2148501890.jpg"),
),
);
}
Widget emailField(){
返回TextFormField(
控制器:_emailOrPhoneController,
装饰:输入装饰(
contentPadding:仅限边集(顶部:10,左侧:20,右侧:20),
边框:InputBorder.none,
hintText:“电子邮件或电话号码”,
hintStyle:TextStyle(颜色:Colors.grey[400],字体大小:15)),
一旦更改:(val){
设置状态(()=>emailOrPhone=val);
},
);
}
Widget firstNameField(){
返回TextFormField(
Future<void> loadDivision() async {
String jsonString = await rootBundle
.loadString('assets/haiti_administrative_district.json');
Map<String, dynamic> map = json.decode(jsonString);
List<dynamic> data = map["departments"];
setState(() {
division = data;
});
}
List<Map> maps = json.decode(jsonString);
List data=new List();
maps.forEach((element)=>data.add(element['departments']));