我正在尝试制作一种 Pokedex 应用程序。这个想法是所有 Pokemon(目前,前 151 个)都通过每个相应的 JSON 从这个 Api 中获取。每当我进入详细信息视图并想要返回列表时,问题就会出现,即使所有列表仍在加载,动画也如此滞后。
这是我生成 Pokemon GridView 的代码
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:pikappi/Models/pokemon.dart';
import 'package:pikappi/screens/details/details.dart';
import '../../app.dart';
class Pokedex extends StatelessWidget {
@override
Widget build(BuildContext context) {
SizeConfig().init(context);
final title = "Pokedex";
return Scaffold(
resizeToAvoidBottomInset: false,
appBar: AppBar(
title: Text(title),
),
body: GridView.count(
crossAxisCount: 3,
children: List.generate(151, (index) {
return FutureBuilder(
future: fetchPokemon(
"https://pokeapi.co/api/v2/pokemon/${index + 1}/"),
builder: (context, snapshot) {
if (snapshot.hasError) print(snapshot.error);
return snapshot.hasData
? PokedexCell(p: snapshot.data)
: Center(child: CircularProgressIndicator());
});
}),
),
);
}
}
class PokedexCell extends StatelessWidget {
final Pokemon p;
var cellColor;
PokedexCell({Key key, this.p}) : super(key: key);
@override
Widget build(BuildContext context) {
cellColor = getTypeColor(p.types[0]);
var elevatedButton = ElevatedButton(
style: ElevatedButton.styleFrom(
primary: cellColor,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(18.0))),
child: Column(
children: <Widget>[
Flexible(
flex: 1,
child: SvgPicture.network(
p.getPrettySprite,
height: SizeConfig.blockSizeVertical * 30,
width: SizeConfig.blockSizeHorizontal * 30,
),
),
Text('${p.name[0].toUpperCase()}${p.name.substring(1)}'),
],
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Details(pokemon: p, color: cellColor)));
},
);
return Center(
child: ConstrainedBox(
constraints: BoxConstraints.tightFor(
height: SizeConfig.blockSizeVertical * 33,
width: SizeConfig.blockSizeHorizontal * 33,
),
child: Padding(
padding: EdgeInsets.fromLTRB(
SizeConfig.blockSizeHorizontal * 2,
SizeConfig.blockSizeVertical * 1,
SizeConfig.blockSizeHorizontal * 2,
SizeConfig.blockSizeVertical * 1),
child: elevatedButton),
));
}
}
Pokemon.dart
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
Map<String, int> pokemonIds = {
"Bulbasaur": 1,
"Ivysaur": 2,
"Venusaur": 3,
"Charmander": 4,
"Charmeleon": 5,
"Charizard": 6,
"Squirtle": 7,
"Wartortle": 8,
"Blastoise": 9,
"Caterpie": 10,
"Metapod": 11,
"Butterfree": 12,
"Weedle": 13,
"Kakuna": 14,
"Beedrill": 15,
"Pidgey": 16,
"Pidgeotto": 17,
"Pidgeot": 18,
"Rattata": 19,
"Raticate": 20,
"Spearow": 21,
"Fearow": 22,
"Ekans": 23,
"Arbok": 24,
"Pikachu": 25,
"Raichu": 26,
"Sandshrew": 27,
"Sandslash": 28,
"Nidoran♀": 29,
"Nidorina": 30,
"Nidoqueen": 31,
"Nidoran♂": 32,
"Nidorino": 33,
"Nidoking": 34,
"Clefairy": 35,
"Clefable": 36,
"Vulpix": 37,
"Ninetales": 38,
"Jigglypuff": 39,
"Wigglytuff": 40,
"Zubat": 41,
"Golbat": 42,
"Oddish": 43,
"Gloom": 44,
"Vileplume": 45,
"Paras": 46,
"Parasect": 47,
"Venonat": 48,
"Venomoth": 49,
"Diglett": 50,
"Dugtrio": 51,
"Meowth": 52,
"Persian": 53,
"Psyduck": 54,
"Golduck": 55,
"Mankey": 56,
"Primeape": 57,
"Growlithe": 58,
"Arcanine": 59,
"Poliwag": 60,
"Poliwhirl": 61,
"Poliwrath": 62,
"Abra": 63,
"Kadabra": 64,
"Alakazam": 65,
"Machop": 66,
"Machoke": 67,
"Machamp": 68,
"Bellsprout": 69,
"Weepinbell": 70,
"Victreebel": 71,
"Tentacool": 72,
"Tentacruel": 73,
"Geodude": 74,
"Graveler": 75,
"Golem": 76,
"Ponyta": 77,
"Rapidash": 78,
"Slowpoke": 79,
"Slowbro": 80,
"Magnemite": 81,
"Magneton": 82,
"Farfetch’d": 83,
"Doduo": 84,
"Dodrio": 85,
"Seel": 86,
"Dewgong": 87,
"Grimer": 88,
"Muk": 89,
"Shellder": 90,
"Cloyster": 91,
"Gastly": 92,
"Haunter": 93,
"Gengar": 94,
"Onix": 95,
"Drowzee": 96,
"Hypno": 97,
"Krabby": 98,
"Kingler": 99,
"Voltorb": 100,
"Electrode": 101,
"Exeggcute": 102,
"Exeggutor": 103,
"Cubone": 104,
"Marowak": 105,
"Hitmonlee": 106,
"Hitmonchan": 107,
"Lickitung": 108,
"Koffing": 109,
"Weezing": 110,
"Rhyhorn": 111,
"Rhydon": 112,
"Chansey": 113,
"Tangela": 114,
"Kangaskhan": 115,
"Horsea": 116,
"Seadra": 117,
"Goldeen": 118,
"Seaking": 119,
"Staryu": 120,
"Starmie": 121,
"Mr. Mime": 122,
"Scyther": 123,
"Jynx": 124,
"Electabuzz": 125,
"Magmar": 126,
"Pinsir": 127,
"Tauros": 128,
"Magikarp": 129,
"Gyarados": 130,
"Lapras": 131,
"Ditto": 132,
"Eevee": 133,
"Vaporeon": 134,
"Jolteon": 135,
"Flareon": 136,
"Porygon": 137,
"Omanyte": 138,
"Omastar": 139,
"Kabuto": 140,
"Kabutops": 141,
"Aerodactyl": 142,
"Snorlax": 143,
"Articuno": 144,
"Zapdos": 145,
"Moltres": 146,
"Dratini": 147,
"Dragonair": 148,
"Dragonite": 149,
"Mewtwo": 150,
"Mew": 151
};
Color getTypeColor(String type) {
switch (type) {
case "fire":
{
return Colors.amber[900];
}
break;
case "grass":
{
return Colors.green;
}
break;
case "water":
{
return Colors.blue;
}
break;
case "bug":
{
return Colors.lightGreen;
}
break;
case "flying":
{
return Colors.lightBlue[100];
}
break;
case "poison":
{
return Colors.purple;
}
break;
case "rock":
{
return Colors.grey[800];
}
break;
case "steel":
{
return Colors.grey;
}
break;
case "ice":
{
return Colors.blueAccent[100];
}
break;
case "ground":
{
return Colors.brown[400];
}
break;
case "dragon":
{
return Colors.blue[900];
}
break;
case "dark":
{
return Colors.black87;
}
break;
case "ghost":
{
return Colors.grey[850];
}
break;
case "fairy":
{
return Colors.pinkAccent;
}
break;
case "psychic":
{
return Colors.pink;
}
break;
case "electric":
{
return Colors.yellow;
}
break;
case "fighting":
{
return Colors.amber;
}
break;
default:
{
return Colors.brown[100];
}
break;
}
}
enum Type {
NORMAL,
GRASS,
FIRE,
WATER,
ELECTRIC,
ICE,
FIGHTING,
POISON,
GROUND,
FLYING,
PSYCHIC,
BUG,
ROCK,
GHOST,
DRAGON,
DARK,
STEEL,
FAIRY
}
class Pokemon {
String name;
int number;
List<dynamic> types;
String sprite;
String prettySprite;
int hp;
int atk;
int def;
int spAtk;
int spDef;
int spd;
List<dynamic> abilities;
String get getName => this.name;
set setName(String name) => this.name = name;
get getNumber => this.number;
set setNumber(number) => this.number = number;
get getTypes => this.types;
set setTypes(types) => this.types = types;
set setSprite(String sprite) => this.sprite = sprite;
set setPrettySprite(String prettySprite) => this.prettySprite = prettySprite;
get getSprite => this.sprite;
get getPrettySprite => this.prettySprite;
get getHp => this.hp;
set setHp(hp) => this.hp = hp;
get getAtk => this.atk;
set setAtk(atk) => this.atk = atk;
get getDef => this.def;
set setDef(def) => this.def = def;
get getSpAtk => this.spAtk;
set setSpAtk(spAtk) => this.spAtk = spAtk;
get getSpDef => this.spDef;
set setSpDef(spDef) => this.spDef = spDef;
get getSpd => this.spd;
set setSpd(spd) => this.spd = spd;
get getabilities => this.abilities;
set setabilities(abilities) => this.abilities = abilities;
Pokemon({
this.name,
this.number,
this.types,
this.sprite,
this.prettySprite,
this.hp,
this.atk,
this.def,
this.spAtk,
this.spDef,
this.spd,
this.abilities,
});
factory Pokemon.fromJson(dynamic data) {
var pokemon = Pokemon(
name: data["name"] as String,
number: data["id"] as int,
types: (data['types'].length == 2)
? [
data['types'][0]["type"]["name"],
data['types'][1]["type"]["name"],
] as List<dynamic>
: [
data['types'][0]["type"]["name"],
] as List<dynamic>,
sprite: data["sprites"]['front_default'] as String,
prettySprite:
data["sprites"]["other"]['dream_world']['front_default'] as String,
hp: data['stats'][0]['base_stat'] as int,
atk: data['stats'][1]['base_stat'] as int,
def: data['stats'][2]['base_stat'] as int,
spAtk: data['stats'][3]['base_stat'] as int,
spDef: data['stats'][4]['base_stat'] as int,
spd: data['stats'][5]['base_stat'] as int,
abilities: (data['abilities'].length == 3)
? [
data['abilities'][0]['ability']['name'],
data['abilities'][1]['ability']['name'],
data['abilities'][2]['ability']['name']
] as List<dynamic>
: (data['abilities'].length == 2)
? [
data['abilities'][0]['ability']['name'],
data['abilities'][1]['ability']['name'],
] as List<dynamic>
: [
data['abilities'][0]['ability']['name'],
] as List<dynamic>,
);
return pokemon;
}
}
Future<Pokemon> fetchPokemon(String url) async {
final response = await http.get(Uri.parse(url));
return parsePokemon(response.body);
}
Pokemon parsePokemon(String responsebody) {
final parsed = jsonDecode(responsebody);
return Pokemon.fromJson(parsed);
}
知道如何改进它吗?