如何在 flutter 的应用程序的每个屏幕上显示名称和电子邮件
How to display name and email on every screen of app in flutter
我在应用程序主屏幕的抽屉中显示名称和电子邮件(从 MongoDB 获取),现在我想在我的应用程序的每个屏幕上显示该抽屉,当我点击任何页面时显示在抽屉上,那么该页面抽屉应该类似于主抽屉。
我也在传递参数,但它给我这个错误
错误:
A non-null String must be provided to a Text widget.
'package:flutter/src/widgets/text.dart':
Failed assertion: line 378 pos 10: 'data != null'
这是我的登录代码,当用户输入正确的凭据时,它将被重定向到主屏幕。
// this save() i am calling on login button
Future save() async {
Dio dio=new Dio();
var data={
'username': user.username,
'password': user.password
};
await dio
.post(localhostUrl,data: json.encode(data))
.then((onResponse){
print(onResponse.data['User']);
//var name=print(onResponse.data['User']['username']);
print(onResponse.data['User']['designation']);
print(onResponse.data['User']['TimeIn']);
//**here i am passing values to EmployeeNavigation which is my home**
Navigator.push(
context, new MaterialPageRoute(builder: (context) => EmployeeNavigation(
name:onResponse.data['User']['username'],
email:onResponse.data['User']['email'],
designation:onResponse.data['User']['designation'],
date:onResponse.data['User']['Date'],
timeIn:onResponse.data['User']['TimeIn'],
timeOut:onResponse.data['User']['TimeOut'],
)));
}).catchError((onerror){
print(onerror.toString());
showAlertDialog(context);
});
}
这是我的 EmployeeNavigation 代码
class EmployeeNavigation extends StatefulWidget {
var name;
var email;
var designation;
var date;
var timeIn;
var timeOut;
EmployeeNavigation({this.name, this.email, this.designation, this.date, this.timeIn, this.timeOut, } );
@override
State<StatefulWidget> createState() {
return EmployeeNavigationState(this.name,this.email,this.designation,this.date,this.timeIn,this.timeOut);
}
}
class EmployeeNavigationState extends State<EmployeeNavigation> {
var name;
var email;
var designation;
var date;
EmployeeNavigationState(this.name,this.email, this.designation,this.date,this.timeIn, this.timeOut );
bool valuefirst = false;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Image.asset("assets/image/company_logo.png",height: 140,width: 280,
),
backgroundColor: Colors.white,
iconTheme: IconThemeData(color: Colors.blue,size: 20),
//leading: new Icon(Icons.menu,color: Colors.blue,),
actions: <Widget>[
IconButton(
icon: Icon(
Icons.notifications,
color: Colors.blue,
size:26
),
)
],
),
drawer:new Drawer(
child: new ListView(
padding: const EdgeInsets.all(0.0),
children: <Widget>[
new UserAccountsDrawerHeader(
accountName: new Text(name,style: TextStyle(fontSize: 14)), //here i am using name parameter
accountEmail: new Text(email,style: TextStyle(fontSize: 14),), // here i am using email parameter
currentAccountPicture: new CircleAvatar(
backgroundColor:
Theme.of(context).platform == TargetPlatform.android
? Colors.white
: Colors.blue,
child: Text(
name[0][0],
style: TextStyle(fontSize: 40.0),
),
),
),
new ListTile(
title: new Text('Request for leave'),
leading: Icon(Icons.request_page),
onTap: (){
Navigator.pop(context);
Navigator.push(context, new MaterialPageRoute(
builder: (context)=>new RequestForLeave(name,email) //here i am passing name and email parameters
)
);
},
),
new ExpansionTile(
title: new Text('History'),
children: <Widget>[
ListTile(
title:new Text("My Attendance"),
leading: Icon(Icons.assessment_outlined ),
onTap: (){
Navigator.pop(context);
Navigator.push(context, new MaterialPageRoute(
builder: (context)=>new MyAttendance()
)
);
},
),
ListTile(
title:new Text("Leaves"),
leading: Icon(Icons.assessment_outlined ),
onTap: (){
Navigator.pop(context);
Navigator.push(context, new MaterialPageRoute(
builder: (context)=>new Leaves()
)
);
},
)
// Text("My Attendance"),
// Text("Leaves"),
],
leading: Icon(Icons.history,
),
)],
),
),
);
}
}
这是我传递参数的 RequestforLeave 代码
import 'package:attendance_system_app/Admin_Navigation/AdminNavigation.dart';
import 'package:attendance_system_app/Employee_Navigation/EmployeeNavigation.dart';
import 'package:attendance_system_app/Leaves/Leaves.dart';
import 'package:attendance_system_app/My_Attendance/MyAttendance.dart';
import 'package:flutter/material.dart';
class RequestForLeave extends StatefulWidget {
var name;
var email;
RequestForLeave(name, email);
@override
State<StatefulWidget> createState(){
return _RequestForLeaveState(this.name,this.email);
}
}
class _RequestForLeaveState extends State<RequestForLeave> {
var name;
var email;
_RequestForLeaveState(this.name,this.email);
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: AppBar(
title: Image.asset("assets/image/company_logo.png",height: 140,width: 280,
),
//automaticallyImplyLeading: false,
backgroundColor: Colors.white,
iconTheme: IconThemeData(color: Colors.blue,size: 20),
//leading: new Icon(Icons.menu,color: Colors.blue,),
actions: <Widget>[
IconButton(
icon: Icon(
Icons.notifications,
color: Colors.blue,
size:26
),
onPressed: () {
// do something
},
)
],
),
drawer:new Drawer(
child: new ListView(
padding: const EdgeInsets.all(0.0),
children: <Widget>[
new UserAccountsDrawerHeader(
accountName: new Text(name,style: TextStyle(fontSize: 14)),
accountEmail: new Text(email,style: TextStyle(fontSize: 14),),
currentAccountPicture: new CircleAvatar(
backgroundColor:
Theme.of(context).platform == TargetPlatform.android
? Colors.white
: Colors.blue,
child: Text(
name[0][0],
style: TextStyle(fontSize: 40.0),
),
),
),
new ListTile(
title: new Text('Request for leave'),
leading: Icon(Icons.request_page),
onTap: (){
Navigator.pop(context);
Navigator.push(context, new MaterialPageRoute(
builder: (context)=>new RequestForLeave(name,email)
)
);
},
),
new ExpansionTile(
title: new Text('History'),
children: <Widget>[
ListTile(
title:new Text("My Attendance"),
leading: Icon(Icons.assessment_outlined ),
onTap: (){
Navigator.pop(context);
Navigator.push(context, new MaterialPageRoute(
builder: (context)=>new MyAttendance()
)
);
},
),
ListTile(
title:new Text("Leaves"),
leading: Icon(Icons.assessment_outlined ),
onTap: (){
Navigator.pop(context);
Navigator.push(context, new MaterialPageRoute(
builder: (context)=>new Leaves()
)
);
},
)
// Text("My Attendance"),
// Text("Leaves"),
],
leading: Icon(Icons.history,
),
)],
),
),
body:Center(
child: Text(
"Request for leave",
style: TextStyle(fontSize: 28),
)),
);
}
}
我在 EmployeeNavigation 抽屉上得到了正确的值,但是当我点击 Request for leave 时出现错误
这里是错误输出
[![在此处输入图片描述][1]][1]
这是我的主屏幕抽屉样子
[![在此处输入图片描述][2]][2]
请帮我解决这个问题,我在我的应用程序的每个屏幕上都显示相同的抽屉。
--------------------更新了-------------------- ----------
class EmployeeNavigation extends StatefulWidget {
var name;
var email;
var designation;
var date;
var timeIn;
var timeOut;
EmployeeNavigation({this.name, this.email, this.designation, this.date, this.timeIn, this.timeOut, } );
@override
State<StatefulWidget> createState() {
return EmployeeNavigationState(this.name,this.email,this.designation,this.date,this.timeIn,this.timeOut);
}
}
class EmployeeNavigationState extends State<EmployeeNavigation> {
// here is create Drawer widget
Widget DrawerCode(){
return Drawer(
child: new ListView(
padding: const EdgeInsets.all(0.0),
children: <Widget>[
new UserAccountsDrawerHeader(
accountName: new Text(name,style: TextStyle(fontSize: 14)),
accountEmail: new Text(email,style: TextStyle(fontSize: 14),),
currentAccountPicture: new CircleAvatar(
backgroundColor:
Theme.of(context).platform == TargetPlatform.android
? Colors.white
: Colors.blue,
child: Text(
name[0][0],
style: TextStyle(fontSize: 40.0),
),
),
),
new ListTile(
title: new Text('Request for leave'),
leading: Icon(Icons.request_page),
onTap: (){
Navigator.pop(context);
Navigator.push(context, new MaterialPageRoute(
builder: (context)=>new RequestForLeave()
)
);
},
),
new ExpansionTile(
title: new Text('History'),
children: <Widget>[
ListTile(
title:new Text("My Attendance"),
leading: Icon(Icons.assessment_outlined ),
onTap: (){
Navigator.pop(context);
Navigator.push(context, new MaterialPageRoute(
builder: (context)=>new MyAttendance()
)
);
},
),
ListTile(
title:new Text("Leaves"),
leading: Icon(Icons.assessment_outlined ),
onTap: (){
Navigator.pop(context);
Navigator.push(context, new MaterialPageRoute(
builder: (context)=>new Leaves()
)
);
},
)
// Text("My Attendance"),
// Text("Leaves"),
],
leading: Icon(Icons.history,
),
)],
),
);
}
var name;
var email;
var designation;
var date;
EmployeeNavigationState(this.name,this.email, this.designation,this.date,this.timeIn, this.timeOut );
bool valuefirst = false;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Image.asset("assets/image/company_logo.png",height: 140,width: 280,
),
backgroundColor: Colors.white,
iconTheme: IconThemeData(color: Colors.blue,size: 20),
//leading: new Icon(Icons.menu,color: Colors.blue,),
actions: <Widget>[
IconButton(
icon: Icon(
Icons.notifications,
color: Colors.blue,
size:26
),
)
],
),
drawer:DrawerCode(),
);
}
}
[1]: https://i.stack.imgur.com/aAqI2.png
[2]: https://i.stack.imgur.com/Ivpbu.png
显示的错误与抽屉无关,它与您将 NULL
传递到需要有效字符串的 Text
小部件有关。
String variable = null;
Text(variable) <-- error
String variable = '';
Text(variable) <-- fine!
对我来说,您采用的方法似乎不正确。如果你有 100 个屏幕并且你想在每个屏幕中显示抽屉,你将有 100 个抽屉。如果您喜欢这种方法,您应该创建一个 Drawer Widget 文件以避免重复。
我可以建议您采用不同的方法吗?
假设您有以下文件夹结构:
Home Screen
- Dashboard Screen
- Customers Screen
- Items Screen
只有Home Screen
有抽屉。 Home Screen
将在其内部加载所有子屏幕(仪表板、客户和项目)。
class _HomeState extends State<Home>
{
String appTitle = 'Dashboard';
Widget appBody = DashboardScreen(); // By default
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(
this.appTitle,
),
),
body: this.appBody,
drawer: YourDrawer()
);
}
}
现在你所需要的只是一个随时跳转到另一个子屏幕的功能:
void jumpToScreen(String appTitle, Widget appBody)
{
setState(()
{
this.appTitle = appTitle;
this.appBody = appBody;
});
}
您还可以应用一些逻辑来根据屏幕显示不同的应用程序操作按钮。
我在应用程序主屏幕的抽屉中显示名称和电子邮件(从 MongoDB 获取),现在我想在我的应用程序的每个屏幕上显示该抽屉,当我点击任何页面时显示在抽屉上,那么该页面抽屉应该类似于主抽屉。
我也在传递参数,但它给我这个错误
错误:
A non-null String must be provided to a Text widget.
'package:flutter/src/widgets/text.dart':
Failed assertion: line 378 pos 10: 'data != null'
这是我的登录代码,当用户输入正确的凭据时,它将被重定向到主屏幕。
// this save() i am calling on login button
Future save() async {
Dio dio=new Dio();
var data={
'username': user.username,
'password': user.password
};
await dio
.post(localhostUrl,data: json.encode(data))
.then((onResponse){
print(onResponse.data['User']);
//var name=print(onResponse.data['User']['username']);
print(onResponse.data['User']['designation']);
print(onResponse.data['User']['TimeIn']);
//**here i am passing values to EmployeeNavigation which is my home**
Navigator.push(
context, new MaterialPageRoute(builder: (context) => EmployeeNavigation(
name:onResponse.data['User']['username'],
email:onResponse.data['User']['email'],
designation:onResponse.data['User']['designation'],
date:onResponse.data['User']['Date'],
timeIn:onResponse.data['User']['TimeIn'],
timeOut:onResponse.data['User']['TimeOut'],
)));
}).catchError((onerror){
print(onerror.toString());
showAlertDialog(context);
});
}
这是我的 EmployeeNavigation 代码
class EmployeeNavigation extends StatefulWidget {
var name;
var email;
var designation;
var date;
var timeIn;
var timeOut;
EmployeeNavigation({this.name, this.email, this.designation, this.date, this.timeIn, this.timeOut, } );
@override
State<StatefulWidget> createState() {
return EmployeeNavigationState(this.name,this.email,this.designation,this.date,this.timeIn,this.timeOut);
}
}
class EmployeeNavigationState extends State<EmployeeNavigation> {
var name;
var email;
var designation;
var date;
EmployeeNavigationState(this.name,this.email, this.designation,this.date,this.timeIn, this.timeOut );
bool valuefirst = false;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Image.asset("assets/image/company_logo.png",height: 140,width: 280,
),
backgroundColor: Colors.white,
iconTheme: IconThemeData(color: Colors.blue,size: 20),
//leading: new Icon(Icons.menu,color: Colors.blue,),
actions: <Widget>[
IconButton(
icon: Icon(
Icons.notifications,
color: Colors.blue,
size:26
),
)
],
),
drawer:new Drawer(
child: new ListView(
padding: const EdgeInsets.all(0.0),
children: <Widget>[
new UserAccountsDrawerHeader(
accountName: new Text(name,style: TextStyle(fontSize: 14)), //here i am using name parameter
accountEmail: new Text(email,style: TextStyle(fontSize: 14),), // here i am using email parameter
currentAccountPicture: new CircleAvatar(
backgroundColor:
Theme.of(context).platform == TargetPlatform.android
? Colors.white
: Colors.blue,
child: Text(
name[0][0],
style: TextStyle(fontSize: 40.0),
),
),
),
new ListTile(
title: new Text('Request for leave'),
leading: Icon(Icons.request_page),
onTap: (){
Navigator.pop(context);
Navigator.push(context, new MaterialPageRoute(
builder: (context)=>new RequestForLeave(name,email) //here i am passing name and email parameters
)
);
},
),
new ExpansionTile(
title: new Text('History'),
children: <Widget>[
ListTile(
title:new Text("My Attendance"),
leading: Icon(Icons.assessment_outlined ),
onTap: (){
Navigator.pop(context);
Navigator.push(context, new MaterialPageRoute(
builder: (context)=>new MyAttendance()
)
);
},
),
ListTile(
title:new Text("Leaves"),
leading: Icon(Icons.assessment_outlined ),
onTap: (){
Navigator.pop(context);
Navigator.push(context, new MaterialPageRoute(
builder: (context)=>new Leaves()
)
);
},
)
// Text("My Attendance"),
// Text("Leaves"),
],
leading: Icon(Icons.history,
),
)],
),
),
);
}
}
这是我传递参数的 RequestforLeave 代码
import 'package:attendance_system_app/Admin_Navigation/AdminNavigation.dart';
import 'package:attendance_system_app/Employee_Navigation/EmployeeNavigation.dart';
import 'package:attendance_system_app/Leaves/Leaves.dart';
import 'package:attendance_system_app/My_Attendance/MyAttendance.dart';
import 'package:flutter/material.dart';
class RequestForLeave extends StatefulWidget {
var name;
var email;
RequestForLeave(name, email);
@override
State<StatefulWidget> createState(){
return _RequestForLeaveState(this.name,this.email);
}
}
class _RequestForLeaveState extends State<RequestForLeave> {
var name;
var email;
_RequestForLeaveState(this.name,this.email);
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: AppBar(
title: Image.asset("assets/image/company_logo.png",height: 140,width: 280,
),
//automaticallyImplyLeading: false,
backgroundColor: Colors.white,
iconTheme: IconThemeData(color: Colors.blue,size: 20),
//leading: new Icon(Icons.menu,color: Colors.blue,),
actions: <Widget>[
IconButton(
icon: Icon(
Icons.notifications,
color: Colors.blue,
size:26
),
onPressed: () {
// do something
},
)
],
),
drawer:new Drawer(
child: new ListView(
padding: const EdgeInsets.all(0.0),
children: <Widget>[
new UserAccountsDrawerHeader(
accountName: new Text(name,style: TextStyle(fontSize: 14)),
accountEmail: new Text(email,style: TextStyle(fontSize: 14),),
currentAccountPicture: new CircleAvatar(
backgroundColor:
Theme.of(context).platform == TargetPlatform.android
? Colors.white
: Colors.blue,
child: Text(
name[0][0],
style: TextStyle(fontSize: 40.0),
),
),
),
new ListTile(
title: new Text('Request for leave'),
leading: Icon(Icons.request_page),
onTap: (){
Navigator.pop(context);
Navigator.push(context, new MaterialPageRoute(
builder: (context)=>new RequestForLeave(name,email)
)
);
},
),
new ExpansionTile(
title: new Text('History'),
children: <Widget>[
ListTile(
title:new Text("My Attendance"),
leading: Icon(Icons.assessment_outlined ),
onTap: (){
Navigator.pop(context);
Navigator.push(context, new MaterialPageRoute(
builder: (context)=>new MyAttendance()
)
);
},
),
ListTile(
title:new Text("Leaves"),
leading: Icon(Icons.assessment_outlined ),
onTap: (){
Navigator.pop(context);
Navigator.push(context, new MaterialPageRoute(
builder: (context)=>new Leaves()
)
);
},
)
// Text("My Attendance"),
// Text("Leaves"),
],
leading: Icon(Icons.history,
),
)],
),
),
body:Center(
child: Text(
"Request for leave",
style: TextStyle(fontSize: 28),
)),
);
}
}
我在 EmployeeNavigation 抽屉上得到了正确的值,但是当我点击 Request for leave 时出现错误
这里是错误输出
[![在此处输入图片描述][1]][1]
这是我的主屏幕抽屉样子
[![在此处输入图片描述][2]][2]
请帮我解决这个问题,我在我的应用程序的每个屏幕上都显示相同的抽屉。
--------------------更新了-------------------- ----------
class EmployeeNavigation extends StatefulWidget {
var name;
var email;
var designation;
var date;
var timeIn;
var timeOut;
EmployeeNavigation({this.name, this.email, this.designation, this.date, this.timeIn, this.timeOut, } );
@override
State<StatefulWidget> createState() {
return EmployeeNavigationState(this.name,this.email,this.designation,this.date,this.timeIn,this.timeOut);
}
}
class EmployeeNavigationState extends State<EmployeeNavigation> {
// here is create Drawer widget
Widget DrawerCode(){
return Drawer(
child: new ListView(
padding: const EdgeInsets.all(0.0),
children: <Widget>[
new UserAccountsDrawerHeader(
accountName: new Text(name,style: TextStyle(fontSize: 14)),
accountEmail: new Text(email,style: TextStyle(fontSize: 14),),
currentAccountPicture: new CircleAvatar(
backgroundColor:
Theme.of(context).platform == TargetPlatform.android
? Colors.white
: Colors.blue,
child: Text(
name[0][0],
style: TextStyle(fontSize: 40.0),
),
),
),
new ListTile(
title: new Text('Request for leave'),
leading: Icon(Icons.request_page),
onTap: (){
Navigator.pop(context);
Navigator.push(context, new MaterialPageRoute(
builder: (context)=>new RequestForLeave()
)
);
},
),
new ExpansionTile(
title: new Text('History'),
children: <Widget>[
ListTile(
title:new Text("My Attendance"),
leading: Icon(Icons.assessment_outlined ),
onTap: (){
Navigator.pop(context);
Navigator.push(context, new MaterialPageRoute(
builder: (context)=>new MyAttendance()
)
);
},
),
ListTile(
title:new Text("Leaves"),
leading: Icon(Icons.assessment_outlined ),
onTap: (){
Navigator.pop(context);
Navigator.push(context, new MaterialPageRoute(
builder: (context)=>new Leaves()
)
);
},
)
// Text("My Attendance"),
// Text("Leaves"),
],
leading: Icon(Icons.history,
),
)],
),
);
}
var name;
var email;
var designation;
var date;
EmployeeNavigationState(this.name,this.email, this.designation,this.date,this.timeIn, this.timeOut );
bool valuefirst = false;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Image.asset("assets/image/company_logo.png",height: 140,width: 280,
),
backgroundColor: Colors.white,
iconTheme: IconThemeData(color: Colors.blue,size: 20),
//leading: new Icon(Icons.menu,color: Colors.blue,),
actions: <Widget>[
IconButton(
icon: Icon(
Icons.notifications,
color: Colors.blue,
size:26
),
)
],
),
drawer:DrawerCode(),
);
}
}
[1]: https://i.stack.imgur.com/aAqI2.png
[2]: https://i.stack.imgur.com/Ivpbu.png
显示的错误与抽屉无关,它与您将 NULL
传递到需要有效字符串的 Text
小部件有关。
String variable = null;
Text(variable) <-- error
String variable = '';
Text(variable) <-- fine!
对我来说,您采用的方法似乎不正确。如果你有 100 个屏幕并且你想在每个屏幕中显示抽屉,你将有 100 个抽屉。如果您喜欢这种方法,您应该创建一个 Drawer Widget 文件以避免重复。
我可以建议您采用不同的方法吗?
假设您有以下文件夹结构:
Home Screen
- Dashboard Screen
- Customers Screen
- Items Screen
只有Home Screen
有抽屉。 Home Screen
将在其内部加载所有子屏幕(仪表板、客户和项目)。
class _HomeState extends State<Home>
{
String appTitle = 'Dashboard';
Widget appBody = DashboardScreen(); // By default
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(
this.appTitle,
),
),
body: this.appBody,
drawer: YourDrawer()
);
}
}
现在你所需要的只是一个随时跳转到另一个子屏幕的功能:
void jumpToScreen(String appTitle, Widget appBody)
{
setState(()
{
this.appTitle = appTitle;
this.appBody = appBody;
});
}
您还可以应用一些逻辑来根据屏幕显示不同的应用程序操作按钮。