Flutter3.7版本新增元件-Menu菜單系列介紹
theme: juejin
之前Flutter
的選單選擇、下拉選單的支援非常簡單且不友好,對於非常常見的下拉選單選擇功能是需要自己自定義實現,今天看到Flutter3.7
版本新增了一系列選單的元件,馬上來試試。
選單元件介紹
本次Flutter
穩定版本菜單系列元件新增了 MenuAnchor
、MenuBar
、SubmenuButton
、MenuItemButton
元件, 這四個元件可以單獨使用也可以相互配合使用。他們都位於menu_anchor.dart
檔案內,下面對這幾個元件詳細介紹下。
MenuAnchor元件
這是一個具有子選單的獨立區域元件,點進去我們可以看到是一個StatefulWidget
元件, 這四個元件除了MenuBar
是靜態元件,其他都是動態元件。
說明我們可以當作普通的Widget
元件去使用它們,MenuAnchor
可以獨立使用,通過這一個元件可以簡單的實現下拉選單的功能。
建構函式:
dart
const MenuAnchor({
super.key,
this.controller,// 控制器
this.childFocusNode,//如果選單是輸入框,焦點控制
this.style, //選單樣式
this.alignmentOffset = Offset.zero,//相對於元件左下角位置
this.clipBehavior = Clip.none,// 超出螢幕剪下 不常用
this.anchorTapClosesMenu = false,// 設定為true時,選單開啟時,點選會重複開啟。
this.onOpen,//打開回調
this.onClose,//關閉回撥
this.crossAxisUnconstrained = true,
required this.menuChildren,//下拉選單列表
this.builder,//元件本身,通常是控制選單的按鈕
this.child,//傳遞給上方builder裡的child元件
});
官方示例:
官方示例選單後面的字母是自定義快捷鍵的操作,我們重點看下選單的聯動功能,選單聯動是和
SubmenuButton
實現的,例如官方示例中的設定背景色的選單就是使用它實現的。接下來介紹下這個元件。
SubmenuButton 聯級選單按鈕
通過這個按鈕可以實現選單的聯級呼叫,一般用來該選項下還有下級選單時使用。該元件一般和MenuAnchor
和MenuBar
配合使用。
dart
const SubmenuButton({
super.key,
this.onHover,//按鈕是否選中回撥 在pc端屬於滑鼠指標在此選單上
this.onFocusChange,//是否獲取焦點回調
this.onOpen,//開啟下級選單回撥
this.onClose,//關閉下級選單回撥
this.style,//按鈕本身樣式
this.menuStyle,//下級選單樣式
this.alignmentOffset,//相對位置偏移量 預設和元件上邊對齊
this.clipBehavior = Clip.none,
this.focusNode,
this.statesController,//元件狀態擴充套件
this.leadingIcon,//左邊可選圖示
this.trailingIcon,//右邊可選圖示
required this.menuChildren,//聯級選單
required this.child,//元件本身
});
MenuItemButton 選單按鈕元件
具體選單的選項,一般選單選項沒有下一級選單時具有具體的功能使用,通過構造方法可以自定義快捷鍵,快捷鍵功能一般在PC端上使用。
構造方法:
dart
const MenuItemButton({
super.key,
this.onPressed,//點選事件
this.onHover,//選中回撥
this.requestFocusOnHover = true,//指標懸停是否聚焦
this.onFocusChange,//是否獲取焦點回調
this.focusNode,//焦點控制
this.shortcut,//快捷鍵設定
this.style,//本身樣式
this.statesController,//元件狀態擴充套件
this.clipBehavior = Clip.none,
this.leadingIcon,//...
this.trailingIcon,//...
required this.child,//...
});
MenuBar 多選單聯級選單頭部Bar
此元件是管理多個聯級選單頭部的元件,例如掘金編輯器下圖,如果選單選項只有1個可以使用MenuAnchor
,多個時使用MenuBar
.
紅框內的元件集就是MenuBar
元件的作用,它可以管理各個選單之間的聯動,預設他們共用一個控制器。一般和SubmenuButton
、MenuItemButton
配合使用。
dart
const MenuBar({
super.key,
this.style,// 選單樣式
this.clipBehavior = Clip.none,
this.controller,
required this.children,
});
示例效果:
左邊的選單1、2、3是一組MenuBar
元件,右邊是可以獨立的MenuAnchor
元件。
示例原始碼:
相較於官方示例,該示例下方展示了上方四個選單元件的單獨使用以及聯合使用的簡單示例,去掉了快捷鍵設定的屬性,更直觀的瞭解選單元件的使用。快捷鍵的使用一般在PC端使用。
```dart import 'package:flutter/material.dart'; void main() => runApp(const MenuApp()); enum MenuEntry { about('About'), showMessage('Show Message'), hideMessage('Hide Message'), colorMenu('Color Menu'), colorRed('Red Background'), colorGreen('Green Background'), colorBlue('Blue Background');
final String label; const MenuEntry(this.label); }
class MyCascadingMenu extends StatefulWidget { const MyCascadingMenu({super.key, required this.message});
final String message;
@override
State
class _MyCascadingMenuState extends State
Color get backgroundColor => _backgroundColor; Color _backgroundColor = Colors.red; set backgroundColor(Color value) { if (_backgroundColor != value) { setState(() { _backgroundColor = value; }); } }
bool get showingMessage => _showingMessage; bool _showingMessage = false; set showingMessage(bool value) { if (_showingMessage != value) { setState(() { _showingMessage = value; }); } }
@override void dispose() { _buttonFocusNode.dispose(); super.dispose(); }
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children:
Expanded(
child: Container(
alignment: Alignment.center,
color: backgroundColor,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Padding(
padding: const EdgeInsets.all(12.0),
child: Text(
showingMessage ? widget.message : '',
style: Theme.of(context).textTheme.headlineSmall,
),
),
Text(_lastSelection != null
? 'Last Selected: ${_lastSelection!.label}'
: ''),
],
),
),
),
],
);
}
void _activate(MenuEntry selection) { setState(() { _lastSelection = selection; });
switch (selection) {
case MenuEntry.about:
showAboutDialog(
context: context,
applicationName: 'MenuBar Sample',
applicationVersion: '1.0.0',
);
break;
case MenuEntry.hideMessage:
case MenuEntry.showMessage:
showingMessage = !showingMessage;
break;
case MenuEntry.colorMenu:
break;
case MenuEntry.colorRed:
backgroundColor = Colors.red;
break;
case MenuEntry.colorGreen:
backgroundColor = Colors.green;
break;
case MenuEntry.colorBlue:
backgroundColor = Colors.blue;
break;
}
}
List
class MenuApp extends StatelessWidget { const MenuApp({super.key});
static const String kMessage = '"Talk less. Smile more." - A. Burr';
@override Widget build(BuildContext context) { return const MaterialApp( home: Scaffold(body: MyCascadingMenu(message: kMessage)), ); } } ```
選單樣式 MenuStyle
構造方法:
構造方法內大多數引數使用的是 MaterialStateProperty<T>
具有狀態選擇設定,這樣做的好處是在PC端例如懸停、點選、不可點選等狀態設定不同樣式時,會非常的方便。例如系統自帶的顏色、邊框MaterialStateColor
、MaterialStateBorderSide
等都是通過 MaterialStateProperty
擴充套件的。
dart
const MenuStyle({
this.backgroundColor,
this.shadowColor,
this.surfaceTintColor,
this.elevation,
this.padding,
this.minimumSize,
this.fixedSize,
this.maximumSize,
this.side,
this.shape,
this.mouseCursor,
this.visualDensity,
this.alignment,
});
原生系統菜單系列元件
使用平臺原生選單元件實現,非Flutter渲染,例如在MacOS系統上特別有用,因為在MacOS上需要一個系統級選單。
- PlatformMenuBar
- PlatformMenu
- PlatformMenuItem
- PlatformMenuItemGroup
...
使用方法大同小異,區別就是這是基於不同平臺實現的系統選單選項。
小結
上面就是本次更新新增的選單相關使用的元件,可以看出這一系列元件更傾向於桌面端使用,裡面加入了實現快捷鍵的操作,反而對於移動端操作需要的選單以外部分的陰影,選單彈出動畫都沒有找到支援的方法。
- Flutter3.7版本新增元件-Menu菜單系列介紹
- Flutter【繪製】製作一個掘金Logo元件
- Flutter【手勢&繪製】模擬紙質書籍翻頁
- Flutter【繪製&手勢】模擬紙質書翻頁2--外掛化
- Flutter【手勢&繪製】圍棋棋盤
- Flutter【手勢&繪製】手遊操縱桿移動解析
- Flutter實現訊飛線上語音合成(WebSocket流式版)
- 2022年中總結--時間過的好快
- Flutter實現訊飛線上語音聽寫(WebSocket流式版)
- Flutter更改輸入框內容,onChanged接受不到回撥?
- 【端午】會說話的粽子你見過嗎?
- Flutter入口中的runApp方法解析
- Flutter實現手勢密碼加密、解鎖
- Flutter 獲取狀態列高度等於0,為啥?
- Flutter仿網易App廣告卡片3D翻轉
- Flutter實現心碎的感覺
- Flutter實現一個牛頓擺
- Flutter實現掘金App點贊效果
- Flutter製作一個吃豆人載入Loading
- Flutter繪製之貝塞爾曲線畫一個小海豚