はじめに
業務ではバックエンド開発を行っており、趣味でFlutterを触っています。
Flutterで開発を行う際に、pub.devで良さげなパッケージを探すことは少なくはないのでしょうか。そこで、本稿では個人的に使ってみて良かったパッケージを5つ紹介します。
もくじ
- カルーセル:carousel_slider
- スプラッシュスクリーン:flutter_native_splash
- URLサポート:url_launcher
- スケルトンスクリーン:shimmer
- ページネーション:paginate_firestore
環境
$ flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 2.0.6, on macOS 11.4 20F71
darwin-x64, locale ja-JP)
[✓] Android toolchain - develop for Android devices (Android
SDK version 29.0.3)
[✓] Xcode - develop for iOS and macOS
[✓] Chrome - develop for the web
[✓] Android Studio (version 3.5)
[✓] VS Code (version 1.61.1)
[✓] Connected device (2 available)
$ dart --version
Dart SDK version: 2.10.4 (stable) (Wed Nov 11 13:35:58 2020 +0100) on "macos_x64"
carousel_slider
無限スクロールやカスタムウィジェットの利用、オートプレイが行えます。
また、オプションによってループさせたりアクティブとなった画像のスケールアップなどが可能となります。
導入例
CarouselSlider
クラスのフィールドで保持しているCarouselOptions
によってオプションの指定ができます。
class CarouselSlider extends StatefulWidget {
/// [CarouselOptions] to create a [CarouselState] with
///
/// This property must not be null
final CarouselOptions options;
/// The widgets to be shown in the carousel of default constructor
final List<Widget> items;
/// The widget item builder that will be used to build item on demand
/// The third argument is the PageView's real index, can be used to cooperate
/// with Hero.
final ExtendedIndexedWidgetBuilder itemBuilder;
/// A [MapController], used to control the map.
final CarouselControllerImpl _carouselController;
final int itemCount;
CarouselSlider(
{@required this.items,
@required this.options,
carouselController,
Key key})
: itemBuilder = null,
itemCount = items != null ? items.length : 0,
_carouselController = carouselController ?? CarouselController(),
super(key: key);
/// The on demand item builder constructor
CarouselSlider.builder(
{@required this.itemCount,
@required this.itemBuilder,
@required this.options,
carouselController,
Key key})
: items = null,
_carouselController = carouselController ?? CarouselController(),
super(key: key);
@override
CarouselSliderState createState() => CarouselSliderState(_carouselController);
}
デフォルトコンストラクタでは以下のような設定がされています。
import 'package:flutter/material.dart';
enum CarouselPageChangedReason { timed, manual, controller }
enum CenterPageEnlargeStrategy { scale, height }
class CarouselOptions {
// コンストラクタのみ抜粋
CarouselOptions({
this.height,
this.aspectRatio: 16 / 9,
this.viewportFraction: 0.8,
this.initialPage: 0,
this.enableInfiniteScroll: true,
this.reverse: false,
this.autoPlay: false,
this.autoPlayInterval: const Duration(seconds: 4),
this.autoPlayAnimationDuration = const Duration(milliseconds: 800),
this.autoPlayCurve: Curves.fastOutSlowIn,
this.enlargeCenterPage = false,
this.onPageChanged,
this.onScrolled,
this.scrollPhysics,
this.pageSnapping = true,
this.scrollDirection: Axis.horizontal,
this.pauseAutoPlayOnTouch: true,
this.pauseAutoPlayOnManualNavigate: true,
this.pauseAutoPlayInFiniteScroll: false,
this.pageViewKey,
this.enlargeStrategy: CenterPageEnlargeStrategy.scale,
this.disableCenter: false,
});
}
導入例は以下のようにカルーセルを実装しており、enlargeCenterPage
・autoPlay
・enlargeCenterPage
を変更しています。
@override
Widget build(BuildContext context) {
return Container(
child: CarouselSlider.builder(
options: CarouselOptions(
height: 160.0,
autoPlay: true,
disableCenter: true,
enlargeCenterPage: true,
),
itemCount: documents.length,
itemBuilder: (BuildContext context, int index, int realIndex) {
// 省略
}
flutter_native_splash
アプリ起動時にデフォルトだと真っ白な画面が表示されます。
そこで、好みの色や画像を表示させるためにこちらのパッケージを利用します。
このパッケージは、Dartファイル上でimportして使うのではなくpubspec.yaml
かflutter_native_splash.yaml
に設定を記述することで適応できます。
背景色や画像以外にも、ダークテーマ時の設定やOS毎で位置設定もできます。
詳細はドキュメントを御覧ください。
dev_dependencies:
flutter_native_splash: ^1.3.2
flutter_native_splash:
#背景色の指定
color: "#42a5f5"
#背景画像の指定
background_image: "assets/background.png"
設定を記述したあとは、以下コマンドを実行します。
$ flutter pub run flutter_native_splash:create
ちなみに、pub.devで動画によるチュートリアルも紹介されています。
url_launcher
外部ブラウザでURLにアクセスする以外にも、スキーマを指定することで電話の発信・メール作成・SMS送信もできるようになります。
import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';
const String _url = 'https://flutter.dev';
void main() => runApp(
const MaterialApp(
home: Material(
child: Center(
child: RaisedButton(
onPressed: _launchURL,
child: Text('Show Flutter homepage'),
),
),
),
),
);
void _launchURL() async {
if (!await launch(_url)) throw 'Could not launch $_url';
}
shimmer
コンテンツの読み込み中にワイヤーフレームのようなウェジェットを表示させ、スケルトンスクリーンを簡単に実装することができます。
導入例
同じくスケルトンスクリーンを導入する際に検討したパッケージにflutter_shimmer
がありました。
個人的に感じた両パッケージの違いは、柔軟性の有無にあるかと思います。
導入例でも使っていたshimmer
のほうがより柔軟な印象でした。
Shimmer
は適応するウィジェットを自作できるのに対し、flutter_shimmer
はパッケージで準備されたモード(典型的なUIの雛形のようなもの)を選択します。flutter_shimmer
のほうが導入は簡単ですが、読み込み後に表示されるウィジェットとデザインの差異が生じることがあるので、実装コストやデザインを天秤にかけて採用パッケージを決めると良いかもしれません。
以下はshimmer
を使った実装の例です。
読み込み後に表示させるウィジェットを元にSizeBoxでサイズを指定することで、違和感なく見た目を整えることができます。
import 'package:shimmer/shimmer.dart';
class ShimmerImage extends StatelessWidget {
const ShimmerImage({
Key key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Padding(
padding: EdgeInsets.symmetric(horizontal: 10),
child: ClipRRect(
borderRadius: BorderRadius.circular(4.0),
child: SizedBox(
width: 280,
height: 160,
child: Shimmer.fromColors(
baseColor: Colors.grey[300],
highlightColor: Colors.grey[100],
child: Container(
color: Colors.grey,
),
),
),
),
);
}
}
paginate_firestore
パッケージ内部でFireStoreをいい感じにラップしてくれて、ページネーション機能を簡単に使えるようにしてくれます。
itemsPerPage
でページあたりの読み込み数を指定し、itemBuilderType
で以下の3つからビルダータイプを選択します。
enum PaginateBuilderType { listView, gridView, pageView }
簡単な実装例は以下の通りです。
class WatchedWorkList extends StatelessWidget {
@override
Widget build(BuildContext context) {
return SafeArea(
child: PaginateFirestore(
itemsPerPage: 10,
itemBuilderType: PaginateBuilderType.listView,
shrinkWrap: true,
itemBuilder: (index, context, documentSnapshot) {
final data = documentSnapshot.data();
Work work = Work.fromMap(data);
// 省略
}
query: FirebaseFirestore.instance
.collection('user')
.doc("xxxxxxxxxxxxxxxxxxxxx")
.collection("watched")
.orderBy('id'),
isLive: true,
),
);
}
}
最後に
パッケージを導入する際はNull safety
に対応していることや、Flutter Favorite
バッチの有無にも注目してみると良いかもしれません。