プログラミング

FlutterでTwitterクライアント作成⑧タイムラインに画像を表示する

2020-04-07




前回の続き。

FlutterでTwitterクライアント作成⑦細かい修正いろいろ

前回の続き。 タイムラインに画像を表示する!! 予定でしたが、その前にいろいろと細かい修正が必要そうだったのでまとめて。 目次1 いいね・リツイートが0の時はラベルを空欄にする1.1 三項演算子を追加 ...

続きを見る

今回はタイムラインに画像を表示させます。
いろいろ試行錯誤してどうにか完成。

LocalのJsonファイルを読み込めるようにする

Twitter APIで情報を取得してもいいけど、画像3枚とかあんまりないのでJsonファイルでテストデータを作ることにしました。

Jsonファイルを作成する

リファレンスと実際に返ってくる値を参考にテストデータを作りました。
実際に使う値だけしか書いてません。
jsons/timeline.jsonに以下を記載。

assetsに追加

pubspec.yamlにフォルダを追加してリソースとして使えるようにします。

Jsonを読み込むためのクラスを作成する

modelじゃなくてutilにしました。
lib/util/get_local_object.dartに以下を書いて保存します。

もし他のローカルファイルを読み込むことがあればここに追加しよう。

Twitter APIの代わりにJsonを読み込む

twitter_card_model.dartを1行書き換えてJsonを読み込めるようにします。
もとのTwitterApiModelはまた使うのでコメントアウトだけ。

Twitter、なぜかentitiesとextended_entitiesの1枚目に同じURLが入ってる。。。
よくわからないのでそのまま追加してます。

JsonでKeyがない可能性がある情報の取得

調べたんですけど、DartってPHPでいうところのissetがない…?
変数に格納されてれば.isEmptyが使えるけど、JsonというかMapだと変数に入れようとした段階で

そのKeyないよ!

って怒られる。
==null ならよくない?と思ったけど、なぜかこれもエラー。

左辺がnullだったら代入するよ!っていう便利な??=というのがあるけど、右側がnullだったら…はないらしい。

nullチェックする方法がないわけない気がするけど見当たらないので、とりあえずTryでくくってみたのでした。

URLを置換

textに画像URLが含まれているので、画像があった場合は置換するようにしました。
ちなみにこれ

Dartのreplaceって見つからなかったときにエラー返すのかウソだろマジか

って思って追加したんですけど、単にkeyが間違ってただけというね。
if文いらないです。
そのうち消します。

タイムラインで画像を表示できるようにする

Twitterの画像は1~4枚まであるので、それぞれ表示できるようにします。

カスタムウィジェットに画像を追加する

当初はカードの種類だけウィジェットを用意しようとしてたんですが、あまりにも冗長になるのでやめました。
テキストだけのカードにImageウィジェットを呼び出す枠を作り、渡された画像の数によって返却する内容を変えてます。

共通ウィジェットで画像の設定

画像に対する処理は大体同じなので、共通メソッドとして切り出しました。
これをそれぞれ画像の配置用ウィジェットに組み込みます。

実際に呼ぶ場合はこんな感じ。

 

画像を角丸にする

ClipRRectを使うと、四角い画像の角を丸めることができます。

borderRadiusにはどの角を丸めるかを指定します。

画像が1枚の場合は全部の角を丸めるので

画像が4枚の場合は1画像につき丸める角は1つなので

BorderRadiusはall、onlyの他にも種類があるので、使いやすいものを使えばOKです。

画像を要素に合わせる

Twitterの画像って、特定の範囲でクリッピングされてるんですよね。
ということで、BoxFitを使って画像を要素の形に変形します。

例えば、こんな感じの縦長画像があったとして

BoxFit.coverを指定するとこう。

他にも枠に合わせてクシャっと押し込めるfill

幅または高さに合わせるcontainなんかがあります。

個人的にはfillの使いどころがさっぱり。
全部で7種類あるのでいろいろ使ってみてください。

Tableでグリッド配置

画像4枚の場合、RowとColumnを組み合わせてもいいけどちょっと冗長。
そんな場合はTableを使うとスッキリかけます。
※_imageItemの引数が多くて長いけど

HTMLのtrがTableRow。
tdがchildrenにあたります。

画像1枚の時と同じサイズに収まるようにしてあります。

RowやColumnが入れ子になると結構ややこしいのでTableは活用していきたいところ。
なんですが。
HTMLと違って行や列の結合ができないという欠点があります。。。
Rowspanやcolspanに該当するものがないんですね。

なので、こんな配置にする場合はTableは使えません。
でも要望は多そうなので今後機能追加されるかな?
期待しよう。

画像がなければ空のContainerを返却

buildの中でどのウィジェットを返すか判定してます。
もし画像が1枚もなければ空っぽのContainerが返るようになってます。

画像のプレビューを表示する

画像をBoxFitで変形してるのもあるし、元の画像を表示する機能が欲しい。
まぁ公式と一緒なんだけど。

ということで、画像をタップしたらプレビュー画面を表示するようにします。

プレビュー画面を作成する

新しくlib/routes/image_preview.dartを作って以下を追加。
もらった画像を中央に表示してるだけです。

名前付き引数と必須引数

コンストラクタでメンバ変数を初期化するときに{}で囲むと名前付き引数になります。
名前付き引数は省略可能なので、必須項目には@requiredを付けましょう。

タップしたときの処理を追加する

画像をタップしたときに画面遷移するようにしたいんですが、ImageやContainerにはonTapがありません。
そんな場合はGestureDetectorでくるみます。

GestureDetectorは結構いろいろできるので、困ったら見てみるといいと思います。

タップで画面遷移する

onTapの中に遷移処理を書きます。
遷移先のImagePreviewには画像を渡します。

で。
画面遷移時に必要なcontextなんですが、_imageItemは持ってないんですよね。
どこから持ってくるかというと、buildをoverrideしてるいつものやつ。

こいつがBuildContextを持っているので、ここからもらいます。

呼び出すときにも引数にcontextを追加。

以上で実装は完了です。
これを保存してみると…。

それぞれ画像が表示され、タップするとプレビューが表示されるようになりました。
Navigator.pushは遷移先にAppBarがあった場合に戻るボタンを自動で追加してくれるのが便利。

見た目はひとまず終了

本当はまだリツイートが表示されないとかあるんですが、深追いすると終わらないのでとりあえずここまで。
次はボタンをタップ→文字を入力して実際にツイートしてみたいと思います。

ここまでのソースはGitHubでどうぞ。

-プログラミング
-,

© 2024 そんなこと猫でもできる Powered by AFFINGER5