виджеты не восстанавливаются после вызова api в flutter

#flutter #flutter-layout #flutter-dependencies #flutter-android

Вопрос:

Посмотрите это видео, чтобы правильно понять проблему.

Когда я создаю проект, виджеты не отображаются, но когда я повторно сохраняю проект, виджеты отображаются. Я даю свой код ниже.

  • главная.дротик :-

(это основной файл, в котором хранятся маршруты к каждой странице)

 import 'package:flutter/material.dart';
import 'package:player_profile/first.dart';
import 'package:player_profile/second.dart';
import 'package:player_profile/third.dart';

void main() {
  runApp(MaterialApp(
    initialRoute: '/first',
    routes: {
      '/first': (context) => First(),
      '/second': (context) => Second(),
      '/third': (context) => Third()
    },
  ));
}
 
  • первый.дротик :-

(это первая страница приложения, которая содержит список виджетов всех данных команды. после нажатия на виджет команды он перейдет на вторую страницу)

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

class First extends StatefulWidget {
  @override
  _FirstState createState() => _FirstState();
}

class _FirstState extends State<First> {
  List<Widget> teamList = [];

  void getTeamList() async {
    var url = Uri.parse('https://www.balldontlie.io/api/v1/teams');
    http.Response response = await http.get(url);
    if (response.statusCode == 200) {
      var jsonData = convert.jsonDecode(response.body) as Map<String, dynamic>;

      if (jsonData['data'] != null) {
        jsonData['data'].forEach((v) {
          // teamData.add(new TeamData.fromJson(v));
          teamList.add(Padding(
            padding: const EdgeInsets.all(8.0),
            // ignore: deprecated_member_use
            child: RaisedButton(
                onPressed: () {
                  Navigator.pushNamed(context, '/second');
                },
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  crossAxisAlignment: CrossAxisAlignment.center,
                  children: [
                    Text(
                      'Name : ${TeamData.fromJson(v).name}',
                      style: TextStyle(
                        color: Colors.red,
                        fontSize: 15.0,
                      ),
                    ),
                    Text(
                      'Abbreviation : ${TeamData.fromJson(v).abbreviation}',
                      style: TextStyle(
                        color: Colors.blue,
                        fontSize: 15.0,
                      ),
                    ),
                    Text(
                      'City : ${TeamData.fromJson(v).city}',
                      style: TextStyle(
                        color: Colors.blue,
                        fontSize: 15.0,
                      ),
                    ),
                    Text(
                      'Conference : ${TeamData.fromJson(v).conference}',
                      style: TextStyle(
                        color: Colors.blue,
                        fontSize: 15.0,
                      ),
                    ),
                    Text(
                      'Division : ${TeamData.fromJson(v).division}',
                      style: TextStyle(
                        color: Colors.blue,
                        fontSize: 15.0,
                      ),
                    )
                  ],
                )),
          ));
        });
      }
    }
  }

  @override
  void initState() {
    super.initState();
    getTeamList();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        backgroundColor: Colors.black,
        appBar: AppBar(
          title: Text('Team'),
        ),
        body: GridView.count(
          crossAxisCount: 2,
          children: teamList,
        ));
  }
}
 
  • второй.дротик :-

(это вторая страница приложения, которая содержит все виджеты сведений об игроке, полученные от http-вызова. он получает данные с http, но виджеты не отображаются. виджеты отображаются только после повторного сохранения проекта. после setState() это не повторное создание страницы.)

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

class Second extends StatefulWidget {
  @override
  _SecondState createState() => _SecondState();
}

class _SecondState extends State<Second> {
  List<SinglePlayerData> playersList = [];
  List<Widget> showPlayers = [];

