Getter 方法返回空值
Getter method returning null value
我在 flutter 中使用本地数据库开发了一个登录页面 SQL。我想在 table 创建后在 SQL 数据库中显示用户名,但 getter 方法返回 null。
我在 class 主页
中显示这样的用户名
body: Center(
child: user != null ? Text("Saved \n \n Username: '${user.username}' ")
: Text("Not saved"),
),
这是登录页面代码
BuildContext _ctx;
bool _isLoading = false;
final _formKey = new GlobalKey<FormState>();
final scaffoldKey = new GlobalKey<ScaffoldState>();
String _username,_password;
LoginPagePresenter _presenter;
@override
void initState(){
_presenter = new LoginPagePresenter(this);
}
void _submit(){
final form = _formKey.currentState;
if(form.validate()){
_isLoading = true;
form.save();
_presenter.doLogin(_username, _password);
}
}
void _showsnackbar(String text){
scaffoldKey.currentState.showSnackBar(new SnackBar(
content: new Text(text),
));
}
@override
Widget build(BuildContext context) {
return _isLoading ? Loading() :Scaffold(
appBar: AppBar(
backgroundColor: Colors.black,
title: Text('Login Page',textAlign: TextAlign.center,),
),
body: Container(
padding: EdgeInsets.symmetric(vertical: 20.0, horizontal: 50.0),
child: Form(
key: _formKey,
child: Column(
children: <Widget>[
SizedBox(height: 20.0),
TextFormField(
decoration: InputDecoration(labelText:'Username' ),
validator: (val) => val.isEmpty ? 'Enter Username' : null,
onChanged: (val) {
setState(() => _username = val);
},
),
SizedBox(height: 20.0),
TextFormField(
obscureText: true,
decoration: InputDecoration(labelText:'Password' ),
validator: (val) => val.length < 6 ? 'Enter a password 6+ chars long' : null,
onChanged: (val) {
setState(() => _password = val);
},
),
SizedBox(height: 20.0),
RaisedButton(
color: Colors.pink[400],
child: Text(
'Sign In',
style: TextStyle(color: Colors.white),
),
onPressed: () async {
_submit();
}
),
],
),
),
),
);
}
@override
void onLoginError(String error) {
_showsnackbar(error);
setState(() {
_isLoading = false;
});
}
@override
void onLoginSuccess(User user) async {
_showsnackbar(user.toString());
setState(() {
_isLoading = false;
});
var db = new DatabaseHelper();
await db.saveUser(user);
Navigator.of(_ctx).push(MaterialPageRoute<Null>(
builder: (BuildContext context){
return new Home(
user:user,
);
}
));
}
这是用户 class
class User{
String _username;
String _password;
User(this._username,this._password);
User.map(dynamic obj){
this._username = obj['username'];
this._password = obj['password'];
}
String get username => _username;
String get password => _password;
Map<String,dynamic> toMap(){
var map = new Map<String,dynamic>();
map["username"] = _username;
map["password"] = _password;
return map;
}
}
这是数据库助手class
class DatabaseHelper{
static final DatabaseHelper _instance = new DatabaseHelper.internal();
DatabaseHelper.internal();
factory DatabaseHelper() => _instance;
static Database _db;
Future<Database> get db async{
if(_db!= null)
{
return _db;
}
_db = await initdb();
return _db;
}
initdb() async{
Directory documentDirectory = await getApplicationDocumentsDirectory();
String path = join(documentDirectory.path,"main.db");
var ourDb = await openDatabase(path,version:1,onCreate:_onCreate);
return ourDb;
}
void _onCreate(Database db,int version)async {
await db.execute("CREATE TABLE User(id INTEGER PRIMARY KEY,username TEXT,password TEXT)");
print("Table created");
}
//insertion of data
Future<int> saveUser(User user)async {
var dbClient = await db;
int res = await dbClient.insert("User", user.toMap());
return res;
}
// deleting data
Future<int> deleteUser(User user)async {
var dbClient = await db;
int res = await dbClient.delete("User");
return res;
}
}
这是登录演示者
abstract class LoginPageContract{
void onLoginSuccess(User user);
void onLoginError(String error);
}
class LoginPagePresenter{
LoginPageContract _view;
RestData api = new RestData();
LoginPagePresenter(this._view);
doLogin(String username,String password){
api
.login(username, password)
.then((user)=> _view.onLoginSuccess(user))
.catchError((onError)=>_view.onLoginError(onError()));
}
}
这是githublink给的代码供参考:https://github.com/meadows12/sql
请帮忙!!
您所要做的就是以 "widget.user" 而不是 "user" 的形式访问用户对象。因此,以下内容可以解决问题:
body: Center(
child: widget.user != null ? Text("Saved \n \n Username: '${widget.user.username}' ")
: Text("Not saved"),
)
代码中还有一个问题。您没有将 buildcontext 分配给变量 _ctx。因此,github 上的代码并未发生屏幕更改。我在 login.dart 中添加了一行,如下所示:
Widget build(BuildContext context) {
_ctx = context;
return _isLoading ? Loading() :Scaffold(______________
结果:
我在 flutter 中使用本地数据库开发了一个登录页面 SQL。我想在 table 创建后在 SQL 数据库中显示用户名,但 getter 方法返回 null。
我在 class 主页
中显示这样的用户名body: Center(
child: user != null ? Text("Saved \n \n Username: '${user.username}' ")
: Text("Not saved"),
),
这是登录页面代码
BuildContext _ctx;
bool _isLoading = false;
final _formKey = new GlobalKey<FormState>();
final scaffoldKey = new GlobalKey<ScaffoldState>();
String _username,_password;
LoginPagePresenter _presenter;
@override
void initState(){
_presenter = new LoginPagePresenter(this);
}
void _submit(){
final form = _formKey.currentState;
if(form.validate()){
_isLoading = true;
form.save();
_presenter.doLogin(_username, _password);
}
}
void _showsnackbar(String text){
scaffoldKey.currentState.showSnackBar(new SnackBar(
content: new Text(text),
));
}
@override
Widget build(BuildContext context) {
return _isLoading ? Loading() :Scaffold(
appBar: AppBar(
backgroundColor: Colors.black,
title: Text('Login Page',textAlign: TextAlign.center,),
),
body: Container(
padding: EdgeInsets.symmetric(vertical: 20.0, horizontal: 50.0),
child: Form(
key: _formKey,
child: Column(
children: <Widget>[
SizedBox(height: 20.0),
TextFormField(
decoration: InputDecoration(labelText:'Username' ),
validator: (val) => val.isEmpty ? 'Enter Username' : null,
onChanged: (val) {
setState(() => _username = val);
},
),
SizedBox(height: 20.0),
TextFormField(
obscureText: true,
decoration: InputDecoration(labelText:'Password' ),
validator: (val) => val.length < 6 ? 'Enter a password 6+ chars long' : null,
onChanged: (val) {
setState(() => _password = val);
},
),
SizedBox(height: 20.0),
RaisedButton(
color: Colors.pink[400],
child: Text(
'Sign In',
style: TextStyle(color: Colors.white),
),
onPressed: () async {
_submit();
}
),
],
),
),
),
);
}
@override
void onLoginError(String error) {
_showsnackbar(error);
setState(() {
_isLoading = false;
});
}
@override
void onLoginSuccess(User user) async {
_showsnackbar(user.toString());
setState(() {
_isLoading = false;
});
var db = new DatabaseHelper();
await db.saveUser(user);
Navigator.of(_ctx).push(MaterialPageRoute<Null>(
builder: (BuildContext context){
return new Home(
user:user,
);
}
));
}
这是用户 class
class User{
String _username;
String _password;
User(this._username,this._password);
User.map(dynamic obj){
this._username = obj['username'];
this._password = obj['password'];
}
String get username => _username;
String get password => _password;
Map<String,dynamic> toMap(){
var map = new Map<String,dynamic>();
map["username"] = _username;
map["password"] = _password;
return map;
}
}
这是数据库助手class
class DatabaseHelper{
static final DatabaseHelper _instance = new DatabaseHelper.internal();
DatabaseHelper.internal();
factory DatabaseHelper() => _instance;
static Database _db;
Future<Database> get db async{
if(_db!= null)
{
return _db;
}
_db = await initdb();
return _db;
}
initdb() async{
Directory documentDirectory = await getApplicationDocumentsDirectory();
String path = join(documentDirectory.path,"main.db");
var ourDb = await openDatabase(path,version:1,onCreate:_onCreate);
return ourDb;
}
void _onCreate(Database db,int version)async {
await db.execute("CREATE TABLE User(id INTEGER PRIMARY KEY,username TEXT,password TEXT)");
print("Table created");
}
//insertion of data
Future<int> saveUser(User user)async {
var dbClient = await db;
int res = await dbClient.insert("User", user.toMap());
return res;
}
// deleting data
Future<int> deleteUser(User user)async {
var dbClient = await db;
int res = await dbClient.delete("User");
return res;
}
}
这是登录演示者
abstract class LoginPageContract{
void onLoginSuccess(User user);
void onLoginError(String error);
}
class LoginPagePresenter{
LoginPageContract _view;
RestData api = new RestData();
LoginPagePresenter(this._view);
doLogin(String username,String password){
api
.login(username, password)
.then((user)=> _view.onLoginSuccess(user))
.catchError((onError)=>_view.onLoginError(onError()));
}
}
这是githublink给的代码供参考:https://github.com/meadows12/sql
请帮忙!!
您所要做的就是以 "widget.user" 而不是 "user" 的形式访问用户对象。因此,以下内容可以解决问题:
body: Center(
child: widget.user != null ? Text("Saved \n \n Username: '${widget.user.username}' ")
: Text("Not saved"),
)
代码中还有一个问题。您没有将 buildcontext 分配给变量 _ctx。因此,github 上的代码并未发生屏幕更改。我在 login.dart 中添加了一行,如下所示:
Widget build(BuildContext context) {
_ctx = context;
return _isLoading ? Loading() :Scaffold(______________
结果: