flutter组件学习之Cupertino 组件(iOS风格)

Flutter Cupertino 组件详解

Cupertino 组件是 Flutter 提供的 iOS 风格 UI 组件库,让你的应用在 iOS 设备上拥有原生 iOS 的外观和交互体验。

一、核心组件概览

1. 应用结构组件

dart 复制代码
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

void main() {
runApp(const MyCupertinoApp());
}

class MyCupertinoApp extends StatelessWidget {
const MyCupertinoApp({super.key});

@override
Widget build(BuildContext context) {
return const CupertinoApp(
title: 'iOS风格应用',
theme: CupertinoThemeData(
brightness: Brightness.light,
primaryColor: CupertinoColors.activeBlue,
),
home: CupertinoHomePage(),
);
}
}

2. 页面骨架与导航

dart 复制代码
class CupertinoHomePage extends StatelessWidget {
const CupertinoHomePage({super.key});

@override
Widget build(BuildContext context) {
return CupertinoPageScaffold(
navigationBar: CupertinoNavigationBar(
middle: const Text('首页'),
trailing: CupertinoButton(
padding: EdgeInsets.zero,
child: const Icon(CupertinoIcons.add),
onPressed: () {},
),
),
child: SafeArea(
child: ListView(
children: [
// 页面内容
],
),
),
);
}
}

二、常用 Cupertino 组件详解

1. 导航相关组件

CupertinoNavigationBar
dart 复制代码
CupertinoNavigationBar(
// 左侧按钮
leading: CupertinoButton(
padding: EdgeInsets.zero,
child: const Text('返回'),
onPressed: () => Navigator.pop(context),
),

// 中间标题
middle: const Text('设置'),

// 右侧按钮
trailing: CupertinoButton(
padding: EdgeInsets.zero,
child: const Icon(CupertinoIcons.gear),
onPressed: () {},
),

// 边框设置
border: const Border(bottom: BorderSide(color: CupertinoColors.systemGrey2)),

// 是否半透明
backgroundColor: CupertinoColors.systemBackground.withOpacity(0.9),
)
CupertinoSliverNavigationBar(可滚动导航栏)
dart 复制代码
CustomScrollView(
slivers: [
CupertinoSliverNavigationBar(
largeTitle: const Text('大型标题'),
trailing: CupertinoButton(
child: const Icon(CupertinoIcons.ellipsis_circle),
onPressed: () {},
),
),
// 其他 Sliver 组件
],
)

2. 底部标签栏

dart 复制代码
class CupertinoTabbedApp extends StatelessWidget {
const CupertinoTabbedApp({super.key});

@override
Widget build(BuildContext context) {
return CupertinoTabScaffold(
tabBar: CupertinoTabBar(
items: const [
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.home),
label: '首页',
),
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.search),
label: '搜索',
),
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.person),
label: '我的',
),
],
activeColor: CupertinoColors.activeBlue,
inactiveColor: CupertinoColors.systemGrey,
backgroundColor: CupertinoColors.systemBackground,
),
tabBuilder: (context, index) {
// 返回对应的页面
switch (index) {
case 0:
return const HomePage();
case 1:
return const SearchPage();
case 2:
return const ProfilePage();
default:
return Container();
}
},
);
}
}

3. 按钮组件

CupertinoButton
dart 复制代码
// 填充按钮
CupertinoButton.filled(
onPressed: () {},
child: const Text('填充按钮'),
)

// 边框按钮
CupertinoButton(
onPressed: () {},
color: CupertinoColors.activeBlue,
borderRadius: BorderRadius.circular(8),
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 12),
child: const Text('普通按钮'),
)

// 无边框文本按钮
CupertinoButton(
onPressed: () {},
child: const Text('文本按钮'),
padding: EdgeInsets.zero, // 去掉默认内边距
)

