Flutter新闻数据获取插件newsapi的使用

发布于 1周前 作者 ionicwang 来自 Flutter

Flutter新闻数据获取插件newsapi的使用

安装

dependencies:
  newsapi: ^1.0.9

示例代码

import 'package:newsapi/newsapi.dart';

void main() async {
  var newsApi = NewsApi(
    // dioOptions: dioOptions,
    // interceptors: interceptors,
    debugLog: true,
    apiKey: 'foo',
  );

  newsApi.apiKey = 'Change_your_api_key'; // 更改为你的API密钥

  var topHeadlines = await newsApi.topHeadlines(
    // country: country,
    // category: category,
    // sources: sources,
    // q: q,
    language: 'en',
    // pageSize: pageSize,
    // page: page,
  );

  // ArticleResponse
  print(topHeadlines);

  var everything = await newsApi.everything(
    q: 'flutter',
    // qInTitle: qInTitle,
    // sources: sources,
    // domains: domains,
    // excludeDomains: excludeDomains,
    // from: from, // support DateTime or String
    // to: to, // support DateTime or String
    // language: language,
    // sortBy: sortBy,
    // pageSize: pageSize,
    // page: page,
  );
  // ArticleResponse
  print(everything);

  var sources = await newsApi.sources(
    // category: category,
    // language: language,
    // country: country,
  );
  // SourceResponse
  print(sources);
}

响应结构

class BaseResponse extends Equatable {
  String code;
  String message;
  @JsonKey(fromJson: statusFromJson, toJson: statusToJson)
  bool status;
  int totalResults;
}

class ArticleResponse extends BaseResponse {
  List<Article> articles;
}

class Article extends Equatable {
  Source source;
  String author;
  String content;
  String description;
  DateTime publishedAt;
  String title;
  String url;
  String urlToImage;
}

class SourceResponse extends BaseResponse {
  List<Source> sources;
}

class Source extends Equatable {
  String category;
  String country;
  String description;
  String id;
  String language;
  String name;
  String url;
}

开始测试

API_KEY=YOUR_API_KEY pub run test

更多关于Flutter新闻数据获取插件newsapi的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter新闻数据获取插件newsapi的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是一个使用Flutter和newsapi来获取新闻数据的示例代码。我们将使用http包来发送HTTP请求,并使用json_serialization来处理JSON数据。

首先,确保你的Flutter项目已经创建,并在pubspec.yaml文件中添加必要的依赖:

dependencies:
  flutter:
    sdk: flutter
  http: ^0.13.3  # 请根据需要更新到最新版本
  json_annotation: ^4.0.1  # 请根据需要更新到最新版本

然后,运行flutter pub get来安装依赖。

接下来,创建一个数据模型来表示新闻数据。我们将使用json_serializable来自动生成fromJsontoJson方法。

创建一个文件news_model.dart

import 'package:json_annotation/json_annotation.dart';

part 'news_model.g.dart';

@JsonSerializable()
class Article {
  final String source;
  final String author;
  final String title;
  final String description;
  final String url;
  final String urlToImage;
  final DateTime publishedAt;
  final String content;

  Article({
    required this.source,
    required this.author,
    required this.title,
    required this.description,
    required this.url,
    required this.urlToImage,
    required this.publishedAt,
    required this.content,
  });

  factory Article.fromJson(Map<String, dynamic> json) => _$ArticleFromJson(json);
  Map<String, dynamic> toJson() => _$ArticleToJson(this);
}

@JsonSerializable()
class NewsResponse {
  final String status;
  final int totalResults;
  final List<Article> articles;

  NewsResponse({
    required this.status,
    required this.totalResults,
    required this.articles,
  });

  factory NewsResponse.fromJson(Map<String, dynamic> json) => _$NewsResponseFromJson(json);
  Map<String, dynamic> toJson() => _$NewsResponseToJson(this);
}

