Как отобразить извлеченные данные из api при нажатии кнопки в flutter?

#android #api #flutter #flutter-layout #flutter-test

#Android #API #flutter #flutter-layout #flutter-тест

Вопрос:

Я хочу показать полученные данные love calculator после нажатия кнопки, но как их отобразить? Пожалуйста, ответьте

 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(
                'All In One Cali',
                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> {
  TextEditingController firstNameController = new TextEditingController();
  TextEditingController secondNameController = new TextEditingController();

  Future<Post> getData() async {
    final response = await http.get(
        'https://love-calculator.p.rapidapi.com/getPercentage?fname=aaliaamp;sname=Alice',
        headers: {
          'x-rapidapi-host': 'love-calculator.p.rapidapi.com',
          'x-rapidapi-key':
              '84e84770b9msh59a96d8b03cb4aap1615a1jsn1cd0ef******',
        });

    if (response.statusCode == 200) {
      return Post.fromJson(json.decode(response.body));
    } 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 DisplayData(String percentageValue, String result) {
    return Padding(
      padding: const EdgeInsets.all(20.0),
      child: Container(
        height: 100.0,
        color: Colors.black,
        child: Column(
          children: [
            Text('Percentage is $percentageValue',
                style: TextStyle(
                  color: Colors.white,
                )),
            Text('Result is: $result',
                style: TextStyle(
                  color: Colors.white,
                )),
          ],
        ),
      ),
    );
  }

  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 DisplayData(
                          snapshot.data.percentage, snapshot.data.result);
                    }
                  }
                })),
      ],
    );
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Padding(
          padding: const EdgeInsets.only(left: 18.0, right: 18.0, top: 15.0),
          child: CustomTextField('First Name', "", Colors.cyan,
              Colors.cyanAccent, Colors.redAccent, firstNameController),
        ),
        Padding(
          padding: const EdgeInsets.only(left: 18.0, right: 18.0),
          child: CustomTextField('Second Name', "", Colors.red,
              Colors.redAccent, Colors.cyanAccent, secondNameController),
        ),
        Padding(
          padding: const EdgeInsets.all(18.0),
          child: MaterialButton(
              color: Colors.redAccent,
              child: Text(
                'Result',
                style: TextStyle(
                  color: Colors.white,
                ),
              ),
              onPressed: () {
                FetchedCalculationValues();
                print('Fetch Calling');
              }),
        ),
        Visibility(
          visible: false,
          child: FetchedCalculationValues(),
          ),
      ],
    );
  }

  @override
  // ignore: must_call_super
  void initState() {
    getData();
  }
}

  

Как сделать функцию для вызова api видимой на экране после нажатия кнопки.
Также я хочу использовать значения текстового поля вместо значений по умолчанию
Можете ли вы решить мою проблему? Это будет очень полезно, если вы это сделаете. Я новичок и изучаю flutter с 15 дней. Помогите мне, чтобы я мог быстро это изучить. Кроме того, сообщество flutter быстро растет, поэтому мне будет легко не ждать ответа. Спасибо.

Ответ №1:

Я создал упрощенное приложение для одного экрана без каких-либо дополнительных возможностей, чтобы решить именно вашу проблему. Он содержит два текстовых поля, два текстовых виджета для отображения результатов API и плавающую кнопку действия для отправки запроса.

Скриншот

Ключевыми понятиями, которые вы должны знать для создания этого кода, являются http-запросы и асинхронное кодирование. Эти ссылки являются хорошей отправной точкой для вас, чтобы получить представление о том, что на самом деле происходит

Подводя итог, что именно вам нужно:

  1. Вы отправляете запрос асинхронно в функцию объявления API с async ключевым словом и await ключевым словом перед http.get() функцией. Это позволяет вам дождаться результата запроса без замораживания приложения

  2. Когда результат возвращается, выполняется остальная _getNames() функция, которая включает setState() . setState() перестраивает ваш виджет и обновляет значения в Text() виджетах

Полный код:

 import 'package:flutter/material.dart';
import 'dart:convert';
import 'package:http/http.dart' as http;

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: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int percentage = 0;
  String resultString = "";

  Map<String, String> requestHeaders = {
    'x-rapidapi-host': 'love-calculator.p.rapidapi.com',
    'x-rapidapi-key': 'your API key',
  };

  final name1Controller = TextEditingController();
  final name2Controller = TextEditingController();

  void _getNames({String name1, String name2}) async {
    final response = await http.get(
      'https://love-calculator.p.rapidapi.com/getPercentage?fname=$name1amp;sname=$name2',
      // Send authorization headers to the backend.
      headers: requestHeaders,
    );

    final responseJson = json.decode(response.body);

    setState(() {
      percentage = int.parse(responseJson['percentage']);
      resultString = responseJson['result'];
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            TextField(
              controller: name1Controller,
              decoration: InputDecoration(
                hintText: "name 1",
              ),
            ),
            TextField(
              controller: name2Controller,
              decoration: InputDecoration(
                hintText: "name 2",
              ),
            ),
            SizedBox(
              height: 10,
            ),
            Text(
              'Your Score is: $percentage',
            ),
            Text(
              '$resultString',
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          _getNames(
            name1: name1Controller.text,
            name2: name2Controller.text,
          );
        },
        tooltip: 'Increment',
        child: Text('Go'),
      ),
    );
  }
}