Как разобрать JSON в флаттер? - PullRequest
0 голосов
/ 05 ноября 2019

Я хочу создать приложение новостей, и я использовал newsapi.org в качестве источника.

Я пытаюсь получить данные JSON, поступающие из библиотеки Http.

I 'мы предоставили весь код ниже.

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

IНе знаю, в чем проблема, но все мои проекты остановились на этой проблеме.

Я ищу решение для этого кода, потому что он не работает.

import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:http/http.dart';
import 'package:newly/services/networking.dart';
import 'package:newly/widgets/article.dart';

class NewsScreen extends StatefulWidget {
  @override
  _NewsScreenState createState() => _NewsScreenState();
}

class _NewsScreenState extends State<NewsScreen> {

  List<Article> articles = [];

  NetworkHelper networkHelper = NetworkHelper(
    url:
        'https://newsapi.org/v2/everything?q=bitcoin&apiKey=392495172bab4b3885ae93760df54b91',
  );

  Future<List<Widget>> getNews() async {
    var newsData = await networkHelper.getData();

    for (int i = 0; i < await newsData['articles'].length; i++) {
      var title = await newsData['articles'][i]['title'];
      var urlToImage = await newsData['articles'][i]['urlToImage'];
      var content = await newsData['articles'][i]['content'];
      var author = await newsData['articles'][i]['author'];
      var url = await newsData['articles'][i]['url'];

      print(title);
      print(urlToImage);
      print(url);
      print(content);
      print(author);
      print('123456789123456789123456789123456789');

      articles.add(
        Article(
          author: author,
          content: content,
          title: title,
          url: url,
          urlToImage: urlToImage,
        ),
      );

      print(articles[0].author);

    }

    return articles;
  }

  Future<List<Article>> showArticles() async {
    var data = await get(
      'https://newsapi.org/v2/everything?q=bitcoin&apiKey=392495172bab4b3885ae93760df54b91',
    );

    var dataDecoded = await json.decode(data.body);

    List<Article> articles = [];

    await dataDecoded.forEach(
      (article) {
        articles.add(
          Article(
            author: article['author'],
            content: article['content'],
            title: article['title'],
            url: article['url'],
            urlToImage: article['urlToImage'],
          ),
        );
      },
    );

    return articles;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Colors.black,
        centerTitle: true,
        title: Text(
          'Newly',
          style: TextStyle(
            color: Colors.white,
          ),
        ),
      ),
      body: FutureBuilder(
        future: getNews(),
        builder: (context, snapshot) {
          return ListView(
            children: articles,
          );
        },
      ),

    );
  }
}

Network Helper:

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

class NetworkHelper {
  NetworkHelper({this.url});

  final String url;

  Future getData() async {
    http.Response response = await http.get(url);

    if (response.statusCode == 200) {
      String data = response.body;

      return json.decode(data);
    } else {
      print('something wrong');
      print(response.statusCode);
    }
  }
}

Ответы [ 4 ]

1 голос
/ 05 ноября 2019

Вы также можете сделать это, используя FutureBuilder, если вы хотите иначе, так как @Mustafa ответ будет работать.

Future<List<Article>> showArticles() async {
var data = await networkHelper.getData();

List<Article> articlesArr = [];

await data['articles'].forEach(
  (article) {
    articlesArr.add(
      Article(
        author: article['author'],
        content: article['content'],
        title: article['title'],
        url: article['url'],
        urlToImage: article['urlToImage'],
      ),
    );
  },
);
return articlesArr;
}

@override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Colors.black,
        centerTitle: true,
        title: Text(
          'Newly',
          style: TextStyle(
            color: Colors.white,
          ),
        ),
      ),
      body: FutureBuilder<List<Article>>(
        future: showArticles(),
        builder: (context, snapshot) {
          if (snapshot.hasData) {
            return ListView(
              children: snapshot.data.map((article) {
                return Container(
                  padding: EdgeInsets.all(8.0),
                  child: Text(article.author),
                );
              }).toList(),
            );
          } else {
            return Container(
              color: Colors.blue,
            );
          }
        },
      ),
    );
  }
}
1 голос
/ 05 ноября 2019

Попробуйте установить setState перед добавлением статей в массив

0 голосов
/ 05 ноября 2019

При работе с данными json

Рекомендуется создать для этого модель , а затем просто извлечь данные через API

Создание модели и класса достаточно просто, не требует усилий и облегчает вашу работу;)

Для Создание модели для вашего проекта

ПОСЕТИТЬ https://javiercbk.github.io/json_to_dart/

см. Изображение ниже

enter image description here

просто скопируйте данные JSONи вставьте текстовое поле, и вы получите готовый класс модели одним щелчком мыши

для доступа к данным

Test _test = Test.fromJson(response.body);

и все.

0 голосов
/ 05 ноября 2019

Проблема в показе статей. и да, как говорит @ISpam Ossama, вы должны использовать setState для добавления данных в список следующим образом.

void getNews() async {
var newsData = await networkHelper.getData();

for (int i = 0; i < newsData['articles'].length; i++) {
  var title = newsData['articles'][i]['title'];
  var urlToImage = newsData['articles'][i]['urlToImage'];
  var content = newsData['articles'][i]['content'];
  var author = newsData['articles'][i]['author'];
  var url = newsData['articles'][i]['url'];

  print(title);
  print(urlToImage);
  print(url);
  print(content);
  print(author);
  print('123456789123456789123456789123456789');
  setState(() {
   articles.add(
    Article(
      author: author,
      content: content,
      title: title,
      url: url,
      urlToImage: urlToImage,
    ),
  );
  });
  print(articles[0].author);
}
}

Теперь вы должны отображать статьи, подобные этой.

ListView.builder(
          itemCount: articles.length,
          itemBuilder: (BuildContext ctxt, int index) {
            return Text(articles[index].title);
          },
        )

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

...