单击按钮后如何获取数据?
How I can fetch the data after button click in flutter?
我是新手,正在制作一个爱情计算器。但我正在从 api 获取数据并在后端计算它。但是我无法通过单击按钮来完成。请帮助我这样做。
import 'dart:io';
import 'package:AllInOneCalci/CustomTextField.dart';
import 'package:AllInOneCalci/Post.dart';
import 'package:AllInOneCalci/customAppBar.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'dart:async';
class LoveCalUI extends StatelessWidget {
@override
Widget build(BuildContext context) {
var AppBarHeight = MediaQuery.of(context).size.height;
return Scaffold(
appBar: customAppBar(
height: (AppBarHeight / 3) * 0.4,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.only(top: 18.0),
child: Text(
'Love Calculator',
style: TextStyle(
color: Colors.black,
fontSize: 35.0,
fontFamily: 'DancingScript',
fontWeight: FontWeight.bold),
),
),
],
),
),
body: CustomFetchData(),
);
}
}
class CustomFetchData extends StatefulWidget {
@override
_CustomFetchDataState createState() => _CustomFetchDataState();
}
class _CustomFetchDataState extends State<CustomFetchData> {
int percentage = 0;
String result = "";
TextEditingController firstNameController = new TextEditingController();
TextEditingController secondNameController = new TextEditingController();
Future<Post> _getData({String name1, String name2}) async {
final response = await http.get(
'https://love-calculator.p.rapidapi.com/getPercentage?fname=$name1&sname=$name2',
headers: {
'x-rapidapi-host': 'love-calculator.p.rapidapi.com',
'x-rapidapi-key':
'84e84770b9msh59a96d8b03cb4aap1615a1jsn1cd0efaeedfe',
});
if (response.statusCode == 200) {
final responseJson = json.decode(response.body);
setState(() {
percentage = int.parse(responseJson['percentage']);
result = responseJson['result'];
});
} else {
throw Exception('Failed to load api');
}
}
Widget ErrorDesign() {
return Padding(
padding: const EdgeInsets.all(20.0),
child: Container(
alignment: Alignment.center,
child: Text(
'Error: Kindly Connect to Internet',
style: TextStyle(
color: Colors.redAccent,
fontFamily: 'DancingScript',
fontSize: 40.0,
fontWeight: FontWeight.bold,
),
),
),
);
}
Widget FetchedCalculationValues() {
return Column(
children: [
Container(
child: FutureBuilder<Post>(
future: _getData(),
builder: (BuildContext context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(
child: Padding(
padding: const EdgeInsets.all(20.0),
child: CircularProgressIndicator(),
),
);
} else {
if (snapshot.hasError) {
return Container(
child: ErrorDesign(),
);
} else {
return Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
children: [
Text('Percentage is $percentage %',
style: TextStyle(
color: Colors.black,
)),
Text('Result is: $result',
style: TextStyle(
color: Colors.black,
)),
],
),
);
}
}
})),
],
);
}
@override
Widget build(BuildContext context) {
bool visibilitySwitch = false;
return SingleChildScrollView(
child: Column(
children: [
Padding(
padding: const EdgeInsets.only(left: 18.0, right: 18.0, top: 15.0),
child: CustomTextField('First Name', "", Colors.cyan, Colors.cyan,
Colors.redAccent, firstNameController, firstNameController),
),
Padding(
padding: const EdgeInsets.only(left: 18.0, right: 18.0),
child: CustomTextField(
'Second Name',
"",
Colors.red,
Colors.redAccent,
Colors.cyanAccent,
secondNameController,
secondNameController),
),
Padding(
padding: const EdgeInsets.all(18.0),
child: MaterialButton(
color: Colors.redAccent,
child: Text(
'Result',
style: TextStyle(
color: Colors.white,
),
),
onPressed: () {
_getData(
name1: firstNameController.text,
name2: secondNameController.text,
);
}),
),
Text(
'Your Score Is: $percentage%',
style: TextStyle(
color: Colors.redAccent,
fontSize: 25.0,
fontWeight: FontWeight.bold,
),
),
Padding(
padding: const EdgeInsets.all(18.0),
child: Text(
'$result',
style: TextStyle(
color: Colors.redAccent,
fontFamily: 'DancingScript',
fontSize: 30.0,
fontWeight: FontWeight.bold,
),
),
),
],
),
);
}
@override
// ignore: must_call_super
void initState() {
_getData();
}
}
我只想在单击“结果”按钮后调用 FetchedCalculationValues(),但我无法这样做,因为 circularProgressIndicator 仅加载而不显示数据。
显示了数据,但存在一些错误:默认情况下它显示 16% 和结果而无需输入单个输入。
请帮助我,这样每当我单击“结果”按钮时,我都会得到一个 curcularProgressIndicator,然后是实际结果,每当我输入数据时,它应该隐藏之前显示的结果。
谢谢:}
在onPressed()
中,等待未来完成。
onPressed: () async{
await _getData(
name1:firstNameController.text,
name2:secondNameController.text,
);
}
要显示加载指示器,
创建一个显示指标的函数。
showAlertDialog(BuildContext context){
AlertDialog alert=AlertDialog(
content: new Row(
children: [
CircularProgressIndicator(),
Container(margin: EdgeInsets.only(left: 5),child:Text("Loading" )),
],),
);
showDialog(barrierDismissible: false,
context:context,
builder:(BuildContext context){
return alert;
},
);
}
现在,在里面调用它onPressed()
onPressed: () async{
showAlertDialog(context);
await _getData(
name1:firstNameController.text,
name2:secondNameController.text);
Navigator.pop(context)//popping the dialog after data is fetched
}
更新
这样做,
创建一个基于条件的函数 returns 文本小部件。
bool isLoaded=false;
_getText(){
if(isLoaded){
return Text("your percentage is..$percentage");
}else{
return Container ();// an empty container.
}
}
现在,在您的 onPressed
中,当您从 API 获取数据时设置 isLoaded=true
。
onPressed: () async{
showAlertDialog(context);
await _getData(
name1:firstNameController.text,
name2:secondNameController.text);
Navigator.pop(context)//popping the dialog after data is fetched
setState((){
isLoaded=true;
});
我是新手,正在制作一个爱情计算器。但我正在从 api 获取数据并在后端计算它。但是我无法通过单击按钮来完成。请帮助我这样做。
import 'dart:io';
import 'package:AllInOneCalci/CustomTextField.dart';
import 'package:AllInOneCalci/Post.dart';
import 'package:AllInOneCalci/customAppBar.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'dart:async';
class LoveCalUI extends StatelessWidget {
@override
Widget build(BuildContext context) {
var AppBarHeight = MediaQuery.of(context).size.height;
return Scaffold(
appBar: customAppBar(
height: (AppBarHeight / 3) * 0.4,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.only(top: 18.0),
child: Text(
'Love Calculator',
style: TextStyle(
color: Colors.black,
fontSize: 35.0,
fontFamily: 'DancingScript',
fontWeight: FontWeight.bold),
),
),
],
),
),
body: CustomFetchData(),
);
}
}
class CustomFetchData extends StatefulWidget {
@override
_CustomFetchDataState createState() => _CustomFetchDataState();
}
class _CustomFetchDataState extends State<CustomFetchData> {
int percentage = 0;
String result = "";
TextEditingController firstNameController = new TextEditingController();
TextEditingController secondNameController = new TextEditingController();
Future<Post> _getData({String name1, String name2}) async {
final response = await http.get(
'https://love-calculator.p.rapidapi.com/getPercentage?fname=$name1&sname=$name2',
headers: {
'x-rapidapi-host': 'love-calculator.p.rapidapi.com',
'x-rapidapi-key':
'84e84770b9msh59a96d8b03cb4aap1615a1jsn1cd0efaeedfe',
});
if (response.statusCode == 200) {
final responseJson = json.decode(response.body);
setState(() {
percentage = int.parse(responseJson['percentage']);
result = responseJson['result'];
});
} else {
throw Exception('Failed to load api');
}
}
Widget ErrorDesign() {
return Padding(
padding: const EdgeInsets.all(20.0),
child: Container(
alignment: Alignment.center,
child: Text(
'Error: Kindly Connect to Internet',
style: TextStyle(
color: Colors.redAccent,
fontFamily: 'DancingScript',
fontSize: 40.0,
fontWeight: FontWeight.bold,
),
),
),
);
}
Widget FetchedCalculationValues() {
return Column(
children: [
Container(
child: FutureBuilder<Post>(
future: _getData(),
builder: (BuildContext context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(
child: Padding(
padding: const EdgeInsets.all(20.0),
child: CircularProgressIndicator(),
),
);
} else {
if (snapshot.hasError) {
return Container(
child: ErrorDesign(),
);
} else {
return Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
children: [
Text('Percentage is $percentage %',
style: TextStyle(
color: Colors.black,
)),
Text('Result is: $result',
style: TextStyle(
color: Colors.black,
)),
],
),
);
}
}
})),
],
);
}
@override
Widget build(BuildContext context) {
bool visibilitySwitch = false;
return SingleChildScrollView(
child: Column(
children: [
Padding(
padding: const EdgeInsets.only(left: 18.0, right: 18.0, top: 15.0),
child: CustomTextField('First Name', "", Colors.cyan, Colors.cyan,
Colors.redAccent, firstNameController, firstNameController),
),
Padding(
padding: const EdgeInsets.only(left: 18.0, right: 18.0),
child: CustomTextField(
'Second Name',
"",
Colors.red,
Colors.redAccent,
Colors.cyanAccent,
secondNameController,
secondNameController),
),
Padding(
padding: const EdgeInsets.all(18.0),
child: MaterialButton(
color: Colors.redAccent,
child: Text(
'Result',
style: TextStyle(
color: Colors.white,
),
),
onPressed: () {
_getData(
name1: firstNameController.text,
name2: secondNameController.text,
);
}),
),
Text(
'Your Score Is: $percentage%',
style: TextStyle(
color: Colors.redAccent,
fontSize: 25.0,
fontWeight: FontWeight.bold,
),
),
Padding(
padding: const EdgeInsets.all(18.0),
child: Text(
'$result',
style: TextStyle(
color: Colors.redAccent,
fontFamily: 'DancingScript',
fontSize: 30.0,
fontWeight: FontWeight.bold,
),
),
),
],
),
);
}
@override
// ignore: must_call_super
void initState() {
_getData();
}
}
我只想在单击“结果”按钮后调用 FetchedCalculationValues(),但我无法这样做,因为 circularProgressIndicator 仅加载而不显示数据。 显示了数据,但存在一些错误:默认情况下它显示 16% 和结果而无需输入单个输入。
请帮助我,这样每当我单击“结果”按钮时,我都会得到一个 curcularProgressIndicator,然后是实际结果,每当我输入数据时,它应该隐藏之前显示的结果。 谢谢:}
在onPressed()
中,等待未来完成。
onPressed: () async{
await _getData(
name1:firstNameController.text,
name2:secondNameController.text,
);
}
要显示加载指示器,
创建一个显示指标的函数。
showAlertDialog(BuildContext context){
AlertDialog alert=AlertDialog(
content: new Row(
children: [
CircularProgressIndicator(),
Container(margin: EdgeInsets.only(left: 5),child:Text("Loading" )),
],),
);
showDialog(barrierDismissible: false,
context:context,
builder:(BuildContext context){
return alert;
},
);
}
现在,在里面调用它onPressed()
onPressed: () async{
showAlertDialog(context);
await _getData(
name1:firstNameController.text,
name2:secondNameController.text);
Navigator.pop(context)//popping the dialog after data is fetched
}
更新
这样做,
创建一个基于条件的函数 returns 文本小部件。
bool isLoaded=false;
_getText(){
if(isLoaded){
return Text("your percentage is..$percentage");
}else{
return Container ();// an empty container.
}
}
现在,在您的 onPressed
中,当您从 API 获取数据时设置 isLoaded=true
。
onPressed: () async{
showAlertDialog(context);
await _getData(
name1:firstNameController.text,
name2:secondNameController.text);
Navigator.pop(context)//popping the dialog after data is fetched
setState((){
isLoaded=true;
});