はじめに
前回はFlutter Widget of the Weekの「#82 AboutDialog」、「#83 async」、「#84 url_launcher」を紹介しました。
今回はその続きで「#85 sqflite」、「#86 SliverAppBar」、「#87 InteractiveViewer」の3つです。
前回の記事はこちら
またGitHubにも公開しています。
GitHub - nobushiueshi/flutter_widget_of_the_week
Contribute to nobushiueshi/flutter_widget_of_the_week development by creating an account on GitHub.
Flutter Widget of the Week
環境
- Flutter 3.3.3
記事にした時点でのバージョンです。GitHubに公開しているのは常に最新の安定版(stable)を使う予定です。
#85 sqflite
sqfliteとは
FlutterでSQLiteを扱うためのパッケージです。
このパッケージを使うことでデータを永続化できます。
サンプルコード
import 'package:flutter/material.dart';
import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';
class SamplePage085 extends StatefulWidget {
const SamplePage085({
super.key,
});
@override
State<SamplePage085> createState() => _SamplePage085State();
}
class _SamplePage085State extends State<SamplePage085> {
final String databaseName = 'sample.db';
final List<String> migrationScripts = [
'CREATE TABLE test (id INTEGER PRIMARY KEY, name TEXT)',
];
Database? db;
List<Map<String, Object?>>? maps = [];
@override
void initState() {
super.initState();
Future(() async {
final databasesPath = await getDatabasesPath();
final path = join(databasesPath, databaseName);
db = await openDatabase(
path,
version: migrationScripts.length,
onCreate: (database, version) async {
debugPrint('onCreate');
for (var i = 0; i < version; i++) {
await database.execute(migrationScripts[i]);
}
},
onUpgrade: (database, oldVersion, newVersion) async {
debugPrint('onUpgrade');
for (var i = oldVersion; i < newVersion; i++) {
await database.execute(migrationScripts[i]);
}
},
);
await query();
});
}
Future<void> query() async {
maps = await db?.rawQuery('SELECT * FROM Test');
setState(() {});
}
Future<void> increment() async {
await db?.transaction<void>((txn) async {
await txn.rawInsert(
// ignore: lines_longer_than_80_chars
'INSERT INTO Test(name) VALUES("${DateTime.now().toLocal().toString()}")',
);
});
await query();
}
@override
void dispose() {
Future(() async {
await db?.close();
});
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('sqflite'),
centerTitle: true,
),
body: SafeArea(
child: ListView.builder(
itemCount: maps?.length ?? 0,
itemBuilder: (context, index) {
final map = maps![index];
final id = map['id'] ?? 0;
final name = map['name'] ?? '';
return ListTile(
title: Text('id : $id'),
subtitle: Text('$name'),
dense: true,
);
},
),
),
floatingActionButton: FloatingActionButton(
onPressed: increment,
child: const Icon(Icons.add),
),
);
}
}
結果
データを追加後、アプリを再起動してもデータが残っています。
動画
公式リファレンス
sqflite | Flutter package
Flutter plugin for SQLite, a self-contained, high-reliability, embedded, SQL database engine.
#86 SliverAppBar
SliverAppBarとは
アプリのヘッダーであるAppBarをスクロールで変化させたり、消したりしたい場合はSliverAppBarを使います。
SliverAppBarは主にCustomScrollViewやNestedScrollViewと共に利用します。
Flutter Widget of the Weekの初期の頃に紹介されています。まさかの2回目です。
サンプルコード
import 'package:flutter/material.dart';
class SamplePage086 extends StatelessWidget {
const SamplePage086({
super.key,
});
@override
Widget build(BuildContext context) {
return Scaffold(
body: CustomScrollView(
slivers: <Widget>[
SliverAppBar(
expandedHeight: 200,
stretch: true,
floating: true,
flexibleSpace: const FlexibleSpaceBar(
title: Text('SliverAppBar'),
background: FlutterLogo(
size: 256,
),
stretchModes: <StretchMode>[
StretchMode.zoomBackground,
StretchMode.blurBackground,
StretchMode.fadeTitle,
],
),
onStretchTrigger: () async {
debugPrint('onStretchTrigger');
},
),
SliverFixedExtentList(
delegate: SliverChildBuilderDelegate((context, index) {
return Container(
alignment: Alignment.center,
color: Colors.blue[100 * (index % 9)],
child: Text('List Item $index'),
);
}),
itemExtent: 50,
),
],
),
);
}
}
結果
SliverAppBarが伸びたり、スクロールすると見えなくなります
動画
公式リファレンス
SliverAppBar class - material library - Dart API
API docs for the SliverAppBar class from the material library, for the Dart programming language.
#87 InteractiveViewer
InteractiveViewerとは
InteractiveViewerを使うことでウィジェットの拡大や縮小やパンができます。
サンプルコード
import 'package:flutter/material.dart';
class SamplePage087 extends StatelessWidget {
const SamplePage087({
super.key,
});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('InteractiveViewer'),
centerTitle: true,
),
body: SafeArea(
child: Center(
child: InteractiveViewer(
child: const FlutterLogo(
size: 512,
),
),
),
),
);
}
}
結果
ピンチインするとFlutterのロゴが拡大できます。
動画
公式リファレンス
InteractiveViewer class - widgets library - Dart API
API docs for the InteractiveViewer class from the widgets library, for the Dart programming language.
さいごに
このシリーズ、終りが見えない。。。
そして追いつく前にYouTubeのFlutter Widget of the Weekが終わってしまい、悲しみ。
おすすめ参考書
リンク
GitHub - nobushiueshi/flutter_widget_of_the_week
Contribute to nobushiueshi/flutter_widget_of_the_week development by creating an account on GitHub.
コメント