// 禁用状态
CupertinoButton(
onPressed: null, // null 表示禁用
child: const Text('禁用按钮'),
)
CupertinoContextMenu
dart 复制代码
CupertinoContextMenu(
actions: [
CupertinoContextMenuAction(
child: const Text('分享'),
onPressed: () {},
trailingIcon: CupertinoIcons.share,
),
CupertinoContextMenuAction(
child: const Text('删除'),
onPressed: () {},
isDestructiveAction: true, // 危险操作
),
],
child: Container(
width: 100,
height: 100,
color: CupertinoColors.systemGrey5,
child: const Center(child: Text('长按显示菜单')),
),
)

4. 输入控件

CupertinoTextField
dart 复制代码
CupertinoTextField(
controller: TextEditingController(),
placeholder: '请输入内容',
prefix: const Icon(CupertinoIcons.search),
suffix: CupertinoButton(
padding: EdgeInsets.zero,
child: const Icon(CupertinoIcons.clear_thick_circled),
onPressed: () {},
),
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 10),
style: CupertinoTheme.of(context).textTheme.textStyle,
decoration: BoxDecoration(
border: Border.all(color: CupertinoColors.systemGrey3),
borderRadius: BorderRadius.circular(8),
),
obscureText: true, // 密码模式
keyboardType: TextInputType.emailAddress,
)
CupertinoSearchTextField(搜索框)
dart 复制代码
CupertinoSearchTextField(
onChanged: (value) {
// 搜索逻辑
},
onSubmitted: (value) {
// 提交搜索
},
placeholder: '搜索...',
prefixIcon: const Icon(CupertinoIcons.search),
suffixIcon: const Icon(CupertinoIcons.mic),
style: CupertinoTheme.of(context).textTheme.textStyle,
)

5. 选择器

CupertinoPicker
dart 复制代码
// 滚动选择器
int selectedIndex = 0;

CupertinoPicker(
scrollController: FixedExtentScrollController(initialItem: selectedIndex),
itemExtent: 32,
onSelectedItemChanged: (index) {
setState(() {
selectedIndex = index;
});
},
children: List.generate(10, (index) => Center(
child: Text('选项 $index'),
)),
)

// 日期选择器
DateTime selectedDate = DateTime.now();

CupertinoDatePicker(
mode: CupertinoDatePickerMode.dateAndTime,
initialDateTime: selectedDate,
minimumDate: DateTime(2000),
maximumDate: DateTime(2100),
onDateTimeChanged: (DateTime newDate) {
setState(() {
selectedDate = newDate;
});
},
use24hFormat: true,
)

// 时间选择器
Duration selectedDuration = const Duration(hours: 1);

CupertinoTimerPicker(
mode: CupertinoTimerPickerMode.hm,
minuteInterval: 5,
onTimerDurationChanged: (Duration newDuration) {
setState(() {
selectedDuration = newDuration;
});
},
)

6. 对话框与提示

CupertinoAlertDialog
dart 复制代码
showCupertinoDialog(
context: context,
builder: (context) => CupertinoAlertDialog(
title: const Text('确认'),
content: const Text('确定要删除吗?'),
actions: [
CupertinoDialogAction(
child: const Text('取消'),
onPressed: () => Navigator.pop(context),
isDefaultAction: true,
),
CupertinoDialogAction(
child: const Text('删除'),
onPressed: () {
// 删除操作
Navigator.pop(context);
},
isDestructiveAction: true,
),
],
),
)
CupertinoActionSheet(操作表)
dart 复制代码
showCupertinoModalPopup(
context: context,
builder: (context) => CupertinoActionSheet(
title: const Text('选择操作'),
message: const Text('请选择一个操作'),
actions: [
CupertinoActionSheetAction(
onPressed: () {
Navigator.pop(context, '拍照');
},
child: const Text('拍照'),
),
CupertinoActionSheetAction(
onPressed: () {
Navigator.pop(context, '从相册选择');
},
child: const Text('从相册选择'),
),
],
cancelButton: CupertinoActionSheetAction(
onPressed: () => Navigator.pop(context),
isDefaultAction: true,
child: const Text('取消'),
),
),
)
CupertinoActivityIndicator
dart 复制代码
// 小型加载指示器
const CupertinoActivityIndicator(radius: 10)

