gpt4 book ai didi

sqlite - Flutter FutureBuilder未使用sqlite的数据进行构建

转载 作者:行者123 更新时间:2023-12-03 03:53:59 25 4
gpt4 key购买 nike

我是个新手,正在尝试编写可从sqlite获取值(value)的应用程序。根据我的尝试,它需要使用FutureBuilder小部件。

但是我写的以下代码,FutureBuilder小部件似乎是从sqlite获取数据的,但是从未调用过“builder”属性:

import 'package:flutter/material.dart';
import 'package:flutter_spinkit/flutter_spinkit.dart';
import 'package:flutterapp/dbHelper.dart';

void main() {
runApp(MyApp());
}

class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
routes:{
"/": (context) =>Test()
}
);
}
}

class Test extends StatefulWidget {
@override
_TestState createState() => _TestState();
}

class _TestState extends State<Test> {

bool nameCheck = false; // Use to check name textfield has correctly be inputed
TextEditingController nameController = TextEditingController();

@override
Widget build(BuildContext context) {
return Scaffold(
body:Column(
children: <Widget>[
SizedBox(height:300),
Row(
children: <Widget>[
Expanded(
child: TextField(
controller: nameController,
)
),
IconButton(
icon: Icon(Icons.check_circle),
onPressed:(){
return FutureBuilder(
future: getData(nameController.text),
builder: (BuildContext context, AsyncSnapshot<List<Map>>snapshot) {
print("Start future"); // never get printed
List<Widget> children;
if (snapshot.hasData) {
children = <Widget>[
Builder(
builder: (BuildContext context) {
print("got data");
final result = snapshot.data;
print(result) ; // never get printed
setState(() {
nameCheck = true;
});
return Container();
})
];
} else {
children = <Widget>[
AlertDialog(
content: SpinKitCircle(
color: Colors.white,
size: 80.0,
))
];
}
return Center(
child: Container(
color: Colors.blue,
child: Column(
mainAxisAlignment:
MainAxisAlignment
.center,
crossAxisAlignment:
CrossAxisAlignment
.center,
children: children,
)));
});}
)
],
),
Builder(
builder: (BuildContext context){
if (nameCheck == true){
return Text("test");
}
return Container();
}
)
],
)
);
}
}

Future<List<Map>> getData(String input_name) async{
final dbHelper = DBHelper.instance;
await dbHelper.database;
final result = await dbHelper.query("SELECT * FROM Guest WHERE Name = \"$input_name\"");
print(result); // This get printed
return result;
}

DBHelper代码如下,基本上它只是建立一个sqlite数据库和一些数据库操作:
import 'package:sqflite/sqflite.dart';
import 'package:path/path.dart';
import 'dart:io';
import 'package:path_provider/path_provider.dart';

class DBHelper {
static final _databaseName = "MonetaryDB.db";
static final _databaseVersion = 1;

static final create_table_Test = "CREATE TABLE \"Guest\" (\"Name\" TEXT NOT NULL PRIMARY KEY, \"Money\" INTEGER, \"Person\" INTEGER)";

static final String insert_guest = "INSERT INTO Guest (Name, Money, Person) VALUES (\"testname\", 1000, 1)";

DBHelper._privateConstructor();

static final DBHelper instance = DBHelper._privateConstructor();

static Database _database;
Future<Database> get database async {
if (_database != null) {
return _database;}
else{
_database = await _initDatabase();
return _database;}
}

_initDatabase() async {
Directory documentsDirectory = await getApplicationDocumentsDirectory();
String path = join(documentsDirectory.path, _databaseName);
return await openDatabase(path,
version: _databaseVersion,
onCreate: _onCreate,
);
}

Future _onCreate(Database db, int version) async {
await db.execute(create_table_Test);
await db.rawInsert(insert_guest);
}

Future<int> insert(String statement) async {
Database db = await instance.database;
return await db.rawInsert(statement);
}

Future<List<Map>> query(String statement) async {
Database db = await instance.database;
return await db.rawQuery(statement);
}

Future<int> update(String statement) async{
Database db = await instance.database;
return await db.rawUpdate(statement);
}

Future<int> delete(String statement) async{
Database db = await instance.database;
return db.rawDelete(statement);
}
}

如果仅将IconButton onPressed函数更改为 setState((){nameCheck = true}),将显示 Text("test")小部件,因此问题一定是FutureBuilder。另外,getData()函数可以从sqlite数据库获取正确的结果

我不知道为什么FutureBuilder无法构建,有人对此有任何想法吗?
谢谢!

最佳答案

因此,在注释部分的帮助下,我更改了代码,它可以正常工作:

...
Widget build(BuildContext context) {
return Scaffold(
body:Column(
children: <Widget>[
SizedBox(height:300),
Row(
children: <Widget>[
Expanded(
child: TextField(
controller: nameController,
)
),
IconButton(
icon: Icon(Icons.check_circle),
onPressed:(){
return showDialog(
context: context,
builder: (BuildContext context){
return AlertDialog(
actions: <Widget>[
SizedBox(
width: 300,
height: 300,
child: FutureBuilder(
future: getData(nameController.text),
builder: (BuildContext context, AsyncSnapshot<List<Map>>snapshot) {
if (snapshot.hasData) {
final result = snapshot.data;
SchedulerBinding.instance.addPostFrameCallback((_) => setState(() {
nameCheck = true;
}));
Navigator.pop(context, true);
}
else {
return Container(
child: SpinKitCircle(
color: Colors.white,
size: 80.0,
));
}
return Container(color: Colors.blue);
})
),
],
);
}
);
}
)
],
),
Builder(
builder: (BuildContext context){
if (nameCheck == true){
return Text("test");
}
return Container();
}
)
],
)
);
}
...

其他代码仍然相同。

就像上面的评论部分所建议的那样,主要问题是将没有地方要为FutureBuilder构建小部件。为了解决此问题,我将FutureBuilder小部件放入AlertDialog小部件中,因为在加载时我仍然希望保留SpinKitCircle小部件。

我还放弃了FutureBuilder小部件末尾的Column小部件,并删除了FutureBuilder小部件开头的Builder小部件,当没有Column时不再需要。

上面的代码仍然引发可接受的异常:“在构建期间调用setState()或markNeedsBuild()”。但是整个过程仍然可以运行,因此我将在第二天尝试修复该问题。

感谢您在评论部分的建议。

关于sqlite - Flutter FutureBuilder未使用sqlite的数据进行构建,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62082567/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com