買い物リストアプリを作成中に、買い物リストは「食品」「日用品」の2タブ構成。並び替えボタンを押したとき、表示中のタブのリストだけを並び替え画面に渡したい。
と思ったので実装していきます。
1. TabController を用意
class _ShoppingPageState extends State<ShoppingPage>
with SingleTickerProviderStateMixin {
late TabController _tabController;
@override
void initState() {
super.initState();
_tabController = TabController(length: 2, vsync: this);
}
}
SingleTickerProviderStateMixinはTabControllerのアニメーションに必要です。
2. TabBar に紐づける
AppBar(
title: const Text('買い物リスト'),
bottom: CategoryTab(controller: _tabController),
),
body: TabBarView(
controller: _tabController,
children: [
ItemList(items: foodItems, onToggle: _toggleCheck),
ItemList(items: dailyItems, onToggle: _toggleCheck),
],
),
3. 表示中のタブ index を取得
final currentCategory = _tabController.index == 0
? Category.food
: Category.daily;
4. タブに応じたリストを渡す
onSort: () async {
final currentCategory = _tabController.index == 0
? Category.food
: Category.daily;
final currentItems = currentCategory == Category.food
? foodItems
: dailyItems;
final sortedItems = await Navigator.push<List<ShoppingItem>>(
context,
MaterialPageRoute(
builder: (_) => ReorderPage(items: currentItems),
),
);
if (sortedItems == null) return;
await FirebaseFirestore.instance
.collection('userOrders')
.doc(uid)
.set({
currentCategory.name: sortedItems.map((e) => e.id).toList(),
}, SetOptions(merge: true));
},
5. フィルター中は並び替えを無効化
フィルター適用中(全て以外)は並び替えボタンを無効にしています。
BottomActionBar(
onAdd: () async { /* ... */ },
onSort: filter != 'all' ? null : () async { /* 並び替え処理 */ },
)
まとめ
_tabController.index で表示中タブを取得し、対応するリストだけ並び替え画面に渡す。タブとFirestoreの保存キーをenumで対応させると見通しが良くなります。