【问题标题】:The getter 'pokemon' was called on null吸气剂“口袋妖怪”在 null 上被调用
【发布时间】:2021-03-24 05:49:20
【问题描述】:

我正在尝试制作一个口袋妖怪应用程序。但我得到这个错误:

“getter 'pokemon' 在 null 上被调用。

接收者:空

尝试召唤:口袋妖怪

我正在将此 API url 用于数据“https://raw.githubusercontent.com/Biuni/PokemonGO-Pokedex/master/pokedex.json”

我的口袋妖怪课在这里:

class PokeHub {
  List<Pokemon> pokemon;

  PokeHub({this.pokemon});

  PokeHub.fromJson(Map<String,dynamic> json) {
    if (json['pokemon'] != null) {
      pokemon = new List<Pokemon>();
      json['pokemon'].forEach((items) {
        pokemon.add(new Pokemon.fromJson(items));
      });
    }
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    if (this.pokemon != null) {
      data['pokemon'] = this.pokemon.map((items) => items.toJson()).toList();
    }
    return data;
  }
}

class Pokemon {
  int id;
  String num;
  String name;
  String img;
  List<String> type;
  String height;
  String weight;
  String candy;
  int candyCount;
  String egg;
  String spawnChance;
  String avgSpawns;
  String spawnTime;
  List<double> multipliers;
  List<String> weaknesses;
  List<NextEvolution> nextEvolution;

  Pokemon(
      {this.id,
        this.num,
        this.name,
        this.img,
        this.type,
        this.height,
        this.weight,
        this.candy,
        this.candyCount,
        this.egg,
        this.spawnChance,
        this.avgSpawns,
        this.spawnTime,
        this.multipliers,
        this.weaknesses,
        this.nextEvolution});

  Pokemon.fromJson(Map<String, dynamic> json) {
    id = json['id'];
    num = json['num'];
    name = json['name'];
    img = json['img'];
    type = json['type'].cast<String>();
    height = json['height'];
    weight = json['weight'];
    candy = json['candy'];
    candyCount = json['candy_count'];
    egg = json['egg'];
    spawnChance = json['spawn_chance'].toString();
    avgSpawns = json['avg_spawns'].toString();
    spawnTime = json['spawn_time'];
    multipliers = json['multipliers']?.cast<double>();
    weaknesses = json['weaknesses'].cast<String>();
    if (json['next_evolution'] != null) {
      nextEvolution = new List<NextEvolution>();
      json['next_evolution'].forEach((v) {
        nextEvolution.add(new NextEvolution.fromJson(v));
      });
    }
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['id'] = this.id;
    data['num'] = this.num;
    data['name'] = this.name;
    data['img'] = this.img;
    data['type'] = this.type;
    data['height'] = this.height;
    data['weight'] = this.weight;
    data['candy'] = this.candy;
    data['candy_count'] = this.candyCount;
    data['egg'] = this.egg;
    data['spawn_chance'] = this.spawnChance;
    data['avg_spawns'] = this.avgSpawns;
    data['spawn_time'] = this.spawnTime;
    data['multipliers'] = this.multipliers;
    data['weaknesses'] = this.weaknesses;
    if (this.nextEvolution != null) {
      data['next_evolution'] =
          this.nextEvolution.map((v) => v.toJson()).toList();
    }
    return data;
  }
}

class NextEvolution {
  String num;
  String name;

  NextEvolution({this.num, this.name});

  NextEvolution.fromJson(Map<String, dynamic> json) {
    num = json['num'];
    name = json['name'];
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['num'] = this.num;
    data['name'] = this.name;
    return data;
  }

这是我的 main.dart 文件:

import 'package:flutter/material.dart';
import 'package:pokemon_flutter/screens/main_screen.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: "Poke App",
      home: MainScreen(),
      debugShowCheckedModeBanner: false,
    );
  }

}

这是我的 main_screen.dart 文件:

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

import 'package:pokemon_flutter/models/pokemon.dart';

class MainScreen extends StatefulWidget {
  @override
  _MainScreenState createState() => _MainScreenState();
}

class _MainScreenState extends State<MainScreen> {
  var url =
      "https://raw.githubusercontent.com/Biuni/PokemonGO-Pokedex/master/pokedex.json";
  PokeHub pokeHub;
  @override
  void initState() {
    super.initState();
    fetchData();
  }

  void fetchData() async {
    var res = await http.get(url);
    var decodedJson = jsonDecode(res.body);
    pokeHub = PokeHub.fromJson(decodedJson);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Poke App"),
        backgroundColor: Colors.cyan,
      ),
      body: GridView.count(
        crossAxisCount: 2,
        children: pokeHub.pokemon.map((poke) => Card()).toList(),
      ),
      drawer: Drawer(),
      floatingActionButton: FloatingActionButton(
        onPressed: () {},
        backgroundColor: Colors.cyan,
        child: Icon(Icons.refresh),
      ),
    );
  }
}

