🍏
Cupertino widgets④
長押しすると表示されるモーダル
はい。タイトルの通り長押しすると表示されるモーダルをCupertinoContextMenu classで作ることができます。こちらはサンプルコードがあったので、サンプルコードがなかったCupertinoContextMenuAction classを使ってみようと思います。
Use CupertinoContextMenu
CupertinoContextMenu
を使用して、iOS風の長押しメニューを実装するデモを作成します。写真や投稿に対するアクションメニューを例として実装してみましょう。
example
import 'package:flutter/cupertino.dart';
import 'package:flutter/services.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
Widget build(BuildContext context) {
return const CupertinoApp(
debugShowCheckedModeBanner: false,
theme: CupertinoThemeData(brightness: Brightness.light),
home: ContextMenuDemo(),
);
}
}
class ContextMenuDemo extends StatelessWidget {
const ContextMenuDemo({super.key});
Widget build(BuildContext context) {
return CupertinoPageScaffold(
navigationBar: const CupertinoNavigationBar(
middle: Text('コンテキストメニューデモ'),
),
child: SafeArea(
child: ListView(
padding: const EdgeInsets.all(16),
children: [
// テキストのコンテキストメニュー
const Text(
'テキストを長押ししてみてください',
textAlign: TextAlign.center,
),
const SizedBox(height: 16),
CupertinoContextMenu(
actions: <CupertinoContextMenuAction>[
CupertinoContextMenuAction(
onPressed: () {
Clipboard.setData(const ClipboardData(
text: 'これはサンプルテキストです。長押しでコピーできます。',
));
Navigator.pop(context);
},
trailingIcon: CupertinoIcons.doc_on_doc,
child: const Text('コピー'),
),
CupertinoContextMenuAction(
onPressed: () {
Navigator.pop(context);
},
trailingIcon: CupertinoIcons.share,
child: const Text('共有'),
),
],
child: Container(
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: CupertinoColors.systemGrey6,
borderRadius: BorderRadius.circular(8),
),
child: const Text(
'これはサンプルテキストです。長押しでコピーできます。',
style: TextStyle(fontSize: 16),
),
),
),
const SizedBox(height: 32),
// カスタムカードのコンテキストメニュー
const Text(
'カードを長押ししてみてください',
textAlign: TextAlign.center,
),
const SizedBox(height: 16),
CupertinoContextMenu(
actions: <CupertinoContextMenuAction>[
CupertinoContextMenuAction(
onPressed: () {
Navigator.pop(context);
},
trailingIcon: CupertinoIcons.pencil,
child: const Text('編集'),
),
CupertinoContextMenuAction(
onPressed: () {
Navigator.pop(context);
},
trailingIcon: CupertinoIcons.bookmark,
child: const Text('ブックマーク'),
),
CupertinoContextMenuAction(
onPressed: () {
Navigator.pop(context);
},
trailingIcon: CupertinoIcons.share,
child: const Text('共有'),
),
CupertinoContextMenuAction(
isDestructiveAction: true,
onPressed: () {
Navigator.pop(context);
},
trailingIcon: CupertinoIcons.delete,
child: const Text('削除'),
),
],
child: Container(
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: CupertinoColors.systemGrey6,
borderRadius: BorderRadius.circular(8),
border: Border.all(
color: CupertinoColors.systemGrey4,
width: 1,
),
),
child: const Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Text(
'カスタムカード',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
SizedBox(height: 8),
Text(
'これはカスタムカードのサンプルです。長押しで様々なアクションを実行できます。',
style: TextStyle(fontSize: 14),
),
],
),
),
),
],
),
),
);
}
}
このデモでは以下の2つのコンテキストメニューの例を実装しています:
- テキストのコンテキストメニュー
- コピー(クリップボードにコピー)
- 共有
- カスタムカードのコンテキストメニュー
- 編集
- ブックマーク
- 共有
- 削除(破壊的アクション)
主な特徴:
- アクションの種類
CupertinoContextMenuAction(
onPressed: () { /* アクション */ },
trailingIcon: CupertinoIcons.heart, // アイコンの追加
child: const Text('いいね'),
)
- 破壊的アクション
CupertinoContextMenuAction(
isDestructiveAction: true, // 赤色で表示
onPressed: () { /* アクション */ },
child: const Text('削除'),
)
- 実用的な機能
// クリップボードへのコピー
Clipboard.setData(const ClipboardData(text: 'テキスト'));
- カスタマイズ可能なデザイン
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),
// その他のスタイリング
),
child: /* コンテンツ */,
)
使用シーン:
- SNSアプリ
- 投稿の操作
- コメントの操作
- プロフィール情報の操作
- メッセージアプリ
- メッセージの操作
- 添付ファイルの操作
- 連絡先の操作
- ドキュメントアプリ
- テキストの編集操作
- ファイルの操作
- フォルダの操作
注意点:
- メニューが開いている時は必ず閉じる方法を提供
onPressed: () {
Navigator.pop(context); // メニューを閉じる
}
- 適切なアイコンの選択
- 破壊的アクションの慎重な使用
- アクセシビリティへの配慮
このように、CupertinoContextMenu
はiOSスタイルのアプリで直感的な操作を提供するのに役立ちます。
Discussion