如何在 Flutter 中的 onPresseed 按钮后获得 JSON 响应 // Dart
How to get JSON response after onPresseed button in Flutter // Dart
我在获取 JSON 数据时没有遇到任何问题按下按钮获取 JSON response.body 打印成功但 JSON 响应在我给 _addressController 值执行 if 条件之前执行,因此异常显示在打印状态上。所以请查看我的代码并帮助我解决问题
import 'package:flutter/material.dart';
import 'dart:async';
import 'dart:core';
import 'dart:convert';
import 'package:http/http.dart'as http;
import 'string.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return const MaterialApp(
title: 'Retrieve Text Input',
home: MyCustomForm(),
);
}
}
class MyCustomForm extends StatefulWidget {
const MyCustomForm({Key? key}) : super(key: key);
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyCustomForm> {
final _formKey = GlobalKey<FormState>();
var url1 = 'This is my first off url';
var _addressControler = TextEditingController();
late Future<Balance> futureBalance;
@override
void initState() {
super.initState();
futureBalance = fetchBalance();
}
Future<Balance> fetchBalance() async {
http.Response response =
await http.get(Uri.parse(url1+_addressControler.text));
print(response.body);
if (response.statusCode == 200) {
return Balance.fromJson(jsonDecode(response.body));
} else {
throw Exception('Failed to load album');
}
}
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Fetch Data Example',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
appBar: AppBar(
title: Text('Fetch Data Example'),
),
body: Center(
key: _formKey,
child: Column(
children: [
Padding(
padding: const EdgeInsets.all(10.0),
child: TextField(
controller: _addressControler,
decoration: InputDecoration(
labelText: 'Enter the address...',
labelStyle: TextStyle(color: Colors.blue),
border: new OutlineInputBorder(
borderSide: new BorderSide(color: Colors.black)),),
),
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 16.0),
child: ElevatedButton(
onPressed: () async {
await fetchBalance();
},
child: const Text('Submit'),
),
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 16.0),
child: Text("${_addressControler.text}"),
),
Container(
//color: Colors.blueAccent,
child: FutureBuilder<Balance>(
future: futureBalance,
builder: (context, index) {
if (index.hasData) {
print(index.data!.height);
var x = (index.data!.result[0].amount);
var y = int.parse(x);
assert(y is int);
var z = (y / 1000000);
print(z);
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('${z.toString()}',
style: TextStyle(fontSize: 20,),),
]);
} else if (index.hasError) {
return Text("${index.error}");
}
return CircularProgressIndicator();
},
),
),
]
),
),
)
);
}
}
我对 fetchBalance() 函数有疑问。 if 条件在我单击 onPressed 按钮之前执行,但是 我在给定 TextField 并提交 onPressed 后执行条件。那么,有没有什么办法可以解决这个问题,请帮助我...
我不确定我是否理解您的问题,但您似乎遇到了错误,因为 fetchBalance
在您预期之前执行了。
好吧,您在 initState()
方法中调用了 futureBalance = fetchBalance();
,因此代码会在您的小部件初始化时执行,而不仅仅是在您按下按钮后执行。这意味着,您尝试在不附加 _addressControler.text
.
的情况下解析 url
另外,你也可以这样使用
fetchBalance().then((balance) {
setState(() {
_balance = balance; //need to create one variable of type Balance
});
});
最好将 setState() 放在异步调用中:
Future<Balance> fetchBalance() async {
http.Response response =
await http.get(Uri.parse(url1+_addressControler.text));
print(response.body);
if (response.statusCode == 200) {
setState(() {
_balance = Balance.fromJson(jsonDecode(response.body));
});
} else {
throw Exception('Failed to load album');
}
}
首先,我删除了 initState()
,然后我使用 setState()
作为 onPressed()
来调用 API 函数 fetchBalance()
在它运行良好的状态下..
child: ElevatedButton(
onPressed: () {
setState(() {
fetchBalance();
});
fetchBalance();
},
child: const Text('Submit'),
),
),
我在获取 JSON 数据时没有遇到任何问题按下按钮获取 JSON response.body 打印成功但 JSON 响应在我给 _addressController 值执行 if 条件之前执行,因此异常显示在打印状态上。所以请查看我的代码并帮助我解决问题
import 'package:flutter/material.dart';
import 'dart:async';
import 'dart:core';
import 'dart:convert';
import 'package:http/http.dart'as http;
import 'string.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return const MaterialApp(
title: 'Retrieve Text Input',
home: MyCustomForm(),
);
}
}
class MyCustomForm extends StatefulWidget {
const MyCustomForm({Key? key}) : super(key: key);
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyCustomForm> {
final _formKey = GlobalKey<FormState>();
var url1 = 'This is my first off url';
var _addressControler = TextEditingController();
late Future<Balance> futureBalance;
@override
void initState() {
super.initState();
futureBalance = fetchBalance();
}
Future<Balance> fetchBalance() async {
http.Response response =
await http.get(Uri.parse(url1+_addressControler.text));
print(response.body);
if (response.statusCode == 200) {
return Balance.fromJson(jsonDecode(response.body));
} else {
throw Exception('Failed to load album');
}
}
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Fetch Data Example',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
appBar: AppBar(
title: Text('Fetch Data Example'),
),
body: Center(
key: _formKey,
child: Column(
children: [
Padding(
padding: const EdgeInsets.all(10.0),
child: TextField(
controller: _addressControler,
decoration: InputDecoration(
labelText: 'Enter the address...',
labelStyle: TextStyle(color: Colors.blue),
border: new OutlineInputBorder(
borderSide: new BorderSide(color: Colors.black)),),
),
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 16.0),
child: ElevatedButton(
onPressed: () async {
await fetchBalance();
},
child: const Text('Submit'),
),
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 16.0),
child: Text("${_addressControler.text}"),
),
Container(
//color: Colors.blueAccent,
child: FutureBuilder<Balance>(
future: futureBalance,
builder: (context, index) {
if (index.hasData) {
print(index.data!.height);
var x = (index.data!.result[0].amount);
var y = int.parse(x);
assert(y is int);
var z = (y / 1000000);
print(z);
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('${z.toString()}',
style: TextStyle(fontSize: 20,),),
]);
} else if (index.hasError) {
return Text("${index.error}");
}
return CircularProgressIndicator();
},
),
),
]
),
),
)
);
}
}
我对 fetchBalance() 函数有疑问。 if 条件在我单击 onPressed 按钮之前执行,但是 我在给定 TextField 并提交 onPressed 后执行条件。那么,有没有什么办法可以解决这个问题,请帮助我...
我不确定我是否理解您的问题,但您似乎遇到了错误,因为 fetchBalance
在您预期之前执行了。
好吧,您在 initState()
方法中调用了 futureBalance = fetchBalance();
,因此代码会在您的小部件初始化时执行,而不仅仅是在您按下按钮后执行。这意味着,您尝试在不附加 _addressControler.text
.
另外,你也可以这样使用
fetchBalance().then((balance) {
setState(() {
_balance = balance; //need to create one variable of type Balance
});
});
最好将 setState() 放在异步调用中:
Future<Balance> fetchBalance() async {
http.Response response =
await http.get(Uri.parse(url1+_addressControler.text));
print(response.body);
if (response.statusCode == 200) {
setState(() {
_balance = Balance.fromJson(jsonDecode(response.body));
});
} else {
throw Exception('Failed to load album');
}
}
首先,我删除了 initState()
,然后我使用 setState()
作为 onPressed()
来调用 API 函数 fetchBalance()
在它运行良好的状态下..
child: ElevatedButton(
onPressed: () {
setState(() {
fetchBalance();
});
fetchBalance();
},
child: const Text('Submit'),
),
),