// 大型加载指示器
const CupertinoActivityIndicator.partiallyRevealed(
progress: 0.5, // 进度 0-1
radius: 15,
animating: true,
)

7. 开关、滑块和分段控件

CupertinoSwitch
dart 复制代码
bool switchValue = false;

CupertinoSwitch(
value: switchValue,
onChanged: (value) {
setState(() {
switchValue = value;
});
},
activeColor: CupertinoColors.activeGreen,
trackColor: CupertinoColors.systemGrey,
)
CupertinoSlider
dart 复制代码
double sliderValue = 0.5;

CupertinoSlider(
value: sliderValue,
min: 0,
max: 1,
divisions: 10,
onChanged: (value) {
setState(() {
sliderValue = value;
});
},
activeColor: CupertinoColors.activeBlue,
thumbColor: CupertinoColors.white,
)
CupertinoSegmentedControl
dart 复制代码
int segmentedValue = 0;

CupertinoSegmentedControl<int>(
groupValue: segmentedValue,
onValueChanged: (value) {
setState(() {
segmentedValue = value;
});
},
children: const {
0: Text('全部'),
1: Text('进行中'),
2: Text('已完成'),
},
selectedColor: CupertinoColors.activeBlue,
unselectedColor: CupertinoColors.systemBackground,
borderColor: CupertinoColors.systemGrey3,
pressedColor: CupertinoColors.systemGrey5,
)

8. 列表和单元格

CupertinoListTile
dart 复制代码
CupertinoListTile(
leading: Icon(CupertinoIcons.person, color: CupertinoColors.systemGrey),
title: const Text('个人资料'),
subtitle: const Text('查看和编辑个人资料'),
trailing: const CupertinoListTileChevron(),
onTap: () {
// 导航到个人资料页面
},
)

// 带开关的列表项
CupertinoListTile(
title: const Text('消息通知'),
trailing: CupertinoSwitch(
value: notificationEnabled,
onChanged: (value) {
setState(() {
notificationEnabled = value;
});
},
),
)
CupertinoListSection
dart 复制代码
CupertinoListSection.insetGrouped(
header: const Text('设置'),
children: [
CupertinoListTile.notched(
title: const Text('账号设置'),
onTap: () {},
),
CupertinoListTile.notched(
title: const Text('隐私设置'),
onTap: () {},
),
CupertinoListTile.notched(
title: const Text('通用设置'),
onTap: () {},
),
],
)

9. 特殊界面组件

CupertinoSlidingSegmentedControl(滑动分段控件)
dart 复制代码
int slidingValue = 0;

CupertinoSlidingSegmentedControl<int>(
groupValue: slidingValue,
onValueChanged: (value) {
setState(() {
slidingValue = value!;
});
},
children: const {
0: Text('Tab 1'),
1: Text('Tab 2'),
2: Text('Tab 3'),
},
)
CupertinoScrollbar(iOS风格滚动条)
dart 复制代码
CupertinoScrollbar(
controller: scrollController,
child: ListView.builder(
controller: scrollController,
itemCount: 100,
itemBuilder: (context, index) {
return ListTile(title: Text('Item $index'));
},
),
)

三、实用技巧和最佳实践

1. 混合使用 Material 和 Cupertino

dart 复制代码
// 根据平台自动选择组件
Theme.of(context).platform == TargetPlatform.iOS
? CupertinoButton(...)
: ElevatedButton(...);

// 或使用 Platform.isIOS 判断
import 'dart:io';

Platform.isIOS
? CupertinoNavigationBar(...)
: AppBar(...);

2. 自定义 Cupertino 主题

dart 复制代码
CupertinoApp(
theme: CupertinoThemeData(
brightness: Brightness.light,
primaryColor: CupertinoColors.systemBlue,
primaryContrastingColor: CupertinoColors.white,
textTheme: CupertinoTextThemeData(
textStyle: const TextStyle(fontFamily: 'SF Pro'),
navTitleTextStyle: TextStyle(
fontSize: 17,
fontWeight: FontWeight.w600,
color: CupertinoColors.label,
),
),
barBackgroundColor: CupertinoColors.systemBackground,
scaffoldBackgroundColor: CupertinoColors.systemGroupedBackground,
),
)

