技術メモ

役に立てる技術的な何か、時々自分用の覚書。幅広く色々なことに興味があります。

【Flutter】便利なパッケージ・参考になるサイトまとめ

[随時追記予定] 最終更新(2023/7/21)


Flutterについてある程度慣れてくると、便利なパッケージを組み合わせていかに車輪の再発明をせず開発するかが大事だと思うようになってきた。
そこで、Flutterでの開発を爆速でデザイン性を高くするであろう便利なパッケージをまとめるに至った。
UIに関するパッケージ、開発ツールに関するパッケージの他によく参考にしているサイトを掲載する。
url_launcherやfirebase用SDKなど有名で他に代えがきかないものは除外した。

Package

UI

画像・アイコン

インターネットから画像を取得する時に、非同期で画像を取得したりキャッシュに保存したりするのをうまくやってくれるパッケージ。

スライドショーのように横に画像をスクロールし表示するためのパッケージ。スライドショー(carousel)を実現するパッケージはいくつもあるがこれが一番人気がある様子。

膨大な数のアイコンを提供している、Web開発ではおなじみのfontawesomeをflutter上で実現するためのパッケージ。標準のIconsにはない色々なアイコンが使えるようになる。

LottieをFlutterで実現するためのパッケージ。LottieFiles: Download Free lightweight animations for website & apps.から可愛いアニメーションを見つけて簡単にキャッチーな動くイラストを挿入することができる。

インタラクティブなアニメーションを実現できる。RiveをFlutterで実現するパッケージ。ここまでリッチなアニメーションを作れるのは調べた限りこれが唯一無二だろう。
【Flutter】Riveを使ってインタラクティブなボタンアニメーションを作成し、UXを向上させたい!

フォント

独自でフォント用ファイルを用意しなくても手軽にフォントを適用できる。フォント用のパッケージとしては調べた限り唯一無二だと思われる。
特にフォントにこだわりがないのであれば使っておけば無難かもしれない。

テーマ

自分で細かく色を設定しなくても綺麗なテーマカラーを設定できる。もちろんライトテーマにもダークテーマにも対応。
特にカラーテーマこだわりがないがデフォルトからは変えたいという場合には使うと良いかもしれない。(最近ではMaterial3のデフォルトでそれなりにおしゃれなカラーになるので、Material3を使うならデフォルトでも十分かなと思ってる。)

ローディング、Progress

読込中のアニメーションを詰め込んだパッケージ。デフォルトのクルクルでは物足りないという時にさっと使える。
SpinKitをflutterのパッケージとして提供しているもの。

上記のSpinKitと似たようなもの。SpinKitの方が人気があるようだが、こちらもちらほら使われている。

スクロールするたびにローディングが走るいわゆる無限スクロールを実現するためのパッケージ。無限スクロールについてはいくつもパッケージがあるが、一番人気なのはこれかもしれない。

テキストやカードなどローディング中にとりあえず置いておくキラキラ輝くようなオブジェクト。似たようなものとして"skeltons"というパッケージもあるがこちらのshimmerの方が主流のよう。

入力・ボタン

入力した文字を自動的に"yyyy/mm/dd"の形式にしてくれたりする入力フォームヘルパー

コンテナのサイズに収まるように文字の大きさをうまく縮めて表示してくれる。

アニメーションを伴ったいいねボタンを実現してくれる。

ルーティング

ルーティングのパッケージとしては人気なパッケージ。後述のgo_routerはおそらく後発で、こちらの方が紹介記事は多い印象。

リダイレクトの設定も可能。URIの中にパスパラメータも含める書き方もできる。

その他

開始と終了のコードを書くだけでスプラッシュ画面を簡単に実装するパッケージ。
もちろん非同期なのでスプラッシュ画面の表示中に必要なAPIを叩いたり初期化処理を走らせる事ができる。
プログレスバーを表示したり動きのあるロゴを表示させたりする柔軟性はないのが難点。