似乎所有事情都是真的,这就是为什么我无法识别错误。如果您对这种情况有任何建议,我将不胜感激。

编辑:我是新来的,这就是为什么有时我的问题可能毫无意义。但请不要降低我的分数。 Stackoverflow 不会再接受我的问题了。请加分。

【问题讨论】:

    标签: android ios api flutter dart


    【解决方案1】:

    当我完成我的代码时,应用程序就开始工作了。这是我的新 main_screen.dart 文件:

    import 'package:flutter/cupertino.dart';
    import 'package:flutter/material.dart';
    import 'package:http/http.dart' as http;
    import 'dart:convert';
    
    import 'package:pokemon_flutter/models/pokemon.dart';
    import 'package:pokemon_flutter/screens/pokemon_detail_screen.dart';
    
    class MainScreen extends StatefulWidget {
      @override
      _MainScreenState createState() => _MainScreenState();
    }
    
    class _MainScreenState extends State<MainScreen> {
      var url =
          "https://raw.githubusercontent.com/Biuni/PokemonGO-Pokedex/master/pokedex.json";
      PokeHub pokeHub;
      @override
      void initState() {
        super.initState();
        fetchData();
      }
      var res;
      void fetchData() async {
         res= await http.get(url);
        var decodedJson = jsonDecode(res.body);
        pokeHub = PokeHub.fromJson(decodedJson);
        print(pokeHub.toJson());
        setState(() {});
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text("Poke App"),
            backgroundColor: Colors.cyan,
          ),
          body: pokeHub == null
              ? Center(
                  child: CircularProgressIndicator(),
                )
              : GridView.count(
                  crossAxisCount: 2,
                  children: pokeHub.pokemon
                      .map((poke) => Padding(
                            padding: const EdgeInsets.all(2.0),
                            child: InkWell(
                              onTap: (){
                                Navigator.push(context, MaterialPageRoute(builder: (context)=>PokeDetail(
                                  pokemon: poke,
                                )));
                              },
                              child: Hero(
                                tag: poke.img,
                                child: Card(
                                  elevation: 3.0,
                                  child: Column(
                                    mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                                    children: <Widget>[
                                      Container(
                                        height: 100.0,
                                        width: 100.0,
                                        decoration: BoxDecoration(
                                            image: DecorationImage(
                                                image: NetworkImage(poke.img))),
                                      ),
                                      Text(
                                        poke.name,
                                        style: TextStyle(
                                          fontSize: 20.0,
                                          fontWeight: FontWeight.bold,
                                        ),
                                      )
                                    ],
                                  ),
                                ),
                              ),
                            ),
                          ))
                      .toList(),
                ),
          drawer: Drawer(),
          floatingActionButton: FloatingActionButton(
            onPressed: () {},
            backgroundColor: Colors.cyan,
            child: Icon(Icons.refresh),
          ),
        );
      }
    }
    

    我添加了 if else 语句并设置状态。我不知道我是如何解决这个问题的,但它已经解决了。 我认为这些代码有效:

     void fetchData() async {
         res= await http.get(url);
        var decodedJson = jsonDecode(res.body);
        pokeHub = PokeHub.fromJson(decodedJson);
        print(pokeHub.toJson());
        setState(() {});
      }
    
    body: pokeHub == null
              ? Center(
                  child: CircularProgressIndicator(),
                )
              : GridView.count(
    

    【讨论】:

      【解决方案2】:

      当您调用 pokeHub.pokemon 时,pokeHub 仍然为 null,因此它不能为 pokemon getter 返回任何值。 我看到您正在获取数据,但是当您的小部件构建时,该数据(异步返回)尚未返回。对于这种情况,使用 FutureBuilder 将是一个不错的选择。像这样的东西应该可以工作:

         var res;
          void fetchData()  {
            res = http.get(url).then((value){
              var decodedJson = jsonDecode(res.body);
              pokeHub = PokeHub.fromJson(decodedJson);
            });
            
         }
      @override
        Widget build(BuildContext context) {
          return Scaffold(
            appBar: AppBar(
              title: Text("Poke App"),
              backgroundColor: Colors.cyan,
            ),
            body: FutureBuilder(
            future: res,
            builder: (BuildContext context, AsyncSnapshot snapshot) {
              if(snapshot.hasData)
      
              return GridView.count(
                crossAxisCount: 2,
                children: pokeHub.pokemon.map((poke) => Card()).toList(),
              ),
              drawer: Drawer(),
              floatingActionButton: FloatingActionButton(
                onPressed: () {},
                backgroundColor: Colors.cyan,
                child: Icon(Icons.refresh),
              );
            },
          ),
          );
        }
      

      只有在检索到数据后,才会使用 futurebuilder 构建小部件。更多信息:https://api.flutter.dev/flutter/widgets/FutureBuilder-class.html

      【讨论】:

      • 感谢您的建议。但我解决了这个问题。我现在要编辑我的问题。祝你有美好的一天!
      猜你喜欢
      • 1970-01-01
      • 2020-10-30
      • 2021-04-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多