3. 完整的 iOS 风格应用示例

dart 复制代码
class IOSMessengerApp extends StatelessWidget {
const IOSMessengerApp({super.key});

@override
Widget build(BuildContext context) {
return CupertinoApp(
theme: const CupertinoThemeData(
brightness: Brightness.light,
),
home: CupertinoTabScaffold(
tabBar: CupertinoTabBar(
items: const [
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.bubble_left_bubble_right),
label: '聊天',
),
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.phone),
label: '通话',
),
],
),
tabBuilder: (context, index) {
return CupertinoPageScaffold(
navigationBar: CupertinoNavigationBar(
middle: Text(index == 0 ? '聊天' : '通话'),
trailing: CupertinoButton(
padding: EdgeInsets.zero,
child: const Icon(CupertinoIcons.pencil),
onPressed: () {},
),
),
child: ListView.builder(
itemCount: 20,
itemBuilder: (context, index) {
return CupertinoListTile(
leading: Container(
width: 50,
height: 50,
decoration: BoxDecoration(
color: CupertinoColors.systemGrey5,
borderRadius: BorderRadius.circular(25),
),
child: const Icon(CupertinoIcons.person_fill),
),
title: Text('联系人 $index'),
subtitle: const Text('最后一条消息...'),
trailing: const Text('刚刚'),
onTap: () {
showCupertinoDialog(
context: context,
builder: (context) => CupertinoAlertDialog(
title: const Text('开始聊天'),
content: Text('确定要联系联系人 $index 吗?'),
actions: [
CupertinoDialogAction(
child: const Text('取消'),
onPressed: () => Navigator.pop(context),
),
CupertinoDialogAction(
child: const Text('确定'),
onPressed: () => Navigator.pop(context),
),
],
),
);
},
);
},
),
);
},
),
);
}
}

四、注意事项

  1. 平台适配:Cupertino 组件主要用于 iOS 平台,在 Android 上使用会显得不协调
  2. 性能考虑:大量使用动画效果时注意性能优化
  3. 用户体验:遵循 iOS 设计规范,保持原生交互习惯
  4. 图标使用 :优先使用 CupertinoIcons 中的图标
  5. 状态管理:Cupertino 组件与 Material 组件一样,可以使用各种状态管理方案

五、资源推荐

  1. 官方文档https://api.flutter.dev/flutter/cupertino/cupertino-library.html
  2. Human Interface Guidelineshttps://developer.apple.com/design/human-interface-guidelines/
  3. SF Symbolshttps://developer.apple.com/sf-symbols/(iOS 原生图标)

通过掌握这些 Cupertino 组件,你可以为 iOS 用户提供原生的、符合 iOS 设计规范的优秀应用体验!

相关推荐
finegx2 小时前
反汇编objdump和strace学习
linux·经验分享·学习
Shining05962 小时前
前沿模型系列(三)《检索增强的语言模型》
人工智能·学习·其他·语言模型·自然语言处理·大模型·rag
QYQ_11272 小时前
嵌入式学习——51单片机(下)
嵌入式硬件·学习·51单片机
今儿敲了吗2 小时前
python基础学习笔记第四章
c++·笔记·python·学习
【数据删除】3482 小时前
计算机复试学习笔记 Day44
笔记·学习
星幻元宇VR2 小时前
VR地震科普学习机|沉浸式防震减灾新体验
学习·安全·vr·虚拟现实
星幻元宇VR2 小时前
VR爱国教育学习机|让红色精神在沉浸体验中代代传承
科技·学习·vr·虚拟现实
逆小舟2 小时前
【SWM320】学习使用UART
单片机·学习·嵌入式软件
国医中兴3 小时前
Flutter 三方库 superclass 的鸿蒙化适配指南 - 支持原生高性能类构造、属性代理与深层元数据解析实战
flutter·harmonyos·鸿蒙·openharmony