Flutterのカレンダー表示では一番人気があるパッケージ。それなりに柔軟に作り込むこともでき、月表示・週表示など形式も自由に切り替える事もできる。

チュートリアル画面でよく見るフォーカスを当てる機能を作り込むパッケージ。記法が少し独特でとっつきにくいかもしれない。

状態管理

Flutterにおける状態管理はそれだけでいくつも記事が書けるほど奥が深く種類も多いが、現在主流となっているのはProvider(riverpod), BLoC, GetX などがある。
状態管理のパッケージについては一つの記事には書ききれない上、他にも優秀な記事が山程あるので自分で書くことは諦めた。個人的にはGetXが好き。
全体像のリストアップは以下が参考になりそう。
zenn.dev

その他

DAO

JSONで来た結果をオブジェクトに変換するためのパッケージ。自前でJSON変換用の関数を書く必要がなくなる。

こちらもjson_serializableと同様JSONで来た結果をオブジェクトに変換するためのパッケージ。
JSON変換用のパッケージとしてはjson_serializableとfreezedのどちらかという感じ。

バグレポート

有償だが高機能で詳細なバグレポートを送信してくれるらしい。使ったことがないので使用感はわからないがスタックトレースまで含めたクラッシュレポートを送信できるサービスとしては有名。
Application Performance Monitoring & Error Tracking Software | Sentry

ユーザー自身がfeedbackを送信する時にスクリーンショット入りでフィードバックを送ることができる。開発メンバー内や試用メンバー内に公開する時にあると便利。

ローカルストレージ

Key-Value型でローカルストレージに値をストレージするためのパッケージ。他にもshared_preferenceが有名だが、それよりも読み書きの速度が早いらしい。

hive, shared_preferenceと並んで使えるKey-Vlue型のローカルストレージがobjectBox。通常stringやboolでしか使えずオブジェクトを持つためには変換する関数を自前で書かないといけないが、objectBoxの記法に従うことでオブジェクトの状態でローカルストレージに保存することができる。
Getting started - ObjectBox Docs

Using Hive instead of SharedPreferences for storing preferences | by Michał Pawlik | Flutter Community | Medium

FlutterでもSQLiteを使える。Key-Valueで事足りる時はhiveまたはshared_preference、それ以上のテーブル形式のローカルストレージを使いたい時はsqliteといった使い方。driftFloorといったパッケージを使えばORMのように使うことができるようになる。


開発ツール

同じPCでflutter2.8, flutter3.10など複数のバージョンのflutterを切り替えて使うためのバージョン管理CLI。日進月歩で進化しているflutterを使いこなすためには必須と言っても過言ではない。"fvm"で調べたらたくさん記事が出てくる。

アプリアイコンを設定・変更するパッケージ。

開発用と本番用でアプリ名を分けたいなどアプリ名を変更するにあたって、手作業で関連ファイルを変更するのは手間だし漏れが発生しうる。そういう時に使うのがこのパッケージ。
似たようなものとしてrenameというパッケージもありこちらは各種プラットフォームに対応しているようだが、あまり有名ではないのか紹介している人は少ない様子だった。

一つのレポジトリで複数のパッケージを管理するための開発ツール。FlutterfireやFlameなど有名なプロジェクトでも採用されているらしい。
【Flutter】melosでマルチパッケージプロジェクトを管理する / Flutter multi package app sample with melos - alpha Lounge

テストデータ用のフェイクデータ(名前、住所、緯度経度、日付、テキスト...)を生成してくれるライブラリ。Flutterだけでなく色々な言語で"Faker"という名称でライブラリが用意されている概念的なものらしい。恥ずかしながら最近まで知らなかった。

参考になるサイト・リポジトリ

Flutterのパッケージを検索できるサイト。
ここで紹介したパッケージもここから検索しているものが多い。

flutterに関する記事や色々な作ってみた系のサンプルを紹介しているサイト。

Flutterが公式で出しているサンプル集。
初学者が標準Widgetでこういうのはどう実装するんだろうと見る時に便利。ソースコードと並べて閲覧できるのも良い。

