颤动的小部件和主题实现当前的MacOS设计语言。
在https://macosui.github.io/macos_ui/#/上在线查看我们的交互式小部件画廊
可以在https://macosui.dev上找到指南,codelabs和其他文档
macos_ui是针对Flutter的stable频道开发的。为了确保macos_ui获得平稳的开发体验,您应该在Flutter的stable频道上构建应用程序。
pub.dev显示macos_ui仅支持MacOS。这是因为macos_ui调用了一些本机代码,因此将MACOS指定为pubspec.yaml文件中的插件平台。
macos_ui从技术上讲, MacOS_UI将在任何扑面支持的平台上工作,但是您将在MacOS上获得最佳结果。不能保证非麦克斯平台支持。
由于调用本机代码, macos_ui的功能将在MACOS以外的其他平台上工作。
macos_window_utils有关的任何东西MacosColors.controlAccentColor()函数MacosColorWell小部件由于此时Flutter不允许UI元素溢出窗口的边界,因此将弹出窗口限制在可用空间上。
因此,如果您使用的是在工具栏中创建弹出键的小部件,例如ToolBarPopupButton ,则应避免允许将应用程序窗口调整到最高弹出窗口高度以下。
macos_ui欢迎贡献!有关更多信息,请参见CONTRIBUTING.md 。
MacosWindow是MacOS风格布局的基本框架。
它支撑左侧的Sidebar ,顶部是一个可选的TitleBar ,其余的窗口通常用MacosScaffold填充。
MacosWindowScope提供了MacosWindow的范围。可以用MacosWindowScope.of(context).toggleSidebar()切换侧栏。请注意,您必须将MacosScaffold包裹在Builder小部件中,以使其正常工作。
侧栏启用应用程序导航,并可以快速访问应用程序中的顶级内容。
侧边栏可能放在应用程序的左侧或右侧。要在左侧放置一个侧边栏,请使用MacosWindow.sidebar属性。要将侧边栏放在右侧,请使用MacosWindow.endSidebar属性。
示例用法:
int pageIndex = 0 ;
...
MacosWindow (
sidebar : Sidebar (
minWidth : 200 ,
builder : (context, scrollController) {
return SidebarItems (
currentIndex : pageIndex,
scrollController : scrollController,
itemSize : SidebarItemSize .large,
onChanged : (i) {
setState (() => pageIndex = i);
},
items : const [
SidebarItem (
label : Text ( 'Page One' ),
),
SidebarItem (
label : Text ( 'Page Two' ),
),
],
);
},
),
endSidebar : Sidebar (
startWidth : 200 ,
minWidth : 200 ,
maxWidth : 300 ,
shownByDefault : false ,
builder : (context, _) {
return const Center (
child : Text ( 'End Sidebar' ),
);
},
),
), MacosScaffold是您可能称为“页面”的。
脚手架具有toolbar财产和children财产。 children接受ContentArea小部件和多个ResizablePane小部件。要捕捉导航或脚手架下方的路线,请考虑将MacosScaffold包裹在CupertinoTabView中。通过这样做, MacosScaffold内部的导航将在MacosScaffold区域内显示,而不是覆盖整个窗口。要将路线推出包裹在CupertinoTabView中的MacosScaffold ,请使用root Navigator Navigator.of(context, rootNavigator: true)
有关自定义和ToolBar示例的文档。
Big Sur(MacOS 11)引入了MacOS应用程序的新外观。为了匹配您的Flutter应用程序中的外观,MACOS_UI依赖Macos_window_utils,这需要最小MACOS部署目标为10.14.6。因此,请确保使用XCode打开项目的macos/Runner.xcworkspace文件夹,然后搜索Runner.xcodeproj 。转到Info > Deployment Target ,并将macOS Deployment Target设置为10.14.6或更高。然后,打开项目的Podfile (如果没有在Xcode中显示,则可以通过VS代码在项目的macos目录中找到它),并将第一行中的最小部署版本设置为10.14.6或更高版本:
platform :osx , '10.14.6'您可能还需要在Xcode中打开应用程序的Runner.xcodeproj ,并在此处设置最小部署版本。
现在,将您的窗口配置在main()内部()内:
/// This method initializes macos_window_utils and styles the window.
Future < void > _configureMacosWindowUtils () async {
const config = MacosWindowUtilsConfig (
toolbarStyle : NSWindowToolbarStyle .unified,
);
await config. apply ();
}
void main () async {
await _configureMacosWindowUtils ();
runApp ( const YourAppHere ());
}请注意,如果您在MacosWindow中使用标题栏( TitleBar ),则应将窗口的toolbarStyle设置为NSWindowToolbarStyle.expanded ,以便正确地对齐,最小化,Zoom窗口窗口按钮:
Future < void > _configureMacosWindowUtils () async {
const config = MacosWindowUtilsConfig (
toolbarStyle : NSWindowToolbarStyle .expanded,
);
await config. apply ();
}在任何其他情况下,您都应将其保留为NSWindowToolbarStyle.unified 。
在MacosScaffold中创建工具栏。该工具栏出现在MACOS应用程序的标题栏(如果存在)下方,或使用其title属性集成。
工具栏可方便访问常用命令和功能(工具栏项目)。应用程序的不同路线可能具有不同的工具栏。
工具栏项目包括ToolBarIconButton , ToolBarPulldownButton和ToolBarSpacer窗口小部件,应通过items属性提供。每个工具栏项目的操作也应作为您应用程序的菜单栏命令提供。
工具栏看起来最好,最容易理解它们包含相同类型的元素时(因此要么为每个工具栏项目使用标签)。
您可以使用ToolBarSpacer小部件来设置不同工具栏操作的分组。
一个示例工具栏是:
ToolBar (
title : const Text ( 'Untitled Document' ),
titleWidth : 200.0 ,
leading : MacosBackButton (
onPressed : () => debugPrint ( 'click' ),
fillColor : Colors .transparent,
),
actions : [
ToolBarIconButton (
label : "Add" ,
icon : const MacosIcon (
CupertinoIcons .add_circled,
),
onPressed : () => debugPrint ( "Add..." ),
showLabel : true ,
),
const ToolBarSpacer (),
ToolBarIconButton (
label : "Delete" ,
icon : const MacosIcon (
CupertinoIcons .trash,
),
onPressed : () => debugPrint ( "Delete" ),
showLabel : false ,
),
ToolBarPullDownButton (
label : "Actions" ,
icon : CupertinoIcons .ellipsis_circle,
items : [
MacosPulldownMenuItem (
label : "New Folder" ,
title : const Text ( "New Folder" ),
onTap : () => debugPrint ( "Creating new folder..." ),
),
MacosPulldownMenuItem (
label : "Open" ,
title : const Text ( "Open" ),
onTap : () => debugPrint ( "Opening..." ),
),
],
),
]
),这构建了这个简单的工具栏:
其他工具栏示例:
您还可以创建自己的CustomToolbarItem ,以在工具栏中包含任何类型的小部件:
// Add a grey vertical line as a custom toolbar item:
CustomToolbarItem (
inToolbarBuilder : (context) => Padding (
padding : const EdgeInsets . all ( 8.0 ),
child : Container (color : Colors .grey, width : 1 , height : 30 ),
),
inOverflowedBuilder : (context) =>
Container (color : Colors .grey, width : 30 , height : 1 ),
),SliverToolBar SliverToolbar是标准ToolBar的变体,关键区别在于(顾名思义),它与诸如CustomScrollView和NestedScrollView之类的可滚动小部件兼容。 SliverToolBar上还有三个其他属性:
pinned ,这确定工具栏在滚动时是否应保持可见floating ,这确定工具栏是否应在使用开始向上滚动后是否可以看到opacity ,管理工具栏的半透明效果该小部件使开发人员能够实现Apple App Store中看到的工具栏行为。
示例用法:
return CustomScrollView (
controller : scrollController,
slivers : [
SliverToolBar (
title : const Text ( 'SliverToolbar' ),
pinned : true ,
toolbarOpacity : 0.75 ,
),
// Other slivers below
],
);一个旨在近似flutter材料库中的ListTile小部件的小部件。
示例用法:
MacosListTile (
leading : const Icon ( CupertinoIcons .lightbulb),
title : Text (
'A robust library of Flutter components for macOS' ,
style : MacosTheme . of (context).typography.headline,
),
subtitle : Text (
'Create native looking macOS applications using Flutter' ,
style : MacosTheme . of (context).typography.subheadline. copyWith (
color : MacosColors .systemGrayColor,
),
),
),一次显示一个页面的乘法接口。必须在StatefulWidget使用。
您可以使用position属性控制选项卡的放置。
用法:
final _controller = MacosTabController (
initialIndex : 0 ,
length : 3 ,
);
...
MacosTabView (
controller : _controller,
tabs : const [
MacosTab (
label : 'Tab 1' ,
),
MacosTab (
label : 'Tab 2' ,
),
MacosTab (
label : 'Tab 3' ,
),
],
children : const [
Center (
child : Text ( 'Tab 1' ),
),
Center (
child : Text ( 'Tab 2' ),
),
Center (
child : Text ( 'Tab 3' ),
),
],
),
MacosIcon在各个方面都与常规Icon相同,但一个例外 - 它尊重MacosTheme 。以相同的方式使用它,您将是常规图标:
MacosIcon (
CupertinoIcons .add,
// color: CupertinoColors.activeBlue.color,
// size: 20,
),复选框是一种按钮,可让用户在两个相反的状态,操作或值之间进行选择。当其中包含一个选中标记时,请考虑选定的复选框。除非在清单中出现,否则几乎总是随后是标题。了解更多
| 未选中 | 检查 | 混合 |
|---|---|---|
这是如何创建基本复选框的示例:
bool selected = false ;
MacosCheckbox (
value : selected,
onChanged : (value) {
setState (() => selected = value);
},
)要在mixed状态下制作复选框,请将value设置为null 。
在视图中显示一个帮助按钮,并在单击时打开特定的帮助文档。所有帮助按钮都是圆形的,始终尺寸的按钮,其中包含问号图标。了解更多
这是如何创建帮助按钮的一个示例:
HelpButton (
onPressed : () {
print ( 'pressed help button' ),
},
)您可以使用HelpButtonTheme自定义“帮助”按钮外观和行为,但是Apple不建议更改帮助按钮的外观。
单选按钮是一个小的圆形按钮,然后是标题。无线电按钮通常以两到五个组的组为组,为用户提供了一组相关但相互排斥的选择。单选按钮的状态在(填充圆圈)或关闭(一个空圆圈)上。了解更多
这是如何创建基本广播按钮的示例:
bool selected = false ;
MacosRadioButton (
value : selected,
onChanged : (value) {
setState (() => selected = value);
},
),下拉按钮(通常称为下拉菜单)是一种弹出按钮,当单击时,将显示包含选择列表的菜单。菜单出现在按钮下方。一旦在屏幕上显示菜单后,它将保持打开状态,直到用户选择菜单项,单击菜单外,切换到另一个应用程序或退出应用程序。或直到系统显示警报。了解更多
使用下拉按钮显示命令列表。下拉按钮可以显示title或icon来描述按钮菜单的内容。如果使用图标,请确保它清楚地传达了按钮的目的。
如果items为null,则将禁用该按钮(灰色)。
必须提供title或icon ,以显示为下拉按钮的标题,但同时又不同时显示。
菜单也可以使用UP/DOWN键和带有返回键的操作导航。
它也可以通过工具栏上ToolBarPulldownButton栏出现在工具栏中。
| 黑暗主题 | 光主题 |
|---|---|
这是如何创建基本下拉按钮的示例:
MacosPulldownButton (
title : "Actions" ,
// Or provide an icon to use as title:
// icon: CupertinoIcons.ellipsis_circle,
items : [
MacosPulldownMenuItem (
title : const Text ( 'Save' ),
onTap : () => debugPrint ( "Saving..." ),
),
MacosPulldownMenuItem (
title : const Text ( 'Save as...' ),
onTap : () => debugPrint ( "Opening Save As dialog..." ),
),
const MacosPulldownMenuDivider (),
MacosPulldownMenuItem (
enabled : false ,
title : const Text ( 'Export' ),
onTap : () => debugPrint ( "Exporting" ),
),
],
),弹出按钮(通常称为弹出菜单)是一种按钮,当单击时,它显示一个包含相互排斥选择列表的菜单。菜单出现在按钮顶部。像其他类型的菜单一样,弹出式按钮的菜单可以包括分离器和符号等符号。显示菜单后,它保持打开状态,直到用户选择菜单项,单击菜单外,切换到另一个应用程序或退出应用程序。或直到系统显示警报。了解更多
MacosPopupButton的类型T是每个弹出菜单项代表的值的类型。给定菜单中的所有条目必须表示具有一致类型的值。通常,使用enum 。项目中的每个MacosPopupMenuItem必须专门使用相同类型的参数。
onChanged回调应更新定义弹出菜单值的状态变量。它还应该调用State.setState用新值重建弹出按钮。
当有可用菜单约束中无法显示的菜单项时,在打开菜单的顶部或底部显示了一个镜头,以表明有些项目当前不可见。
菜单也可以使用上/下键和带有返回键的项目导航。
| 黑暗主题 | 光主题 |
|---|---|
这是如何创建基本弹出按钮的示例:
String popupValue = 'One' ;
MacosPopupButton < String >(
value : popupValue,
onChanged : ( String ? newValue) {
setState (() {
popupValue = newValue ! ;
});
},
items : < String > [ 'One' , 'Two' , 'Three' , 'Four' ]
. map < MacosPopupMenuItem < String >>(( String value) {
return MacosPopupMenuItem < String >(
value : value,
child : Text (value),
);
}). toList (),
),按钮是MacOS中的标准按钮类型。按钮包含文本(不是图标),并且通常打开一个单独的窗口,对话框或应用程序,以便用户可以完成任务。了解更多
| 黑暗主题 | 光主题 |
|---|---|
请注意,本机按钮可以用作仅文本的样式,具有图标或仅图标的文本。当前,支持仅文本按钮。要创建一个仅图标按钮,请使用MacosIconButton窗口小部件。
这是如何创建基本按钮的示例:
PushButton (
child : Text ( 'button' ),
controlSize : ControlSize .regular,
onPressed : () {
print ( 'button pressed' );
},
),开关(也称为切换)是一个控件,该控件在两个相互排他性状态之间提供了二进制选择。一个开关显示,当可见重音颜色以及开关显示无色时,它正在打开。
可以将ContolSize Enum传递到size属性以控制开关的大小。 MacosSwitch支持以下控制大小:
minismallregular| 离开 | 在 |
|---|---|
这是如何创建基本切换开关的示例:
bool switchValue = false ;
MacosSwitch (
value : switchValue,
onChanged : (value) {
setState (() => switchValue = value);
},
),在此处了解有关开关的更多信息。
在单个水平组中显示一个或多个导航选项卡。由MacosTabView使用,用于在标签栏的不同选项卡之间导航。
该小部件的典型用法是通过MacosTabView来控制其孩子的导航。您无需使用MacosTabView来指定MacosSegmentedControl ,因为它是由该小部件构建的。
用法:
showMacosAlertDialog (
context : context,
builder : (_) => MacosAlertDialog (
appIcon : FlutterLogo (size : 64 ),
title : Text (
'Alert Dialog with Primary Action' ,
style : MacosTheme . of (context).typography.headline,
),
message : Text (
'This is an alert dialog with a primary action and no secondary action' ,
textAlign : TextAlign .center,
style : MacosTypography . of (context).headline,
),
primaryButton : PushButton (
controlSize : ControlSize .large,
child : Text ( 'Primary' ),
onPressed : () {},
),
),
);用法:
showMacosSheet (
context : context,
builder : (_) => const MacosuiSheet (),
);文本字段是用户进入或编辑一条或多个文本的矩形区域。文本字段可以包含普通或样式的文本。
这是如何创建基本文本字段的示例:
MacosTextField (
placeholder : 'Type some text here' ,
)搜索字段是优化的文本字段样式,用于在大量值集合中执行基于文本的搜索。
当用户开始键入搜索字段时,可选结果的列表将显示在下面(或更高)的字段中。
| 黑暗主题 | 光主题 |
|---|---|
这是如何创建搜索字段的示例:
MacosSearchField (
placeholder : 'Search for a country...' ,
results : countries. map ((e) => SearchResultItem (e)). toList (),
onResultSelected : (resultItem) {
debugPrint (resultItem.searchKey);
},
)检查examples/fields_page以获取更多示例。
标签是屏幕上元素所做的简短描述。
Tooltips简洁地描述了如何使用控件,而无需将人们的注意力转移到主要界面。当用户将指针定位在控件上几秒钟时,帮助标签出现。工具提示保持10秒钟,或直到指针远离控件。
| 黑暗主题 | 光主题 |
|---|---|
要创建工具提示,请在MacosTooltip上包装任何小部件:
MacosTooltip (
message : 'This is a tooltip' ,
child : Text ( 'Hover or long press to show a tooltip' ),
),您可以通过自定义主题的TooltipTheme来自定义工具提示。工具提示会自动适应其环境,响应触摸和指针事件。要使用工具栏项目使用工具提示,请为其提供tooltipMessage属性属性。
不要让人们坐在静态屏幕上,等待您的应用程序加载内容或执行冗长的数据处理操作。使用进度指标让人们知道您的应用程序尚未停滞,并让他们了解他们将等待多长时间。
进度指标具有两种不同的样式:
人们不会与进度指标互动;但是,它们通常伴随着一个按钮,用于取消相应的操作。了解更多
可以确定的或不确定的ProgressCircle 。
| 确定进度圈子 | 不确定的进度圆圈 |
|---|---|
这是如何创建不确定进度圈子的一个示例:
ProgressCircle (
value : null ,
),您可以为value提供非零值以确定进度圈子。
ProgressBar只能确定。
这是如何创建确定进度标准的一个示例:
ProgressBar (
value : 30 ,
)级别指示灯以图形方式表示数字值范围内的特定值。它类似于目的的滑块,但更多的视觉效果,并且不包含选择值的独特控件,但是支持在级别指示器上单击和拖动以选择一个值以选择一个值。级别指示器还可以包括刻度标记,从而使用户轻松地查明该范围内的特定值。有三种不同的指标样式,每种样式具有不同的外观,用于交流能力,评级和相关性。
容量指标说明了与有限容量有关的当前水平。传达磁盘和电池使用等因素时,通常会使用容量指标。了解更多
这是如何创建交互式连续容量指标的一个示例:
double value = 30 ;
CapacityIndicator (
value : value,
discrete : false ,
onChanged : (v) {
setState (() => value = v);
},
),您可以将discrete设置为true ,以使其成为离散的容量指示器。
滑块是一个控制,使人们可以通过移动滑块拇指从连续或离散的值范围中选择值。
| 连续的 | 离散的 |
|---|---|
| 水平滑块,可以选择最小值和最大值之间的任何值连续值 | 水平滑块只能选择最小和最大之间的离散值。通常显示刻度标记以提供上下文。 |
这是如何创建交互式连续滑块的一个示例:
double value = 0.5 ;
MacosSlider (
value : value,
onChanged : (v) {
setState (() => value = v);
},
),评分指标使用一系列水平布置的图形符号来传达排名级别。默认符号是恒星。
评分指示灯不显示部分符号 - 它的值是舍入的,以仅显示完整的符号。在评分指示器中,符号总是相同的距离,并且不要扩展或收缩以适合控件。了解更多
这是如何创建交互式评级指标的示例:
double value = 3 ;
RatingIndicator (
amount : 5 ,
value : value,
onChanged : (v) {
setState (() => value = v);
}
)让用户选择一个日期。
MacosDatePickers有三种样式:
textual :仅使用文本的日期选择器,用户必须选择日期,月或年,并使用Caret-Control按钮来更改值。当您的应用中的空间受到限制时,这很有用。graphical :用户可以在类似日历的接口中导航以选择日期的视觉日期选择器。combined :提供textual和graphical接口。 PICKER的本地化由weekdayAbbreviations和monthAbbreviations参数(例如标准localizations.narrowWeekdays()以符合Apple的规格)。
weekdayAbbreviations应该是7个琴弦的清单,一周中的每一天,从周日开始monthAbbreviations应该是12个字符串的列表,一年中的每个月为1月。您还可以定义dateFormat以更改文本接口中显示日期的方式。它需要一串令牌(不敏感),并用相应的值代替它们。支持以下令牌:
D :月中的一天(1-31)DD :月中的一天(01-31)M :一年中的月份(1-12)MM :一年中的月份(01-12)YYYY :年(0000-9999)/ , - , . )默认格式为M/D/YYYY 。
示例用法:
MacosDatePicker (
onDateChanged : (date) => debugPrint ( '$ date ' ),
),让用户选择时间。
MacosTimePickers有三种样式:
textual :仅使用文本的时间选择器,用户必须选择小时或分钟,并使用Caret-Control按钮来更改值。当您的应用中的空间受到限制时,这很有用。graphical :视觉时间选择器,用户可以在其中移动类似时钟的接口的手来选择时间。combined :提供textual和graphical接口。示例用法:
MacosTimePicker (
onTimeChanged : (time) => debugPrint ( '$ time ' ),
),让用户可以通过本机MacOS颜色选择器选择颜色。
您可以选择使用ColorPickerMode枚举来启动选择器的模式。默认值是ColorPickerMode.wheel
这个小部件将在MacOS以外的平台上不起作用!
示例用法:
MacosColorWell (
onColorSelected : (color) => debugPrint ( '$ color ' ),
),