  getAllPlayers() async {
    var url = Uri.parse('https://www.balldontlie.io/api/v1/players');
    http.Response response = await http.get(url);
    if (response.statusCode == 200) {
      var jsonData = convert.jsonDecode(response.body) as Map<String, dynamic>;

      jsonData['data'].forEach((v) {
        SinglePlayerData playerData = SinglePlayerData(
            v['id'],
            v['first_name'],
            v['height_feet'],
            v['height_inches'],
            v['last_name'],
            v['position'],
            v['weight_pounds'],
            v['team']['id'],
            v['team']['abbreviation'],
            v['team']['city'],
            v['team']['conference'],
            v['team']['division'],
            v['team']['full_name'],
            v['team']['name']);
        playersList.add(playerData);
        setState(() {
          print('setState');
          showPlayers.add(Padding(
            padding: const EdgeInsets.all(8.0),
            // ignore: deprecated_member_use
            child: RaisedButton(
                onPressed: () {
                  Navigator.pushNamed(context, '/third',
                      arguments: {'data': playerData});
                },
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  crossAxisAlignment: CrossAxisAlignment.center,
                  children: [
                    Container(
                        height: 75.0,
                        width: 75.0,
                        child: Image(image: AssetImage('images/player2.png'))),
                    Padding(
                      padding: const EdgeInsets.all(5.0),
                      child: Text(
                        'Name : ${playerData.firstName} ${playerData.lastName}',
                        style: TextStyle(fontSize: 15.0, color: Colors.red),
                      ),
                    ),
                    Text(
                      'Team : ${playerData.name}',
                      style: TextStyle(fontSize: 15.0, color: Colors.blue),
                    ),
                    Padding(
                      padding: const EdgeInsets.all(5.0),
                      child: Text(
                        'Position : ${playerData.position}',
                        style: TextStyle(fontSize: 15.0, color: Colors.purple),
                      ),
                    )
                  ],
                )),
          ));
        });
      });
      print(playersList[1].firstName);
    }
  }

  @override
  void initState() {
    print('initState');
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    print('build');
    getAllPlayers();
    return Scaffold(
        backgroundColor: Colors.black,
        appBar: AppBar(
          title: Text('Players'),
        ),
        body: GridView.count(
          crossAxisCount: 2,
          children: showPlayers,
        ));
  }
}
 
  • teamData.dart (Model class) :-

    (this is the model class for team data)

      class TeamData {
       int? id;
       String? abbreviation;
       String? city;
       String? conference;
       String? division;
       String? fullName;
       String? name;
    
       TeamData(this.id, this.abbreviation, this.city, this.conference,
           this.division, this.fullName, this.name);
    
       TeamData.fromJson(Map<String, dynamic> json)
           : id = json['id'],
             abbreviation = json['abbreviation'],
             city = json['city'],
             conference = json['conference'],
             division = json['division'],
             fullName = json['full_name'],
             name = json['name'];
    
       Map<String, dynamic> toJson() {
         final Map<String, dynamic> data = new Map<String, dynamic>();
         data['id'] = this.id;
         data['abbreviation'] = this.abbreviation;
         data['city'] = this.city;
         data['conference'] = this.conference;
         data['division'] = this.division;
         data['full_name'] = this.fullName;
         data['name'] = this.name;
         return data;
       }
     }
     
  • одиночная игра.дротик (класс модели) :-

(это класс модели для подробных данных игроков)

 class TeamData {
  int? id;
  String? abbreviation;
  String? city;
  String? conference;
  String? division;
  String? fullName;
  String? name;

  TeamData(this.id, this.abbreviation, this.city, this.conference,
      this.division, this.fullName, this.name);

  TeamData.fromJson(Map<String, dynamic> json)
      : id = json['id'],
        abbreviation = json['abbreviation'],
        city = json['city'],
        conference = json['conference'],
        division = json['division'],
        fullName = json['full_name'],
        name = json['name'];

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['id'] = this.id;
    data['abbreviation'] = this.abbreviation;
    data['city'] = this.city;
    data['conference'] = this.conference;
    data['division'] = this.division;
    data['full_name'] = this.fullName;
    data['name'] = this.name;
    return data;
  }
}
 

Ответ №1:

Используйте FutureBuilder , когда захотите что-нибудь принести на будущее.

 
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.cyan,
      body: FutureBuilder<Transaction>(
        future: getAllPlayers(),
        builder: (context, snapshot) {
          if (snapshot.connectionState == ConnectionState.waiting)
            return CircularProgressIndicator();
          if (snapshot.hasError)
            return Column(
              children: [
                Text(
                  snapshot.error.toString(),
                ),
              ],
            );
          if (snapshot.hasData) {
            var data = snapshot.data!;
            ///todo:: add you design model
            return GridView.count(
          crossAxisCount: 2,
          children: showPlayers,
        );
          }
          return Text('Something was wrong!');
        },
      ),
    );
  }
 

дайте мне знать, если это решит вашу проблему.

Ответ №2:

Я думаю, тебе просто нужно позвонить setState((){}); в конце getTeamList()