この記事のように有名なパッケージなどを紹介している。

この記事のように有名なパッケージなどを紹介している。

サンプルコードへのリンクを多数掲載しているリポジトリ

flutter UI challengeと称して色々なデザインのモックを掲載している

複雑な動きでデザイン性の高いサンプルを掲載しているリポジトリ

状態管理ライブラリGetXを使ったFlutterのアーキテクチャのベストプラクティスを示してくれている。


https://raw.githubusercontent.com/phamdinhduc795397/flutter-getx-clean-architecture/main/assets/Clean-Architecture-Flutter-Diagram.png

アニメーションが素晴らしい。Heroアニメーションをふんだんに使用していて良い意味で"Flutterらしさ"がないUIモック。ゼロからここまで作れたらフラッターのアニメーションは極めたと言っても過言ではないかもしれない。





番外編

ここからは番外編。気になったものの取り立てて紹介するほどでもないという物を集めた。
面白そうとは思ったもののメンテされていなかったり使い道が限られるものを番外編とする。

MicrosoftがかかげるFluent UIをFlutterで実現する非公式のUIフレームワーク。用意されているWidgetも多くこれを使えばMicrosoft風の見た目のアプリを作ることができる。
あまり使われている様子がない&Flutter3.10から標準化されているMaterial3を使えば十分なので番外編とした。
参考:https://developer.microsoft.com/ja-jp/fluentui

デザイン性の高い出来あいのWidgetを集めたUIフレームワーク。私自身触っていないのでよくわからないが、もしかしたら標準Widgetで事足りるかもしれない。あまり使われている様子がない&Flutter3.10から標準化されているMaterial3を使えば十分なので番外編とした。

xtermをFlutterで実現する。mobileプラットフォームでもサポートしたらしい。
面白そうだが使い道は全くないので番外編にした。

アニメーションやナビゲーションなどを含め必要最低限で高速にUIを組むことを目的にしているUIフレームワーク
慣れれば早いのかもしれないが公式ドキュメントをパッと見た感じ学習コストが低いわけではく標準Widgetを使うのと大差がなさそうなので番外編にした。興味のある人は見てみると良いかもしれない、実はめっちゃ使いやすいのかもしれない。

ネオンのようなUIを実現できるライブラリ。
面白そうだが使い道はなさそうなので番外編にした。

WIndows95風の見た目を実現できるUIライブラリ。
面白そうだが使い道はなさそうなので番外編にした。

neumorphicなデザインをflutterで実現するUIフレームワーク
少し触ってみた感想としては、フレームワーク独特の記法が多く自分でソースを調べる能力がないと使いこなすのは厳しそうなので番外編にした。
neumorphic_buttonも気になる。

個人的に気になるパッケージ。使いどころは限られるので番外編にした。

投票・結果表示をするライブラリ。使いどころは限られるので番外編にした。

チャット画面を簡単に作るライブラリ。簡単にサクッと作れる分カスタマイズが難しそうではある。個人開発やモック開発等で簡単に作るには良いが使い所が限られるので番外編にした。

FlutterでAPIをコールしBLoCで状態管理をしながら非同期で表示まで一通りできるニュースアプリのソースコードを公開してくれているリポジトリ。Mockitoを使ったテストコードまで掲載してくれている。
メンテは止まっているようなので番外編にした。

Dartで標準関数にない便利な関数などを用意してくれているエクステンション。メールアドレスかどうかの判定、大文字小文字変換、うるう年判定など。一度pubdevを眺めてみると良いかもしれない。似たようなものにdartxがある。
便利そうではあるものの個人的にはあえてこれを使うほどでもないかと判断したので番外編にした。

assetsフォルダにアセットを配置すると一発でクラスを生成してくれるCLIツール。アセットを多用するプロジェクトには便利かもしれない。
便利そうではあるものの個人的にはあえてこれを使うほどでもないかと判断したので番外編にした。

2進数を使って(表裏/オンオフ)数え上げ