然后,在项目的根目录下运行flutter pub run build_runner build来生成news_model.g.dart文件。

接下来,创建一个服务类来处理新闻数据的获取。创建一个文件news_service.dart

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

class NewsService {
  final String apiKey = 'YOUR_NEWS_API_KEY'; // 请替换为你的News API密钥
  final String baseUrl = 'https://newsapi.org/v2';

  Future<NewsResponse> fetchNews(String category) async {
    final Uri uri = Uri.https(baseUrl, '/top-headlines', {
      'category': category,
      'apiKey': apiKey,
    });

    try {
      final response = await http.get(uri);
      if (response.statusCode == 200) {
        final Map<String, dynamic> body = jsonDecode(response.body);
        return NewsResponse.fromJson(body);
      } else {
        throw Exception('Failed to load news');
      }
    } catch (e) {
      throw Exception('Failed to load news: $e');
    }
  }
}

最后,在你的主应用程序文件中(通常是main.dart),使用NewsService来获取并显示新闻数据:

import 'package:flutter/material.dart';
import 'news_service.dart';
import 'news_model.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter News App',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: NewsScreen(),
    );
  }
}

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

class _NewsScreenState extends State<NewsScreen> {
  late NewsService _newsService;
  late Future<NewsResponse> _futureNews;

  @override
  void initState() {
    super.initState();
    _newsService = NewsService();
    _futureNews = _newsService.fetchNews('technology'); // 可以根据需要更改类别
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('News'),
      ),
      body: FutureBuilder<NewsResponse>(
        future: _futureNews,
        builder: (context, snapshot) {
          if (snapshot.connectionState == ConnectionState.done) {
            if (snapshot.hasError) {
              return Center(
                child: Text('Error: ${snapshot.error}'),
              );
            } else {
              final NewsResponse newsResponse = snapshot.data!;
              return ListView.builder(
                itemCount: newsResponse.articles.length,
                itemBuilder: (context, index) {
                  final Article article = newsResponse.articles[index];
                  return ListTile(
                    leading: Image.network(article.urlToImage ?? ''),
                    title: Text(article.title),
                    subtitle: Text(article.description),
                    onTap: () {
                      // 打开新闻详情页面
                      Navigator.push(
                        context,
                        MaterialPageRoute(
                          builder: (context) => NewsDetailScreen(article: article),
                        ),
                      );
                    },
                  );
                },
              );
            }
          } else {
            return Center(
              child: CircularProgressIndicator(),
            );
          }
        },
      ),
    );
  }
}

class NewsDetailScreen extends StatelessWidget {
  final Article article;

  NewsDetailScreen({required this.article});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(article.title),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Image.network(article.urlToImage ?? ''),
            SizedBox(height: 16),
            Text(article.title, style: TextStyle(fontSize: 24),),
            SizedBox(height: 8),
            Text(article.description, style: TextStyle(fontSize: 18),),
            SizedBox(height: 16),
            Text('Source: ${article.source}', style: TextStyle(fontSize: 16, color: Colors.grey),),
            SizedBox(height: 8),
            Text('Author: ${article.author ?? 'Unknown'}', style: TextStyle(fontSize: 16, color: Colors.grey),),
            SizedBox(height: 16),
            ElevatedButton(
              onPressed: () => launchUrl(Uri.parse(article.url)),
              child: Text('Read more'),
            ),
          ],
        ),
      ),
    );
  }

  Future<void> launchUrl(Uri url) async {
    if (await canLaunchUrl(url)) {
      await launchUrl(url);
    } else {
      throw 'Could not launch $url';
    }
  }
}

请注意,为了打开URL,你需要添加url_launcher依赖:

dependencies:
  url_launcher: ^6.0.3  # 请根据需要更新到最新版本

并在main.dart文件顶部添加导入:

import 'package:url_launcher/url_launcher.dart';

这样,你就可以在Flutter应用中使用newsapi来获取并显示新闻数据了。

回到顶部