19. Flutterでwebfeedとhtmlを使ってRSSのリスト一覧を作成する

今回はFlutterでRSSの導入みたいなものを作成したいと思います。
RSSアプリの概要
今回RSSで使うXMLファイルはQiitaにユーザーフィードにしています。
ここで学習できた内容は
- ListViewとListTileの使い方
- 画面遷移
- ライブラリのインストール
- ウィジェットのイニシャライズ
こちらになります。
Flutterのライブラリのパッケージ
Flutterで使うパッケージは
- webfeed (RSSパーサーライブラリ)
- http (httpクライアント)
この2つを使って開発していきます。
それぞれのパッケージのインストールと使い方については上記ページの「Installing」タブに記載されています。
私のpubspec.yamlは下記の通りです。
pubspec.yaml
dependencies:
  flutter:
    sdk: flutter
  # The following adds the Cupertino Icons font to your application.
  # Use with the CupertinoIcons class for iOS style icons.
  cupertino_icons: ^0.1.2
  webfeed: ^0.4.2
  http: ^0.12.0+4RSSの構造はXMLをとってきてパースしてFeedのitemに変換しなければなりません。
 XMLの取得についてはhttpを使って
 Feedの変換についてはwebfeedを使って
 それぞれ行います。
変換したitemをListTileのウィジェットに代入してそれをListViewにセットします。
サンプルコードについて
それではRSSアプリの基礎になるList一覧までのソースコードを書いていきます。
main.dart
import 'package:flutter/material.dart';
import 'package:rss_app/rss_list_page.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.green,
      ),
      home: RssListPage(),
    );
  }
}rss_list_page.dart
import 'package:flutter/material.dart';
import 'package:rss_app/item_detail_page.dart';
import 'package:webfeed/webfeed.dart';
import 'package:http/http.dart';
class RssListPage extends StatefulWidget {
  final String title;
  final String url;
  RssListPage({@required this.title, @required this.url});
  @override
  _RssListPageState createState() => _RssListPageState(title: title, url: url);
}
class _RssListPageState extends State<RssListPage> {
  final String _rssUrl = "https://qiita.com/tamappe/feed.atom";
  final String title;
  final String url;
  List<Widget> _items = [];
  _RssListPageState({@required this.title, @required this.url}) {
    convertItemFromXML();
  }
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("RSS リーダー"),
      ),
      body: Center(
        child: ListView(
          padding: EdgeInsets.all(10.0),
          children: _items,
        ),
      ),
    );
  }
  void convertItemFromXML() async {
    List<Widget> list = [];
    Response res  = await get(_rssUrl);
    var atomFeed = new AtomFeed.parse(res.body);
    for (AtomItem item in atomFeed.items) {
      list.add(ListTile(
        contentPadding: EdgeInsets.all(10.0),
        title: Text(
          item.title,
        ),
        subtitle: Text(
            item.published
        ),
        onTap: () {
          Navigator.push(context, MaterialPageRoute(
              builder: (_) =>
                  ItemDetailPage(
                    item: item,
                  )
          ));
        },
      ));
    }
    setState(() {
      _items = list;
    });
  }
}item_detail_page.dart
import 'package:flutter/material.dart';
import 'package:webfeed/webfeed.dart';
class ItemDetailPage extends StatefulWidget {
  final AtomItem item;
  ItemDetailPage({
    @required this.item
  });
  @override
  _ItemDetailPageState createState() => _ItemDetailPageState(item: item);
}
class _ItemDetailPageState extends State<ItemDetailPage> {
  AtomItem item;
  _ItemDetailPageState({@required this.item});
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(item.title),
      ),
      body: Center(
          child: Text(item.title)
      ),
    );
  }
}これでビルドすると次のような動作になります。
自分のQiitaのフィードをもとにRSSアプリの基礎であるXMLファイルのパースが出来上がる。
httpとwebfeedを使って実装する。 pic.twitter.com/ei1xEpRWgs— Tamappe@オンライン英会話のエンジニア (@tamapppe) 2020年2月16日
ツイッターでgifを貼り付けても自動再生されませんでした。。。

rss_list
解説
それではhtmlとwebfeedの使い方について解説していきます。
今回ではRSSのURLをgetしてXMLファイルを取得するために使いました。
Response res  = await get(_rssUrl);get(url)でhttp通信を行うことができます。今回はGETの通信を行いました。awaitはDartにおける非同期処理を行うために使うものです。
 awaitを使うためにはメソッドにasyncが必要になるためメソッドにasyncを記載しています。
void convertItemFromXML() async {}取得したresponseであるresがFeedです。
 公式でも次のように解説しています。
var atomFeed = new AtomFeed.parse(xmlString); // for parsing Atom feedちなみにQiitaのユーザーフィードはAtom仕様らしいのでAtomFeedオブジェクトに変換しました。
 RSS仕様の場合は次のとおりです。
var rssFeed = new RssFeed.parse(xmlString);AtomFeedオブジェクトの取得に成功したらfor文を使ってそれぞれの記事のitemを取得しに行きます。
for (AtomItem item in atomFeed.items) {
    }AtomItemからItemの情報を取得する場合は
item.id
item.title  // 記事タイトル
item.updated  // 更新日
item.published  // 投稿日という感じになります。
そして、取得できた情報をListTileにセットしてListViewを表示させました。
 これでRSSアプリの基本であるリスト一覧までが完成しました。
あとはまあ取得できたWEBのリンクを使ってウェブページを表示させるのが常套手段ですが、
 今回はここまでにします。