N枚のコインを同時に投げる場合やN人のYES/NOの数え上げなどがしたい時は、
2**N通りのパータンを2進数に変換してしてからパターンを作ると良い。
具体的には、
0~2**N-1までの数字を10進数⇒2進数表記に文字列として変換したのち、文字列をリストと考えて処理する。
ただし、桁数分ゼロ埋めする必要がある。

for i in range(2**n):
    pattern1 = list(map(int, bin(i)[2:].zfill(n)))
    pattern2 = list(map(int, format(i, '0'+str(n)+'b')))

itertoolsを使う方法

itertools.product([0,1], repeat=n)

リストの組み合わせをすべて列挙する

src = [1,2,3,4,5]
for i in itertools.product([0,1], repeat=len(src)):
    combination = [j for j in itertools.compress(src, i)]
    print(combination)

output:

[]
[5]
[4]
[4, 5]
[3]
[3, 5]
[3, 4]
[3, 4, 5]
[2]
[2, 5]
[2, 4]
[2, 4, 5]
[2, 3]
[2, 3, 5]
[2, 3, 4]
[2, 3, 4, 5]
[1]
[1, 5]
[1, 4]
[1, 4, 5]
[1, 3]
[1, 3, 5]
[1, 3, 4]
[1, 3, 4, 5]
[1, 2]
[1, 2, 5]
[1, 2, 4]
[1, 2, 4, 5]
[1, 2, 3]
[1, 2, 3, 5]
[1, 2, 3, 4]
[1, 2, 3, 4, 5]

pythonのargsとkwargsの使い方色々

※実行環境 python3.6

########### 基本的なargs
def argsfunc(*args):
    return args[0] + args[1]
print(argsfunc(1,2))
# print(argsfunc(dog=1, cat=2)) 引数名を与えるとargsとして認識してくれない

########### 基本的なkwargs
def kwargsfunc(**kwargs):
    return kwargs["a"] + kwargs["b"]
print(kwargsfunc(a=1,b=2))

def multifunc(*args, **kwargs):
    return args[0] + args[1] + kwargs["a"]
print(multifunc(1,2,a=3,b=4))

########### デフォルト引数と併用するケース
def multifunc2(first, second=0, *args, **kwargs):
    return first + second + args[0] + kwargs["a"]
print(multifunc2(1,2,3,a=4)) #>10
# print(multifunc2(1, second=2, 3, a=3)) #ダメ。変数指定して渡すのは全て後に書かないといけない

def multifunc2_2(first, *args, second=0, **kwargs):
    print("second: {}".format(second), end="| ")
    return first + second + args[0] + kwargs["a"]
print(multifunc2_2(1, 3, second=2, a=3)) 
print(multifunc2_2(1, 3, 2, a=3)) #>7 #3番目の引数はsecond=2のつもりなのにargs[1]として認識されてしまう


def multifunc3(first, second=0, **kwargs):
    return first + second + kwargs["a"]
print(multifunc3(1,2,a=3))
print(multifunc3(1,second=2,a=3))


############ キーワードが重複するケース # 定義だけではエラーにならない。呼び出そうとするとTypeError
def duplicate_kwargs(first, second=0, **kwargs):
    return first + second + kwargs["first"]
# print(duplicate_kwargs(1,2,first=3)) 
# >TypeError: duplicate_kwargs() got multiple values for argument 'first'

############ 可変長引数の重複はSyntaxError
# def kwargs_duplicate(**kw1, **kw2):
#    return kw1["a"] + kw1["b"] + kw2["a2"]

############ 可変長引数が引数の前に来るのはSyntaxError
# def kwargs_head(**kw1, second=0):
#    return first + second + kw1["a"]

############ argsを先に使うと、後ろの変数は全て変数指定して渡さないといけなくなる
def args_head(*args, first, second=0):
    return first + args[0] + second
# print(args_head(3,1,2)) #変数名を指定しない場合全部argsとして認識されるのでfirstが無いと怒られる
print(args_head(3,first=1,second=2)) #OK