Flutter 建立自己的對話方塊,不使用任何包!
建立自己的對話方塊,不使用任何包!
原文 https://itnext.io/create-your-own-dialog-without-using-any-packages-7bb303f62471
前言
在本文中,我們將學習如何建立我們自己的 showDialog() 函式,並瞭解到底發生了什麼。
正文
先看效果
讓我們首先檢查 showDialog,看看它裡面有什麼!
正如您所看到的,showDialog ()所做的就是獲取小部件並將其作為 DialogRoute 使用 Navigator 進行推送。沒什麼特別的!
因此,如果我們想建立一個對話方塊,我們應該使用導航器和路由,太!
但什麼是導航器,為什麼我們需要它的對話?
沒錯,導航器也是個 widget !
畢竟,一切都是一個 widget ,甚至是我,甚至是你,甚至是導航器本身ー匿名 Flutter 開發人員
本質上,Navigator 的工作是管理一堆 Route 物件,並在 Overlay widget 中的 widget 之間進行視覺化切換。
什麼是疊加,為什麼它很重要?
基本上,Overlay 是一種特殊的 Stack widget ,它將應用程式包裝在導航器中。
正如您所猜測的,Dialogs 僅僅是 UI 之上的 widget (就像吐司 widget 一樣) ,但在這種情況下,導航器明智地使用 Routes 控制它們。這就是為什麼他們讓我們感覺像別的東西。
是的,我們也可以僅僅使用 Overlay widget 建立我們自己的 widget ,但是我們也想與導航器互動,因為我們不想重新發明輪子!如果我們不用領航員的話。我們必須處理所有的過渡、生命週期、後退按鈕、可取消的障礙等等。
這就是為什麼我們也應該知道路線!
記住,showDialog() 也使用 DialogRoute 是有原因的。
但是對話路由有什麼特別之處呢?
對話路由繼承模式
對話路線的超能力來自於它的祖先! 讓我來告訴你怎麼做!
讓我們看看,在每一步,我們繼承了什麼!
``` Route -> A basic route
“Route is a base class that interacts with the navigator.” OverlayRoute -> A route that knows how to interact with Overlay
“A route that displays widgets in the Navigator’s Overlay.” TransitionRoute -> A route that can do a magic trick
“A route with entrance and exit transitions.” ModalRoute -> A route that has a barrier behind it
“A route that blocks interaction with previous routes.” PopupRoute -> A route that shows up over the current route
“A modal route that overlays a widget over the current route.” RawDialogRoute -> A pre-configured route for dialogs
“A general dialog route which allows for customization of the dialog popup.” DialogRoute -> A ready-to-use, pre-designed route
“A dialog route with Material entrance and exit animations, modal barrier color, and modal barrier behavior” ```
(這些句子都參考了官方的 api 文件。)
這裡的教訓是: 當我們呼叫 showDialog() ,它呼叫導航器.push() ,當導航器推動某些東西,如果它是 PopupRoute,它得到生命週期(來自導航器) ,家庭(來自 OverlayRoute) ,過渡(來自過渡路線) ,障礙(來自 ModalRoute) ,並出現在路線上(來自自身)。
無論如何,如果我們得到了主要的想法,讓我們看看程式碼,並學習如何建立我們自己的對話方塊!
對話方塊例子
1. 設計一個對話方塊
建立自己的對話方塊小部件
```dart // Just a simple custom dialog, nothing special class CustomDialog extends StatelessWidget { const CustomDialog({ super.key, required this.title, required this.description, required this.confirmText, this.onTap, });
final String title; final String description; final String confirmText; final void Function()? onTap;
@override Widget build(BuildContext context) { return Center( child: Padding( padding: const EdgeInsets.all(32), child: Material( elevation: 4, borderRadius: const BorderRadius.all(Radius.circular(16)), child: Padding( padding: const EdgeInsets.all(24), child: Column( mainAxisSize: MainAxisSize.min, children: [ Text( title, style: const TextStyle( fontSize: 20, fontWeight: FontWeight.bold, ), ), const SizedBox(height: 12), Text( description, style: const TextStyle(color: Colors.grey), ), const SizedBox(height: 32), SizedBox( width: double.infinity, child: CupertinoButton.filled( onPressed: onTap, child: Text(confirmText), ), ), ], ), ), ), ), ); } } ```
2. 建立自己的對話方塊
在這個例子中,我將使用 PopupRoute 來製作我自己的配置。如果需要預先配置的 Dialogs,可以使用 RawDialogRoute 或 DialogRoute,就像 showDialog ()所做的那樣。
```dart
// Custom Dialog implementation
class CustomDialogRoute
@override
Widget buildPage(
BuildContext context,
Animation
@override
Widget buildTransitions(
BuildContext context,
Animation
@override Color? get barrierColor => Colors.black.withOpacity(.65);
@override bool get barrierDismissible => true;
@override String? get barrierLabel => 'CustomDialog';
@override Duration get transitionDuration => const Duration(milliseconds: 250); } ```
3. 為可重用程式碼建立 showCustomDialog 方法
為了讓事情變得更簡單,我把它變成了一種延伸。
dart
extension DialogExtension on BuildContext {
Future<T?> showCustomDialog<T extends Object?>(
Widget child, {
RouteSettings? settings,
}) {
return Navigator.of(this).push<T>(
CustomDialogRoute<T>(
builder: (_) => child,
settings: settings,
),
);
}
}
4. 想在哪裡用就在哪裡用!
```dart class HomePage extends StatelessWidget { const HomePage({super.key});
@override Widget build(BuildContext context) { return Scaffold( body: Center( child: ElevatedButton( onPressed: () { context.showCustomDialog( CustomDialog( title: 'Hello Fellow!', description: "Don't you think Flutter is awesome?", confirmText: 'Absolutely!', onTap: () { debugPrint('agreed'); Navigator.pop(context); }, ), ); }, child: const Text('Show Dialog'), ), ), ); } } ```
程式碼
https://github.com/rei-codes/custom_dialog_example
結束語
如果本文對你有幫助,請轉發讓更多的朋友閱讀。
也許這個操作只要你 3 秒鐘,對我來說是一個激勵,感謝。
祝你有一個美好的一天~
© 貓哥
-
微信 ducafecat
-
https://wiki.ducafecat.tech
-
https://video.ducafecat.tech
- Flutter 中使用 OpenAI GPT-3 進行語義化處理
- Flutter 構建設計系統
- Flutter ー Authentication 認證
- Flutter 離線資料方案 Flutter_Data 包
- 基於 Hive 的 Flutter 文件型別儲存
- Flutter AlarmManager = ⏰
- Flutter 8 個優秀動畫 Packages
- Flutter 建立自己的對話方塊,不使用任何包!
- 在 Flutter App 中編寫自定義平臺特定程式碼[Method Channel]
- Flutter 最有用的 5 個優秀的依賴包
- Neumorphism 元件 ーー Dart extension 擴充套件
- 用抽象工廠方法構建 Flutter 主題
- Dart 語言的7個很酷的特點
- 17 個提高效能的 Flutter 最佳實踐
- Flutter 應用程式建立一個擴充套件面板列表
- 在 Flutter 使用 GetX 對話方塊
- flutter 互動式使用者指導,以及如何在佈局中創造一個洞
- Flutter開源專案 - appFlowy 真的是 Notion 的替代品? 一週暴漲 star 9k 多!
- 桌面 Flutter 應用程式
- Flutter 2020 開源專案推薦 第一彈