Flutter: невозможно преобразовать HTTP-ответ в объект podo - PullRequest
0 голосов
/ 03 мая 2020

XKCD.dart

class XKCD {
  final String id;
  final String imageURL;
  final String safeTitle;

  XKCD({this.id, this.imageURL, this.safeTitle});

  factory XKCD.fromJson(Map<String, dynamic> json){
    return XKCD(
    id: json['num'],
    imageURL:json['img'],
    safeTitle:json['safe_title'],
    );
  }
}

import 'package:http/http.dart' as http;
import 'dart:convert';
import 'dart:async';
import 'package:fluttermvpillustrativeapp/data/xkcd_data.dart';

class ProdXKCDRepo {
  String baseURL = "http://xkcd.com/";

  Future<XKCD> fetchComicPost() async {
    http.Response response = await http.get(baseURL + "info.0.json");
    final responseBody = json.decode(response.body);
    final statusCode = response.statusCode;

    if (response.statusCode == 200) {
      print (XKCD.fromJson(json.decode(response.body)); // No value gets printed
      return XKCD.fromJson(json.decode(response.body));
    }

  }
}

class HomePage extends StatefulWidget {
  HomePage({Key key}) : super(key: key);

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

class _HomePageState extends State<HomePage> {
  Future<XKCD> comicPost;

  @override
  void initState() {
    super.initState();
    comicPost = ProdXKCDRepo().fetchComicPost();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("XKCD comic"),
        actions: <Widget>[
          IconButton(
            icon: new Icon(Icons.file_download),
            tooltip: 'Download',
            onPressed: () {},
          ),
          IconButton(
            icon: new Icon(Icons.share),
            tooltip: 'Share',
            onPressed: () {},
          ),
        ],
      ),
      body: _comicBody(),
    );
  }

  Widget _comicBody() {
    return Center(
      child: FutureBuilder<XKCD>(
        future: comicPost,
        builder: (context, snapshot) {
          if (snapshot.hasData) {
            Column(
              children: <Widget>[
                Expanded(
                  child: Container(
                    child: PhotoView(
                      imageProvider: NetworkImage(snapshot.data.imageURL),
                    ),
                  ),
                  flex: 1,
                ),
                Row(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: <Widget>[
                    IconButton(icon: Icon(Icons.fast_rewind), onPressed: null),
                    IconButton(icon: Icon(Icons.chevron_left), onPressed: null),
                    IconButton(
                        icon: Icon(Icons.center_focus_strong), onPressed: null),
                    IconButton(
                        icon: Icon(Icons.chevron_right), onPressed: null),
                    IconButton(icon: Icon(Icons.fast_forward), onPressed: null),
                  ],
                )
              ],
            );
          }
          // By default, show a loading spinner.
          return CircularProgressIndicator();
        },
      ),
    );
  }
}

Когда я использую его в FutureBuilder ошибка получения imageURL is null, а счетчик загружается бесконечно.

════════ Exception caught by widgets library ═══════════════════════════════════════════════════════
The following NoSuchMethodError was thrown building FutureBuilder<XKCD>(dirty, state: _FutureBuilderState<XKCD>#b4c12):
The getter 'imageURL' was called on null.
Receiver: null
Tried calling: imageURL

Я не могу понять, где я иду не так.

Ответы [ 2 ]

1 голос
/ 03 мая 2020

Вашу ошибку можно исправить, добавив оператор return прямо перед вашим столбцом в будущем компоновщике.

См. Код ниже:

if (snapshot.hasData) {
           return Column(
            children: <Widget>[
              Expanded(
                child: Container(
                  child: Image.network('${snapshot.data.imageURL}'),
                ),
                flex: 1,
              ),
              Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  IconButton(icon: Icon(Icons.fast_rewind), onPressed: null),
                  IconButton(icon: Icon(Icons.chevron_left), onPressed: null),
                  IconButton(
                      icon: Icon(Icons.center_focus_strong), onPressed: null),
                  IconButton(icon: Icon(Icons.chevron_right), onPressed: null),
                  IconButton(icon: Icon(Icons.fast_forward), onPressed: null),
                ],
              )
            ],
          );
        }

Вывод: enter image description here

Надеюсь, это поможет.

ПОЛНЫЙ КОД:

Widget _comicBody() {
  return Center(
    child: FutureBuilder<XKCD>(
      future: ProdXKCDRepo().fetchComicPost(),
      builder: (context, snapshot) {
        if (snapshot.hasData) {
          return Column(
            children: <Widget>[
              Expanded(
                child: Container(
                  child: Image.network('${snapshot.data.imageURL}'),
                ),
                flex: 1,
              ),
              Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  IconButton(icon: Icon(Icons.fast_rewind), onPressed: null),
                  IconButton(icon: Icon(Icons.chevron_left), onPressed: null),
                  IconButton(
                      icon: Icon(Icons.center_focus_strong), onPressed: null),
                  IconButton(icon: Icon(Icons.chevron_right), onPressed: null),
                  IconButton(icon: Icon(Icons.fast_forward), onPressed: null),
                ],
              )
            ],
          );
        } else if (snapshot.hasError) {
          return Center(
            child: Text('${snapshot.error}'),
          );
        }
        // By default, show a loading spinner.
        return CircularProgressIndicator();
      },
    ),
  );
}
1 голос
/ 03 мая 2020

вы забыли добавить ключевое слово return в следующем месте.

if (snapshot.hasData) { return Column( children: <Widget>[ 

и из-за этого вы не получаете обновленный пользовательский интерфейс.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...