Flutter & OpenHarmony OA系统工作台快捷入口组件开发指南

前言
工作台是OA系统的核心页面,快捷入口组件作为工作台的重要组成部分,为用户提供了快速访问常用功能的途径。一个设计良好的快捷入口组件需要支持图标展示、功能分类、自定义排序、角标提示等功能。本文将详细介绍如何使用Flutter和OpenHarmony开发一个灵活实用的工作台快捷入口组件,提升用户的工作效率。
组件功能规划
快捷入口组件通常采用宫格布局,每个入口包含图标、名称和可选的角标。组件需要支持动态配置入口项,不同用户可以看到不同的功能入口。同时支持编辑模式,用户可以自定义入口的显示顺序和是否显示。在交互上,点击入口跳转到对应功能页面,长按进入编辑模式。
Flutter端实现
定义快捷入口数据模型:
class QuickEntry {
final String id;
final String name;
final String icon;
final String route;
final int? badge;
final Color? backgroundColor;
int sortOrder;
bool isVisible;
QuickEntry({
required this.id,
required this.name,
required this.icon,
required this.route,
this.badge,
this.backgroundColor,
this.sortOrder = 0,
this.isVisible = true,
});
}
数据模型包含入口的基本信息和配置选项。badge字段用于显示未处理数量,如待审批数、未读消息数等。sortOrder和isVisible用于支持用户自定义排序和显示控制,这两个字段设为可变以便运行时修改。
快捷入口组件的基础结构:
class QuickEntryGrid extends StatefulWidget {
final List<QuickEntry> entries;
final Function(QuickEntry) onTap;
final Function(List<QuickEntry>) onOrderChanged;
const QuickEntryGrid({
Key? key,
required this.entries,
required this.onTap,
required this.onOrderChanged,
}) : super(key: key);
State<QuickEntryGrid> createState() => _QuickEntryGridState();
}
组件接收入口列表和回调函数,onTap处理点击事件,onOrderChanged在排序变化时触发,用于持久化用户的自定义排序。
状态类中的编辑模式管理:
class _QuickEntryGridState extends State<QuickEntryGrid> {
bool _isEditMode = false;
void _toggleEditMode() {
setState(() => _isEditMode = !_isEditMode);
}
void _onReorder(int oldIndex, int newIndex) {
setState(() {
final item = widget.entries.removeAt(oldIndex);
widget.entries.insert(newIndex, item);
for (int i = 0; i < widget.entries.length; i++) {
widget.entries[i].sortOrder = i;
}
});
widget.onOrderChanged(widget.entries);
}
}
编辑模式下用户可以拖拽调整入口顺序。_onReorder方法处理拖拽排序,更新列表顺序后同步更新每个入口的sortOrder字段,然后通知父组件保存新的排序。
宫格布局的构建:
GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 4,
mainAxisSpacing: 16,
crossAxisSpacing: 16,
childAspectRatio: 0.9,
),
itemCount: widget.entries.where((e) => e.isVisible).length,
itemBuilder: (context, index) {
final entry = widget.entries.where((e) => e.isVisible).toList()[index];
return _buildEntryItem(entry);
},
)
GridView构建4列的宫格布局,mainAxisSpacing和crossAxisSpacing设置网格间距。childAspectRatio控制每个格子的宽高比,0.9使格子略高于宽,为图标和文字留出足够空间。只显示isVisible为true的入口。
入口项的构建:
Widget _buildEntryItem(QuickEntry entry) {
return GestureDetector(
onTap: () => widget.onTap(entry),
onLongPress: _toggleEditMode,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Stack(
clipBehavior: Clip.none,
children: [
Container(
width: 48,
height: 48,
decoration: BoxDecoration(
color: entry.backgroundColor ?? Colors.blue.withOpacity(0.1),
borderRadius: BorderRadius.circular(12),
),
child: Icon(
_getIconData(entry.icon),
color: Colors.blue,
),
),
if (entry.badge != null && entry.badge! > 0)
Positioned(
right: -8,
top: -8,
child: _buildBadge(entry.badge!),
),
],
),
SizedBox(height: 8),
Text(
entry.name,
style: TextStyle(fontSize: 12),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
],
),
);
}
入口项使用Column垂直排列图标和名称,Stack用于叠加角标。长按触发编辑模式,点击触发跳转。角标使用Positioned定位在图标右上角,clipBehavior设为none允许角标超出Stack边界。
OpenHarmony鸿蒙端实现
定义快捷入口接口:
interface QuickEntry {
id: string
name: string
icon: Resource
route: string
badge?: number
backgroundColor?: ResourceColor
sortOrder: number
isVisible: boolean
}
icon字段使用Resource类型,可以引用资源文件中的图片。backgroundColor使用ResourceColor类型,支持颜色字符串和Color枚举。
快捷入口组件的基础结构:
@Component
struct QuickEntryGrid {
@Prop entries: QuickEntry[] = []
@State isEditMode: boolean = false
private onEntryClick: (entry: QuickEntry) => void = () => {}
private onOrderChange: (entries: QuickEntry[]) => void = () => {}
}
使用@State管理编辑模式状态,@Prop接收入口列表。回调函数处理点击和排序变化事件。
宫格布局的构建:
Grid() {
ForEach(this.getVisibleEntries(), (entry: QuickEntry, index: number) => {
GridItem() {
this.EntryItem(entry)
}
})
}
.columnsTemplate('1fr 1fr 1fr 1fr')
.rowsGap(16)
.columnsGap(16)
.padding(16)
Grid组件构建4列等宽布局,columnsTemplate使用1fr定义等分列。rowsGap和columnsGap设置网格间距,padding设置整体内边距。ForEach只渲染可见的入口项。
入口项的构建:
@Builder
EntryItem(entry: QuickEntry) {
Column() {
Badge({
count: entry.badge || 0,
position: BadgePosition.RightTop,
style: { badgeSize: 16, badgeColor: '#F44336' }
}) {
Column() {
Image(entry.icon)
.width(32)
.height(32)
}
.width(48)
.height(48)
.backgroundColor(entry.backgroundColor || '#E6F7FF')
.borderRadius(12)
.justifyContent(FlexAlign.Center)
}
Text(entry.name)
.fontSize(12)
.fontColor('#333333')
.maxLines(1)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.margin({ top: 8 })
}
.onClick(() => this.onEntryClick(entry))
.gesture(
LongPressGesture()
.onAction(() => {
this.isEditMode = true
})
)
}
鸿蒙的Badge组件内置了角标功能,count为0时自动隐藏。LongPressGesture处理长按手势,触发编辑模式。Image组件直接使用Resource类型的图标资源。
编辑模式下的拖拽排序:
@Builder
EditableGrid() {
List() {
ForEach(this.entries, (entry: QuickEntry, index: number) => {
ListItem() {
Row() {
Image($r('app.media.drag_handle'))
.width(24)
.height(24)
Image(entry.icon)
.width(32)
.height(32)
.margin({ left: 12 })
Text(entry.name)
.fontSize(14)
.margin({ left: 8 })
.layoutWeight(1)
Toggle({ type: ToggleType.Switch, isOn: entry.isVisible })
.onChange((isOn: boolean) => {
entry.isVisible = isOn
})
}
.width('100%')
.padding(12)
}
})
}
.editMode(true)
.onItemMove((from: number, to: number) => {
this.moveEntry(from, to)
return true
})
}
编辑模式使用List组件的editMode功能实现拖拽排序,onItemMove回调处理排序逻辑。每个列表项包含拖拽手柄、图标、名称和显示开关,用户可以调整顺序和控制显示隐藏。
总结
本文详细介绍了Flutter和OpenHarmony平台上工作台快捷入口组件的开发方法。快捷入口是OA系统工作台的核心组件,直接影响用户的操作效率。通过支持自定义排序和显示控制,可以让每个用户根据自己的使用习惯定制工作台。两个平台都提供了网格布局和拖拽排序的支持,开发者可以根据需求灵活实现。
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net
更多推荐


所有评论(0)