Dart

22. RSSアプリを色々カスタマイズしてみる

今回はRSSアプリのカスタマイズをしていきます。
デザインの調整がメインになります。

RSSアプリの作成

tamappe.com

RSSアプリの詳細ページの作成

tamappe.com

separatorを追加する

まず最初にiOSにあるようなUITableViewのseparatorを作成します。
作り方はListTileListTile.divideTilesにすれば可能です。

ListView(
padding: EdgeInsets.all(10.0),
children: ListTile.divideTiles(
color: Colors.black,
context: context,
tiles: _items
).toList(),
),

separatorの線の色をblack指定しました。

f:id:qed805:20200223154550p:plain
黒色のセパレータ線を追加する

このように線が表示されていたら成功です。

日付のフォーマットを整える

次にRSSで受け取った日付がタイムゾーンを含んだものになっているのでDateを調整して日本時刻に変換します。
実はアプリ開発で扱いが難しいのは日付のデータだったりするのですが、Flutterも例外ではありません。

とりあえずFlutterで日付を操作するパッケージがありますので紹介します。

Intl

pub.dev

パッケージを使うためにpubspec.yamlファイルにIntlを書きます。

dependencies:
flutter:
sdk: flutter
cupertino_icons: ^0.1.2
webfeed: ^0.4.2
http: ^0.12.0+4
webview_flutter: ^0.3.19+7
intl: ^0.15.7 # こちらを追加する

パッケージをアップデートしたらインストール完了です。
まだintlの理解が及んでいませんが、DateTime.parse()タイムゾーンを含んだStringを
DateFormatで指定した文字列形式に変換することができました。

例えば、次のようなメソッドを書きます。

Widget convertText(String published) {
var formatter = DateFormat('yyyy年MM月dd日');
final date = DateTime.parse(published);
var formatted = formatter.format(date);
return Text(formatted);  /// 2020年MM月dd日と表示される
}

これでStringのpublishedから指定の日付フォーマットに変換されたTextウィジェットを作成することができました。
前回作成したRSSアプリのrss_list_page.dartを次のように修正します。

rss_list_page.dart

import 'package:flutter/material.dart';
import 'package:intl/intl.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: ListTile.divideTiles(
color: Colors.black,
context: context,
tiles: _items
).toList(),
),
),
);
}
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: convertText(item.updated),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (_) => ItemDetailPage(
item: item,
)));
},
));
}
setState(() {
_items = list;
});
}
Widget convertText(String published) {
var formatter = DateFormat('yyyy年MM月dd日');
final date = DateTime.parse(published);
var formatted = formatter.format(date);
return Text(formatted);
}
}

これをビルドすると次のように画面が表示されます。

f:id:qed805:20200223160003p:plain
日付を変換

これでよりRSSアプリとして使えるようになりました。
あとはより細かいレイアウト調整だったり、画像を表示させられるといった工夫ができますが
ひとまずRSSの基本としてはOKだと思います。

今回は区切り線と日付の扱いについて学びました。

ABOUT ME
tamappe
都内で働くiOSアプリエンジニアのTamappeです。 当ブログではモバイルアプリの開発手法について紹介しています。メインはiOS、サブでFlutter, Android も対応できます。 執筆・講演のご相談は tamapppe@gmail.com までお問い合わせください。