我是Flutter的新手。我编写了一些代码,使用户可以使用自己的帐户和密码登录或注册。但是,当我要将数据添加到诸如用户名,帐户和ID之类的列表时,总是会收到此错误:“ NoSuchMethodError:方法'add'被调用为null。”。我读过人们问过的一些类似问题。他们中的大多数人都因为没有初始化列表而得到错误。与它们不同,我已经初始化了每个列表,但是仍然不断收到此错误。请帮我解决这个问题,tks。
导致错误的函数:
Future Register() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
Username.add(_RtextFieldUsername.value.text.toString());
Account.add(_RtextFieldAccount.value.text.toString());
ID.add(_RtextFieldID.value.text.toString());
await prefs.setStringList(_StorageAccount, Account);
await prefs.setStringList(_StorageID, ID);
await prefs.setStringList(_StorageUsername, Username);
}
整个代码:
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'Uhome.dart';
import 'Thome.dart';
class ProfilePage extends StatefulWidget{
List<String> Username = List();
List<String> Account = List();
List<String> ID = List();
ProfilePage({this.Username, this.Account, this.ID});
@override
_ProfilePageState createState() => _ProfilePageState(Username, Account, ID);
}
class _ProfilePageState extends State<ProfilePage>{
List<String> Username = List();
List<String> Account = List();
List<String> ID = List();
_ProfilePageState(this.Username, this.Account, this.ID);
int _currentIndex = 2;
final _Pages = <Widget>[
UniversityPage(),
TransportationPage(),
ProfilePage(),
];
var _LtextFieldAccount = new TextEditingController();
var _LtextFieldID = new TextEditingController();
final _StorageUsername = 'Username';
final _StorageAccount = 'Account';
final _StorageID = 'ID';
String LoginedUsername = '';
Future Login() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
bool checked = false;
String InsertAccount = _LtextFieldAccount.value.text.toString();
String InsertID = _LtextFieldID.value.text.toString();
List<String> GetAccountList = (prefs.getStringList(_StorageAccount) ?? List<String>());
List<String> GetIDList = (prefs.getStringList(_StorageID) ?? List<String>());
for(int i = 0 ; i < GetAccountList.length ; i++){
if(GetAccountList[i] == InsertAccount && GetIDList[i] == InsertID){
List<String> GetUsernameList = (prefs.getStringList(_StorageUsername) ?? List<String>());
checked = true;
LoginedUsername = GetUsernameList[i];
break;
}
}
if(checked == true){
print('Succeed');// Navigate to profile page
}
else{
Alert(context);// stay at the same page
}
}
void Alert(BuildContext context) {
AlertDialog dialog = AlertDialog(
backgroundColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(15)),
),
content: Container(
padding: EdgeInsets.only(left: 5, top: 5, bottom: 5),
child: Row(
children: <Widget>[
Icon(
Icons.warning,
color: Colors.black54,
size: 30,
),
Padding(padding: EdgeInsets.only(right: 10)),
Text("帳號或密碼輸入錯誤", style: TextStyle(color: Colors.black, fontSize: 20,),
),
],
),
),
actions: <Widget>[
FlatButton(
onPressed: () {
Navigator.pop(context, true);
},
child: Text("確定", style: TextStyle(color: Colors.blueAccent),),
),
],
);
showDialog(
barrierDismissible: false,
context: context,
builder: (BuildContext context) => dialog,
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: <Widget>[
Container(
height: double.infinity,
width: double.infinity,
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
Color(0xFF73AEF5),
Color(0xFF61A4F1),
Color(0xFF478DE0),
Color(0xFF398AE5),
],
stops: [0.1, 0.4, 0.7, 0.9],
)
),
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
SizedBox(height: 10,),
Icon(Icons.account_circle, size: 150.0,),
SizedBox(height: 30),
Container(
width: 300,
child: Theme(
data: ThemeData(
primaryColor: Colors.white,
primaryColorDark: Colors.yellowAccent,
),
child: TextField(
controller: _LtextFieldAccount,
decoration: InputDecoration(
border: OutlineInputBorder(),
hintText: '請輸入帳號',
prefixIcon: const Icon(Icons.person)
),
)
),
),
SizedBox(height: 20),
Container(
width: 300,
child: Theme(
data: ThemeData(
primaryColor: Colors.white,
primaryColorDark: Colors.yellowAccent,
),
child: TextField(
controller: _LtextFieldID,
decoration: InputDecoration(
border: OutlineInputBorder(),
hintText: '請輸入密碼',
prefixIcon: const Icon(Icons.lock)
),
)
),
),
SizedBox(height: 30),
RaisedButton(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(25.0)),
elevation: 4.0,
color: Colors.white,
child: Container(
padding: EdgeInsets.only(left: 10, right: 10, top: 10, bottom: 10),
child: Text('登入', style: TextStyle(fontSize: 25, color: Colors.blueAccent),),
),
onPressed: Login,
),
SizedBox(height: 20),
RaisedButton(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(25.0)),
elevation: 4.0,
color: Colors.white,
child: Container(
padding: EdgeInsets.only(left: 10, right: 10, top: 10, bottom: 10),
child: Text('新用戶註冊', style: TextStyle(fontSize: 25, color: Colors.blueAccent),),
),
onPressed: (){
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => RegisterPage(Username: Username, Account: Account, ID: ID,)
));
}
)
],
),
),
),
],
),
bottomNavigationBar: BottomNavigationBar(
onTap: onTabTapped,
currentIndex: _currentIndex,
// this will be set when a new tab is tapped
items: [
new BottomNavigationBarItem(
icon: new Icon(Icons.school),
title: new Text('大學'),
),
new BottomNavigationBarItem(
icon: new Icon(Icons.directions_subway),
title: new Text('交通'),
),
new BottomNavigationBarItem(
icon: new Icon(Icons.person),
title: new Text('個人'),
)
],
),
);
}
void onTabTapped(int index){
setState(() {
_currentIndex = index;
Navigator.push(
context,
PageRouteBuilder(
pageBuilder: (context, animation1, animation2) => _Pages[index],
transitionDuration: Duration(seconds: 0),
),
);
});
}
}
// LoginPage-----------------------------------------------------------------------------------------------------------------------------------------------------------------
class RegisterPage extends StatefulWidget{
List<String> Username = List();
List<String> Account = List();
List<String> ID = List();
RegisterPage({this.Username, this.Account, this.ID});
RegisterPageState createState() => RegisterPageState(Username, Account, ID);
}
class RegisterPageState extends State<RegisterPage>{
List<String> Username = List();
List<String> Account = List();
List<String> ID = List();
RegisterPageState(this.Username, this.Account, this.ID);
int _currentIndex = 2;
final _Pages = <Widget>[
UniversityPage(),
TransportationPage(),
ProfilePage(),
];
var _RtextFieldUsername = new TextEditingController();
var _RtextFieldAccount = new TextEditingController();
var _RtextFieldID = new TextEditingController();
final _StorageUsername = 'Username';
final _StorageAccount = 'Account';
final _StorageID = 'ID';
// register & store data
Future Register() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
Username.add(_RtextFieldUsername.value.text.toString());
Account.add(_RtextFieldAccount.value.text.toString());
ID.add(_RtextFieldID.value.text.toString());
await prefs.setStringList(_StorageAccount, Account);
await prefs.setStringList(_StorageID, ID);
await prefs.setStringList(_StorageUsername, Username);
}
void Alert(BuildContext context) {
AlertDialog dialog = AlertDialog(
backgroundColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(15)),
),
content: Container(
padding: EdgeInsets.only(left: 5, top: 5, bottom: 5),
child: Row(
children: <Widget>[
Icon(
Icons.check,
color: Colors.black54,
size: 30,
),
Padding(padding: EdgeInsets.only(right: 10)),
Text("註冊成功! =D\n請重新登入", style: TextStyle(color: Colors.black, fontSize: 20,),
),
],
),
),
actions: <Widget>[
FlatButton(
onPressed: () {
Navigator.pop(context, true);
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => ProfilePage(Username: Username, Account: Account, ID: ID,)
));
},
child: Text("確定", style: TextStyle(color: Colors.blueAccent),),
),
],
);
showDialog(
barrierDismissible: false,
context: context,
builder: (BuildContext context) => dialog,
);
}
void RegisterAlert(BuildContext context, int num) {
List<String> AlertText = ['欄位不可為空', '帳號需至少8個字元', '密碼需至少8個字元'];
AlertDialog dialog = AlertDialog(
backgroundColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(15)),
),
content: Container(
padding: EdgeInsets.only(left: 5, top: 5, bottom: 5),
child: Row(
children: <Widget>[
Icon(
Icons.warning,
color: Colors.black54,
size: 30,
),
Padding(padding: EdgeInsets.only(right: 10)),
Text(AlertText[num], style: TextStyle(color: Colors.black, fontSize: 20,),
),
],
),
),
actions: <Widget>[
FlatButton(
onPressed: () {
Navigator.pop(context, true);
},
child: Text("確定", style: TextStyle(color: Colors.blueAccent),),
),
],
);
showDialog(
barrierDismissible: false,
context: context,
builder: (BuildContext context) => dialog,
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: <Widget>[
Container(
height: double.infinity,
width: double.infinity,
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
Color(0xFF73AEF5),
Color(0xFF61A4F1),
Color(0xFF478DE0),
Color(0xFF398AE5),
],
stops: [0.1, 0.4, 0.7, 0.9],
)
),
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
SizedBox(height: 10,),
Icon(Icons.person_add, size: 150.0,),
SizedBox(height: 30),
Container(
width: 300,
child: Theme(
data: ThemeData(
primaryColor: Colors.white,
primaryColorDark: Colors.yellowAccent,
),
child: TextField(
controller: _RtextFieldUsername,
decoration: InputDecoration(
border: OutlineInputBorder(),
hintText: '請輸入用戶名',
prefixIcon: const Icon(Icons.face)
),
)
),
),
SizedBox(height: 20),
Container(
width: 300,
child: Theme(
data: ThemeData(
primaryColor: Colors.white,
primaryColorDark: Colors.yellowAccent,
),
child: TextField(
controller: _RtextFieldAccount,
decoration: InputDecoration(
border: OutlineInputBorder(),
hintText: '請輸入註冊帳號',
prefixIcon: const Icon(Icons.person)
),
)
),
),
SizedBox(height: 20),
Container(
width: 300,
child: Theme(
data: ThemeData(
primaryColor: Colors.white,
primaryColorDark: Colors.yellowAccent,
),
child: TextField(
controller: _RtextFieldID,
decoration: InputDecoration(
border: OutlineInputBorder(),
hintText: '請輸入註冊密碼',
prefixIcon: const Icon(Icons.lock)
),
)
),
),
SizedBox(height: 30),
RaisedButton(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(25.0)),
elevation: 4.0,
color: Colors.white,
child: Container(
padding: EdgeInsets.only(left: 10, right: 10, top: 10, bottom: 10),
child: Text('註冊', style: TextStyle(fontSize: 25, color: Colors.blueAccent),),
),
onPressed: (){
if(_RtextFieldUsername.value.text.toString() == '' || _RtextFieldAccount.value.text.toString() == '' || _RtextFieldID.value.text.toString() == '' ){
RegisterAlert(context, 0);
}
else if(_RtextFieldAccount.value.text.toString().length < 8){
RegisterAlert(context, 1);
}
else if(_RtextFieldID.value.text.toString().length < 8){
RegisterAlert(context, 2);
}
else{
Register();
Alert(context);
}
},
),
],
),
),
),
],
),
bottomNavigationBar: BottomNavigationBar(
onTap: onTabTapped,
currentIndex: _currentIndex,
// this will be set when a new tab is tapped
items: [
new BottomNavigationBarItem(
icon: new Icon(Icons.school),
title: new Text('大學'),
),
new BottomNavigationBarItem(
icon: new Icon(Icons.directions_subway),
title: new Text('交通'),
),
new BottomNavigationBarItem(
icon: new Icon(Icons.person),
title: new Text('個人'),
)
],
),
);
}
void onTabTapped(int index){
setState(() {
_currentIndex = index;
Navigator.push(
context,
PageRouteBuilder(
pageBuilder: (context, animation1, animation2) => _Pages[index],
transitionDuration: Duration(seconds: 0),
),
);
});
}
}
错误消息:
E/flutter (20665): [ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: NoSuchMethodError: The method 'add' was called on null.
E/flutter (20665): Receiver: null
E/flutter (20665): Tried calling: add("username")
E/flutter (20665): #0 Object.noSuchMethod (dart:core-patch/object_patch.dart:53:5)
E/flutter (20665): #1 RegisterPageState.Register (package:roadtouniversity/profile.dart:281:14)
E/flutter (20665): <asynchronous suspension>
E/flutter (20665): #2 RegisterPageState.build.<anonymous closure> (package:roadtouniversity/profile.dart:473:25)
E/flutter (20665): #3 _InkResponseState._handleTap (package:flutter/src/material/ink_well.dart:779:19)
E/flutter (20665): #4 _InkResponseState.build.<anonymous closure> (package:flutter/src/material/ink_well.dart:862:36)
E/flutter (20665): #5 GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:182:24)
E/flutter (20665): #6 TapGestureRecognizer.handleTapUp (package:flutter/src/gestures/tap.dart:504:11)
E/flutter (20665): #7 BaseTapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:282:5)
E/flutter (20665): #8 BaseTapGestureRecognizer.handlePrimaryPointer (package:flutter/src/gestures/tap.dart:217:7)
E/flutter (20665): #9 PrimaryPointerGestureRecognizer.handleEvent (package:flutter/src/gestures/recognizer.dart:475:9)
E/flutter (20665): #10 PointerRouter._dispatch (package:flutter/src/gestures/pointer_router.dart:76:12)
E/flutter (20665): #11 PointerRouter._dispatchEventToRoutes.<anonymous closure> (package:flutter/src/gestures/pointer_router.dart:122:9)
E/flutter (20665): #12 _LinkedHashMapMixin.forEach (dart:collection-patch/compact_hash.dart:379:8)
E/flutter (20665): #13 PointerRouter._dispatchEventToRoutes (package:flutter/src/gestures/pointer_router.dart:120:18)
E/flutter (20665): #14 PointerRouter.route (package:flutter/src/gestures/pointer_router.dart:106:7)
E/flutter (20665): #15 GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:218:19)
E/flutter (20665): #16 GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:198:22)
E/flutter (20665): #17 GestureBinding._handlePointerEvent (package:flutter/src/gestures/binding.dart:156:7)
E/flutter (20665): #18 GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:102:7)
E/flutter (20665): #19 GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:86:7)
E/flutter (20665): #20 _rootRunUnary (dart:async/zone.dart:1196:13)
E/flutter (20665): #21 _CustomZone.runUnary (dart:async/zone.dart:1085:19)
E/flutter (20665): #22 _CustomZone.runUnaryGuarded (dart:async/zone.dart:987:7)
E/flutter (20665): #23 _invoke1 (dart:ui/hooks.dart:275:10)
E/flutter (20665): #24 _dispatchPointerDataPacket (dart:ui/hooks.dart:184:5)
E/flutter (20665):
答案 0 :(得分:0)
您可以在下面复制粘贴运行完整代码
步骤1:使用初始值
ProfilePage
home: ProfilePage(
Username: [],
Account: [],
ID: [],
),
步骤2:您无需再次初始化List<String>
class ProfilePage extends StatefulWidget {
List<String> Username;
List<String> Account;
List<String> ID;
...
class _ProfilePageState extends State<ProfilePage> {
List<String> Username;
List<String> Account;
List<String> ID;
...
class RegisterPage extends StatefulWidget {
List<String> Username;
List<String> Account;
List<String> ID;
...
class RegisterPageState extends State<RegisterPage> {
List<String> Username;
List<String> Account;
List<String> ID;
...
第3步:使用SingleChildScrollView
避免溢出
child: SingleChildScrollView(
child: Center(
工作演示
完整代码
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
class ProfilePage extends StatefulWidget {
List<String> Username;
List<String> Account;
List<String> ID;
ProfilePage({this.Username, this.Account, this.ID});
@override
_ProfilePageState createState() => _ProfilePageState(Username, Account, ID);
}
class _ProfilePageState extends State<ProfilePage> {
List<String> Username;
List<String> Account;
List<String> ID;
_ProfilePageState(this.Username, this.Account, this.ID);
int _currentIndex = 2;
final _Pages = <Widget>[
UniversityPage(),
TransportationPage(),
ProfilePage(),
];
var _LtextFieldAccount = new TextEditingController();
var _LtextFieldID = new TextEditingController();
final _StorageUsername = 'Username';
final _StorageAccount = 'Account';
final _StorageID = 'ID';
String LoginedUsername = '';
Future Login() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
bool checked = false;
String InsertAccount = _LtextFieldAccount.value.text.toString();
String InsertID = _LtextFieldID.value.text.toString();
List<String> GetAccountList =
(prefs.getStringList(_StorageAccount) ?? List<String>());
List<String> GetIDList =
(prefs.getStringList(_StorageID) ?? List<String>());
for (int i = 0; i < GetAccountList.length; i++) {
if (GetAccountList[i] == InsertAccount && GetIDList[i] == InsertID) {
List<String> GetUsernameList =
(prefs.getStringList(_StorageUsername) ?? List<String>());
checked = true;
LoginedUsername = GetUsernameList[i];
break;
}
}
if (checked == true) {
print('Succeed'); // Navigate to profile page
} else {
Alert(context); // stay at the same page
}
}
void Alert(BuildContext context) {
AlertDialog dialog = AlertDialog(
backgroundColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(15)),
),
content: Container(
padding: EdgeInsets.only(left: 5, top: 5, bottom: 5),
child: Row(
children: <Widget>[
Icon(
Icons.warning,
color: Colors.black54,
size: 30,
),
Padding(padding: EdgeInsets.only(right: 10)),
Text(
"帳號或密碼輸入錯誤",
style: TextStyle(
color: Colors.black,
fontSize: 20,
),
),
],
),
),
actions: <Widget>[
FlatButton(
onPressed: () {
Navigator.pop(context, true);
},
child: Text(
"確定",
style: TextStyle(color: Colors.blueAccent),
),
),
],
);
showDialog(
barrierDismissible: false,
context: context,
builder: (BuildContext context) => dialog,
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: <Widget>[
Container(
height: double.infinity,
width: double.infinity,
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
Color(0xFF73AEF5),
Color(0xFF61A4F1),
Color(0xFF478DE0),
Color(0xFF398AE5),
],
stops: [0.1, 0.4, 0.7, 0.9],
)),
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
SizedBox(
height: 10,
),
Icon(
Icons.account_circle,
size: 150.0,
),
SizedBox(height: 30),
Container(
width: 300,
child: Theme(
data: ThemeData(
primaryColor: Colors.white,
primaryColorDark: Colors.yellowAccent,
),
child: TextField(
controller: _LtextFieldAccount,
decoration: InputDecoration(
border: OutlineInputBorder(),
hintText: '請輸入帳號',
prefixIcon: const Icon(Icons.person)),
)),
),
SizedBox(height: 20),
Container(
width: 300,
child: Theme(
data: ThemeData(
primaryColor: Colors.white,
primaryColorDark: Colors.yellowAccent,
),
child: TextField(
controller: _LtextFieldID,
decoration: InputDecoration(
border: OutlineInputBorder(),
hintText: '請輸入密碼',
prefixIcon: const Icon(Icons.lock)),
)),
),
SizedBox(height: 30),
RaisedButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(25.0)),
elevation: 4.0,
color: Colors.white,
child: Container(
padding: EdgeInsets.only(
left: 10, right: 10, top: 10, bottom: 10),
child: Text(
'登入',
style:
TextStyle(fontSize: 25, color: Colors.blueAccent),
),
),
onPressed: Login,
),
SizedBox(height: 20),
RaisedButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(25.0)),
elevation: 4.0,
color: Colors.white,
child: Container(
padding: EdgeInsets.only(
left: 10, right: 10, top: 10, bottom: 10),
child: Text(
'新用戶註冊',
style:
TextStyle(fontSize: 25, color: Colors.blueAccent),
),
),
onPressed: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => RegisterPage(
Username: Username,
Account: Account,
ID: ID,
)));
})
],
),
),
),
],
),
bottomNavigationBar: BottomNavigationBar(
onTap: onTabTapped,
currentIndex: _currentIndex,
// this will be set when a new tab is tapped
items: [
new BottomNavigationBarItem(
icon: new Icon(Icons.school),
title: new Text('大學'),
),
new BottomNavigationBarItem(
icon: new Icon(Icons.directions_subway),
title: new Text('交通'),
),
new BottomNavigationBarItem(
icon: new Icon(Icons.person),
title: new Text('個人'),
)
],
),
);
}
void onTabTapped(int index) {
setState(() {
_currentIndex = index;
Navigator.push(
context,
PageRouteBuilder(
pageBuilder: (context, animation1, animation2) => _Pages[index],
transitionDuration: Duration(seconds: 0),
),
);
});
}
}
// LoginPage-----------------------------------------------------------------------------------------------------------------------------------------------------------------
class RegisterPage extends StatefulWidget {
List<String> Username;
List<String> Account;
List<String> ID;
RegisterPage({this.Username, this.Account, this.ID});
RegisterPageState createState() => RegisterPageState(Username, Account, ID);
}
class RegisterPageState extends State<RegisterPage> {
List<String> Username;
List<String> Account;
List<String> ID;
RegisterPageState(this.Username, this.Account, this.ID);
int _currentIndex = 2;
final _Pages = <Widget>[
UniversityPage(),
TransportationPage(),
ProfilePage(),
];
var _RtextFieldUsername = new TextEditingController();
var _RtextFieldAccount = new TextEditingController();
var _RtextFieldID = new TextEditingController();
final _StorageUsername = 'Username';
final _StorageAccount = 'Account';
final _StorageID = 'ID';
// register & store data
Future Register() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
Username.add(_RtextFieldUsername.value.text.toString());
Account.add(_RtextFieldAccount.value.text.toString());
ID.add(_RtextFieldID.value.text.toString());
await prefs.setStringList(_StorageAccount, Account);
await prefs.setStringList(_StorageID, ID);
await prefs.setStringList(_StorageUsername, Username);
}
void Alert(BuildContext context) {
AlertDialog dialog = AlertDialog(
backgroundColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(15)),
),
content: Container(
padding: EdgeInsets.only(left: 5, top: 5, bottom: 5),
child: Row(
children: <Widget>[
Icon(
Icons.check,
color: Colors.black54,
size: 30,
),
Padding(padding: EdgeInsets.only(right: 10)),
Text(
"註冊成功! =D\n請重新登入",
style: TextStyle(
color: Colors.black,
fontSize: 20,
),
),
],
),
),
actions: <Widget>[
FlatButton(
onPressed: () {
Navigator.pop(context, true);
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => ProfilePage(
Username: Username,
Account: Account,
ID: ID,
)));
},
child: Text(
"確定",
style: TextStyle(color: Colors.blueAccent),
),
),
],
);
showDialog(
barrierDismissible: false,
context: context,
builder: (BuildContext context) => dialog,
);
}
void RegisterAlert(BuildContext context, int num) {
List<String> AlertText = ['欄位不可為空', '帳號需至少8個字元', '密碼需至少8個字元'];
AlertDialog dialog = AlertDialog(
backgroundColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(15)),
),
content: Container(
padding: EdgeInsets.only(left: 5, top: 5, bottom: 5),
child: Row(
children: <Widget>[
Icon(
Icons.warning,
color: Colors.black54,
size: 30,
),
Padding(padding: EdgeInsets.only(right: 10)),
Text(
AlertText[num],
style: TextStyle(
color: Colors.black,
fontSize: 20,
),
),
],
),
),
actions: <Widget>[
FlatButton(
onPressed: () {
Navigator.pop(context, true);
},
child: Text(
"確定",
style: TextStyle(color: Colors.blueAccent),
),
),
],
);
showDialog(
barrierDismissible: false,
context: context,
builder: (BuildContext context) => dialog,
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: <Widget>[
Container(
height: double.infinity,
width: double.infinity,
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
Color(0xFF73AEF5),
Color(0xFF61A4F1),
Color(0xFF478DE0),
Color(0xFF398AE5),
],
stops: [0.1, 0.4, 0.7, 0.9],
)),
child: SingleChildScrollView(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
SizedBox(
height: 10,
),
Icon(
Icons.person_add,
size: 150.0,
),
SizedBox(height: 30),
Container(
width: 300,
child: Theme(
data: ThemeData(
primaryColor: Colors.white,
primaryColorDark: Colors.yellowAccent,
),
child: TextField(
controller: _RtextFieldUsername,
decoration: InputDecoration(
border: OutlineInputBorder(),
hintText: '請輸入用戶名',
prefixIcon: const Icon(Icons.face)),
)),
),
SizedBox(height: 20),
Container(
width: 300,
child: Theme(
data: ThemeData(
primaryColor: Colors.white,
primaryColorDark: Colors.yellowAccent,
),
child: TextField(
controller: _RtextFieldAccount,
decoration: InputDecoration(
border: OutlineInputBorder(),
hintText: '請輸入註冊帳號',
prefixIcon: const Icon(Icons.person)),
)),
),
SizedBox(height: 20),
Container(
width: 300,
child: Theme(
data: ThemeData(
primaryColor: Colors.white,
primaryColorDark: Colors.yellowAccent,
),
child: TextField(
controller: _RtextFieldID,
decoration: InputDecoration(
border: OutlineInputBorder(),
hintText: '請輸入註冊密碼',
prefixIcon: const Icon(Icons.lock)),
)),
),
SizedBox(height: 30),
RaisedButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(25.0)),
elevation: 4.0,
color: Colors.white,
child: Container(
padding: EdgeInsets.only(
left: 10, right: 10, top: 10, bottom: 10),
child: Text(
'註冊',
style:
TextStyle(fontSize: 25, color: Colors.blueAccent),
),
),
onPressed: () {
if (_RtextFieldUsername.value.text.toString() == '' ||
_RtextFieldAccount.value.text.toString() == '' ||
_RtextFieldID.value.text.toString() == '') {
RegisterAlert(context, 0);
} else if (_RtextFieldAccount.value.text
.toString()
.length <
8) {
RegisterAlert(context, 1);
} else if (_RtextFieldID.value.text.toString().length <
8) {
RegisterAlert(context, 2);
} else {
Register();
Alert(context);
}
},
),
],
),
),
),
),
],
),
bottomNavigationBar: BottomNavigationBar(
onTap: onTabTapped,
currentIndex: _currentIndex,
// this will be set when a new tab is tapped
items: [
new BottomNavigationBarItem(
icon: new Icon(Icons.school),
title: new Text('大學'),
),
new BottomNavigationBarItem(
icon: new Icon(Icons.directions_subway),
title: new Text('交通'),
),
new BottomNavigationBarItem(
icon: new Icon(Icons.person),
title: new Text('個人'),
)
],
),
);
}
void onTabTapped(int index) {
setState(() {
_currentIndex = index;
Navigator.push(
context,
PageRouteBuilder(
pageBuilder: (context, animation1, animation2) => _Pages[index],
transitionDuration: Duration(seconds: 0),
),
);
});
}
}
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: ProfilePage(
Username: [],
Account: [],
ID: [],
),
);
}
}
class UniversityPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Text("UniversityPage");
}
}
class TransportationPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Text("TransportationPage");
}
}
答案 1 :(得分:0)
您要将列表从一个班级传递到另一个班级
ProfilePage > _ProfilePageState > RegisterPage > RegisterPageState
但这并不意味着列表开始时不能为空。
class ProfilePage extends StatefulWidget{
List<String> Username = List();
List<String> Account = List();
List<String> ID = List();
ProfilePage({this.Username, this.Account, this.ID});
@override
_ProfilePageState createState() => _ProfilePageState(Username, Account, ID);
}
将它们初始化为List但在构造函数中调用它们意味着它们将被构造函数的值覆盖。如果您以ProfilePage(Username: null, Account: null, ID: null)
开头或只是将其命名为ProfilePage()
,则这些属性为空,尽管您在开始时就给了它们值。您必须确保在创建ProfilePage类时,传递给的属性不为null,否则整个逻辑将为null
就像其他人指出的那样,您不需要在StatefulWidget和State中初始化它们
class RegisterPage extends StatefulWidget{
List<String> Username = List();
List<String> Account = List();
List<String> ID = List();
RegisterPage({this.Username, this.Account, this.ID});
RegisterPageState createState() => RegisterPageState(Username, Account, ID);
}
class RegisterPageState extends State<RegisterPage>{
List<String> Username = List(); //This is pointless
List<String> Account = List(); //This is pointless
List<String> ID = List(); //This is pointless
...
}
如果您要使用/修改刚刚从上一页传递过来的内容,只需像这样使用它们
class RegisterPage extends StatefulWidget{
List<String> Username = List(); //you wanted to use this
List<String> Account = List(); //you wanted to use this
List<String> ID = List(); //you wanted to use this
RegisterPage({this.Username, this.Account, this.ID});
RegisterPageState createState() => RegisterPageState(); //no need to pass the parameters
}
class RegisterPageState extends State<RegisterPage>{
Future Register() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
widget.Username.add(_RtextFieldUsername.value.text.toString());
widget.Account.add(_RtextFieldAccount.value.text.toString());
widget.ID.add(_RtextFieldID.value.text.toString());
/*
widget.value let you use the objects/variables defined in the StatefulWidget
so you don't need to create new ones in the State
*/
await prefs.setStringList(_StorageAccount, Account);
await prefs.setStringList(_StorageID, ID);
await prefs.setStringList(_StorageUsername, Username);
}
....
}