NoSuchMethodError:方法“ add”在null上被调用

时间:2020-06-24 01:30:18

标签: list flutter dart

我是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): 

2 个答案:

答案 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(

工作演示

enter image description here

完整代码

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);
  } 
  ....
}