探索flutter中的material和cupertino组件库
2021-10-193.9k 阅读
Flutter 中的 Material 组件库
Material 设计理念
Material Design 是由 Google 推出的一套视觉设计语言,旨在为不同平台和设备提供一致且直观的用户体验。它借鉴了现实世界中的物理规律,如光影、材质和空间关系,创造出具有立体感和动态效果的界面。在 Flutter 中,Material 组件库就是基于这种设计理念构建的,它提供了一系列符合 Material Design 规范的 UI 组件,帮助开发者快速搭建出美观、实用且易于交互的应用界面。
基础组件
- AppBar
- 功能与特点:AppBar 是应用栏,通常位于屏幕顶部,用于显示应用的标题、导航按钮和其他重要操作。它是应用界面的重要组成部分,为用户提供了导航和操作的入口。
- 代码示例:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('My App'),
actions: <Widget>[
IconButton(
icon: Icon(Icons.search),
onPressed: () {},
)
],
),
body: Center(
child: Text('Content'),
),
),
);
}
}
- 解析:在上述代码中,通过
AppBar
类创建了一个应用栏。title
属性设置了应用栏的标题为 “My App”。actions
列表中添加了一个搜索图标按钮,当用户点击该按钮时,会触发onPressed
回调函数(这里暂时为空)。
- Button
- 功能与特点:Flutter 中的按钮组件是用户与应用进行交互的重要元素。Material 组件库提供了多种类型的按钮,如
ElevatedButton
(凸起按钮)、TextButton
(文本按钮)和OutlinedButton
(轮廓按钮),每种按钮都有其独特的视觉风格和适用场景。 - 代码示例:
- 功能与特点:Flutter 中的按钮组件是用户与应用进行交互的重要元素。Material 组件库提供了多种类型的按钮,如
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
ElevatedButton(
onPressed: () {},
child: Text('Elevated Button'),
),
TextButton(
onPressed: () {},
child: Text('Text Button'),
),
OutlinedButton(
onPressed: () {},
child: Text('Outlined Button'),
)
],
),
),
),
);
}
}
- 解析:这段代码展示了三种不同类型按钮的创建。
ElevatedButton
具有凸起的效果,通常用于强调重要的操作;TextButton
只有文本,比较简洁,适用于不太突出的操作;OutlinedButton
有轮廓,视觉效果介于两者之间。每个按钮的onPressed
属性指定了按钮点击时执行的逻辑(这里暂时为空),child
属性设置了按钮显示的文本。
- Card
- 功能与特点:Card 组件用于在应用中展示相关信息的集合,它模拟了现实世界中卡片的外观,具有一定的阴影和圆角,使信息呈现更加清晰和美观。Card 可以包含各种其他组件,如文本、图片等。
- 代码示例:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: Card(
child: Column(
children: <Widget>[
Image.network(
'https://picsum.photos/200/300',
fit: BoxFit.cover,
),
Padding(
padding: EdgeInsets.all(16.0),
child: Text(
'This is a card with an image and text.',
style: TextStyle(fontSize: 18.0),
),
)
],
),
),
),
),
);
}
}
- 解析:在这个示例中,
Card
组件内部包含一个Column
,Column
又包含一个通过网络加载的图片和一段文本。Image.network
用于从指定的 URL 加载图片,Padding
组件用于给文本添加内边距,使文本看起来不那么贴近卡片边缘。
布局组件
- Row 和 Column
- 功能与特点:
Row
和Column
是 Flutter 中最常用的线性布局组件。Row
会将其子组件沿水平方向排列,Column
则沿垂直方向排列。它们提供了灵活的布局控制选项,如主轴和交叉轴的对齐方式等。 - 代码示例:
- 功能与特点:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Container(
width: 100,
height: 100,
color: Colors.red,
),
Container(
width: 100,
height: 100,
color: Colors.green,
)
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
Container(
width: 100,
height: 100,
color: Colors.blue,
),
Container(
width: 100,
height: 100,
color: Colors.yellow,
)
],
)
],
),
),
);
}
}
- 解析:代码中使用了
Column
作为根布局,在Column
内部有两个Row
。第一个Row
使用MainAxisAlignment.spaceEvenly
使两个红色和绿色的Container
组件在水平方向上均匀分布。第二个Row
使用MainAxisAlignment.spaceAround
,使蓝色和黄色的Container
组件在水平方向上分布,并且周围有均匀的空白空间。
- Expanded
- 功能与特点:
Expanded
组件通常用于Row
或Column
内部,它可以让其子组件在主轴方向上扩展,以填充剩余的空间。这在需要灵活分配空间时非常有用。 - 代码示例:
- 功能与特点:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Row(
children: <Widget>[
Expanded(
flex: 1,
child: Container(
color: Colors.red,
),
),
Expanded(
flex: 2,
child: Container(
color: Colors.green,
),
)
],
),
),
);
}
}
- 解析:在这个
Row
布局中,有两个Expanded
包裹的Container
。flex
属性用于指定扩展比例,这里红色Container
的flex
为 1,绿色Container
的flex
为 2,所以绿色Container
会占据两倍于红色Container
的水平空间。
高级组件
- TabBar 和 TabBarView
- 功能与特点:
TabBar
和TabBarView
结合使用可以实现选项卡式的界面,用户可以通过切换选项卡来查看不同的内容。TabBar
用于显示选项卡标题,TabBarView
用于显示与每个选项卡对应的内容。 - 代码示例:
- 功能与特点:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: DefaultTabController(
length: 3,
child: Scaffold(
appBar: AppBar(
bottom: TabBar(
tabs: <Widget>[
Tab(text: 'Tab 1'),
Tab(text: 'Tab 2'),
Tab(text: 'Tab 3'),
],
),
title: Text('Tab Example'),
),
body: TabBarView(
children: <Widget>[
Center(child: Text('Content of Tab 1')),
Center(child: Text('Content of Tab 2')),
Center(child: Text('Content of Tab 3')),
],
),
),
),
);
}
}
- 解析:通过
DefaultTabController
来管理选项卡的状态,length
属性指定了选项卡的数量为 3。AppBar
的bottom
属性设置为TabBar
,其中定义了三个选项卡标题。body
部分使用TabBarView
,其children
列表对应每个选项卡的具体内容。
- BottomNavigationBar
- 功能与特点:
BottomNavigationBar
通常位于屏幕底部,用于在应用的主要功能页面之间进行快速切换。它提供了简洁直观的导航方式,提升用户体验。 - 代码示例:
- 功能与特点:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
bottomNavigationBar: BottomNavigationBar(
items: <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: 'Home',
),
BottomNavigationBarItem(
icon: Icon(Icons.search),
label: 'Search',
),
BottomNavigationBarItem(
icon: Icon(Icons.person),
label: 'Profile',
)
],
currentIndex: 0,
onTap: (int index) {
// 处理选项卡切换逻辑
},
),
body: Center(
child: Text('Home Page'),
),
),
);
}
}
- 解析:在这段代码中,
BottomNavigationBar
包含三个BottomNavigationBarItem
,分别代表 “Home”、“Search” 和 “Profile”。currentIndex
属性指定了当前选中的选项卡索引,onTap
回调函数用于处理用户点击选项卡时的逻辑(这里暂时为空)。
Flutter 中的 Cupertino 组件库
Cupertino 设计理念
Cupertino 设计风格源自苹果的 iOS 系统,它强调简洁、直观和与设备的自然交互。与 Material Design 不同,Cupertino 更注重拟物化的设计元素,以提供用户熟悉的 iOS 风格体验。在 Flutter 中,Cupertino 组件库就是按照这种设计理念构建的,让开发者能够为 iOS 平台创建原生风格的应用界面。
基础组件
- CupertinoNavigationBar
- 功能与特点:
CupertinoNavigationBar
类似于 iOS 应用中的导航栏,位于屏幕顶部,用于显示标题和导航按钮。它具有典型的 iOS 风格,如左侧的返回按钮和右侧的操作按钮。 - 代码示例:
- 功能与特点:
import 'package:flutter/cupertino.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return CupertinoApp(
home: CupertinoPageScaffold(
navigationBar: CupertinoNavigationBar(
middle: Text('My Cupertino App'),
trailing: CupertinoButton(
child: Text('Edit'),
onPressed: () {},
),
),
child: Center(
child: Text('Content'),
),
),
);
}
}
- 解析:在这个示例中,通过
CupertinoNavigationBar
创建了一个导航栏。middle
属性设置了导航栏的中间标题为 “My Cupertino App”。trailing
属性添加了一个 “Edit” 按钮,点击按钮会触发onPressed
回调函数(这里暂时为空)。
- CupertinoButton
- 功能与特点:
CupertinoButton
是 Cupertino 风格的按钮组件,它具有与 iOS 系统按钮相似的外观和交互效果。根据不同的使用场景,有多种样式可供选择,如填充按钮、边框按钮等。 - 代码示例:
- 功能与特点:
import 'package:flutter/cupertino.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return CupertinoApp(
home: CupertinoPageScaffold(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
CupertinoButton(
child: Text('Filled Button'),
onPressed: () {},
color: CupertinoColors.activeBlue,
),
CupertinoButton(
child: Text('Bordered Button'),
onPressed: () {},
color: CupertinoColors.systemGrey,
padding: EdgeInsets.all(16.0),
borderRadius: BorderRadius.circular(8.0),
border: Border.all(color: CupertinoColors.systemGrey),
)
],
),
),
),
);
}
}
- 解析:代码展示了两种
CupertinoButton
的创建。第一个按钮是填充按钮,通过color
属性设置为蓝色。第二个按钮是边框按钮,通过border
属性设置了边框,padding
和borderRadius
属性调整了按钮的外观。每个按钮的onPressed
属性指定了点击时的逻辑(这里暂时为空)。
- CupertinoAlertDialog
- 功能与特点:
CupertinoAlertDialog
用于显示模态对话框,向用户传达重要信息或请求确认操作。它具有典型的 iOS 风格的外观和动画效果。 - 代码示例:
- 功能与特点:
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return CupertinoApp(
home: CupertinoPageScaffold(
child: Center(
child: CupertinoButton(
child: Text('Show Dialog'),
onPressed: () {
showCupertinoDialog(
context: context,
builder: (BuildContext context) {
return CupertinoAlertDialog(
title: Text('Alert'),
content: Text('This is a Cupertino alert dialog.'),
actions: <Widget>[
CupertinoDialogAction(
child: Text('Cancel'),
onPressed: () {
Navigator.pop(context);
},
),
CupertinoDialogAction(
child: Text('OK'),
onPressed: () {
Navigator.pop(context);
},
)
],
);
},
);
},
),
),
),
);
}
}
- 解析:在这个示例中,点击 “Show Dialog” 按钮会触发
showCupertinoDialog
函数。CupertinoAlertDialog
包含标题 “Alert”、内容 “This is a Cupertino alert dialog.” 以及两个按钮 “Cancel” 和 “OK”。点击按钮时,通过Navigator.pop(context)
关闭对话框。
布局组件
- CupertinoPageScaffold
- 功能与特点:
CupertinoPageScaffold
是 Cupertino 风格应用页面的基本脚手架,它提供了一个标准的页面布局结构,包括导航栏(如果有)和内容区域。 - 代码示例:
- 功能与特点:
import 'package:flutter/cupertino.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return CupertinoApp(
home: CupertinoPageScaffold(
navigationBar: CupertinoNavigationBar(
middle: Text('Page Title'),
),
child: Center(
child: Text('Page Content'),
),
),
);
}
}
- 解析:上述代码使用
CupertinoPageScaffold
创建了一个页面,navigationBar
属性设置了页面的导航栏标题为 “Page Title”,child
属性设置了页面的主要内容为 “Page Content”。
- CupertinoListTile
- 功能与特点:
CupertinoListTile
用于在列表中显示单个项目,它具有简洁的 iOS 风格设计,可包含图标、文本和辅助信息等。 - 代码示例:
- 功能与特点:
import 'package:flutter/cupertino.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return CupertinoApp(
home: CupertinoPageScaffold(
child: CupertinoListTile(
leading: Icon(CupertinoIcons.home),
title: Text('Home'),
subtitle: Text('Go to home page'),
onTap: () {},
),
),
);
}
}
- 解析:在这个例子中,
CupertinoListTile
的leading
属性添加了一个房屋图标,title
设置了主文本为 “Home”,subtitle
设置了副标题为 “Go to home page”。onTap
属性指定了点击列表项时的逻辑(这里暂时为空)。
高级组件
- CupertinoTabBar 和 CupertinoTabScaffold
- 功能与特点:
CupertinoTabBar
和CupertinoTabScaffold
配合使用可实现类似于 iOS 底部选项卡的导航效果。CupertinoTabBar
显示在屏幕底部,用于切换不同的选项卡页面,CupertinoTabScaffold
管理选项卡页面的内容。 - 代码示例:
- 功能与特点:
import 'package:flutter/cupertino.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return CupertinoApp(
home: CupertinoTabScaffold(
tabBar: CupertinoTabBar(
items: <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.home),
label: 'Home',
),
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.search),
label: 'Search',
),
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.person),
label: 'Profile',
)
],
),
tabBuilder: (BuildContext context, int index) {
switch (index) {
case 0:
return CupertinoPageScaffold(
child: Center(
child: Text('Home Page'),
),
);
case 1:
return CupertinoPageScaffold(
child: Center(
child: Text('Search Page'),
),
);
case 2:
return CupertinoPageScaffold(
child: Center(
child: Text('Profile Page'),
),
);
default:
return CupertinoPageScaffold();
}
},
),
);
}
}
- 解析:
CupertinoTabBar
定义了三个底部选项卡,分别对应 “Home”、“Search” 和 “Profile”。tabBuilder
回调函数根据选项卡的索引返回相应的页面内容。当用户点击不同的选项卡时,会显示对应的CupertinoPageScaffold
页面。
- CupertinoDatePicker
- 功能与特点:
CupertinoDatePicker
是用于选择日期和时间的组件,它具有 iOS 风格的滚轮式交互界面,方便用户快速选择所需的日期和时间。 - 代码示例:
- 功能与特点:
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return CupertinoApp(
home: CupertinoPageScaffold(
child: Center(
child: CupertinoButton(
child: Text('Select Date'),
onPressed: () {
showCupertinoModalPopup(
context: context,
builder: (BuildContext context) {
return Container(
height: 216.0,
color: CupertinoColors.white,
child: CupertinoDatePicker(
initialDateTime: DateTime.now(),
minimumDate: DateTime(2000),
maximumDate: DateTime(2030),
onDateTimeChanged: (DateTime newDateTime) {
print('Selected date: $newDateTime');
},
),
);
},
);
},
),
),
),
);
}
}
- 解析:点击 “Select Date” 按钮会弹出一个模态对话框,其中包含
CupertinoDatePicker
。initialDateTime
设置了初始显示的日期和时间为当前时间,minimumDate
和maximumDate
限定了可选日期的范围。onDateTimeChanged
回调函数在用户选择新的日期和时间时被触发,并打印出选中的日期。
Material 与 Cupertino 组件库的对比与选择
视觉风格
- Material Design:Material Design 强调简洁、扁平且富有现代感的设计,通过光影、材质和动画效果营造出一种立体感和动态性。其颜色体系丰富且鲜明,组件的形状通常较为规整,如矩形按钮、卡片等。
- Cupertino Design:Cupertino 设计风格源自 iOS,更注重拟物化元素,追求与 iOS 设备原生界面的一致性。颜色相对柔和,组件形状和交互方式更符合用户对 iOS 设备的操作习惯,如圆形按钮、滚轮式选择器等。
交互体验
- Material Design:提供了丰富的动画和过渡效果,使界面交互更加流畅和生动。例如,按钮点击时的涟漪效果,页面切换时的转场动画等。这些动画效果不仅增强了用户体验,还符合 Material Design 的设计理念。
- Cupertino Design:交互体验注重与 iOS 设备的自然交互,强调简洁和直观。例如,
CupertinoDatePicker
的滚轮式选择方式,用户可以通过上下滑动滚轮轻松选择日期和时间,这种交互方式在 iOS 设备上非常常见且易于操作。
平台适配性
- Material Design:最初由 Google 推出,在 Android 平台上具有原生的支持和良好的适配性。但由于其设计理念的通用性,也可以很好地应用于 iOS 和其他平台,为跨平台应用提供统一的视觉风格。
- Cupertino Design:专门为 iOS 平台设计,与 iOS 系统的交互和视觉风格高度契合。在 iOS 应用开发中使用 Cupertino 组件库可以提供原生的用户体验,使应用看起来和操作起来都更像 iOS 原生应用。
如何选择
- 跨平台应用:如果开发的是跨平台应用,希望在不同平台上保持统一的视觉风格,那么 Material 组件库是一个不错的选择。它可以在 Android、iOS 和 Web 等平台上提供一致的体验,减少开发和维护成本。
- iOS 原生风格应用:如果目标是开发一款具有 iOS 原生风格的应用,为 iOS 用户提供熟悉的操作体验,那么 Cupertino 组件库是首选。它能够精准地模拟 iOS 系统的界面和交互,提升用户对应用的认同感。
- 混合使用:在某些情况下,也可以根据具体需求在应用中混合使用 Material 和 Cupertino 组件库。例如,对于一些通用的基础组件可以使用 Material 组件库,而对于特定的 iOS 功能模块(如日期选择器)则使用 Cupertino 组件库,以达到最佳的用户体验和开发效率。
在实际开发中,开发者应根据应用的目标平台、用户群体以及设计需求等因素综合考虑,选择合适的组件库来构建高质量的 Flutter 应用界面。无论是 Material 还是 Cupertino 组件库,都为 Flutter 开发者提供了强大的工具,帮助他们打造出优秀的用户界面。