Flutter for OpenHarmony 跨平台开发:记事本功能实战指南

作者:liulian0916日期:2026/5/1

Flutter for OpenHarmony 跨平台开发:记事本功能实战指南

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net


一、引言

记事本是移动设备中最基础且常用的应用之一,其开发涉及数据存储、列表展示、搜索过滤、状态管理等多个技术领域。随着鸿蒙生态的快速发展,如何高效地实现跨平台记事本应用,成为开发者关注的技术要点。

Flutter作为Google推出的开源UI框架,凭借其跨平台能力和丰富的组件生态,为记事本功能的实现提供了便捷的技术方案。Flutter for OpenHarmony的出现,使得Flutter开发者能够将应用部署到鸿蒙设备,进一步拓展了跨平台开发的应用范围。

本文将以记事本功能为例,详细介绍如何使用Flutter for OpenHarmony实现笔记的增删改查、搜索过滤、排序、置顶等功能,为开发者提供完整的技术参考。


二、技术背景

2.1 Flutter for OpenHarmony概述

Flutter是Google于2017年发布的开源UI框架,采用Dart语言进行开发。Flutter通过Skia渲染引擎实现自绘,不依赖平台原生组件,从而保证了不同平台上UI的一致性。

OpenHarmony是由开放原子开源基金会孵化的开源操作系统项目,旨在构建万物智联的操作系统生态。Flutter for OpenHarmony是Flutter在OpenHarmony平台上的适配实现,使Flutter开发者能够将应用无缝部署到鸿蒙设备。

2.2 记事本的技术架构

实现记事本功能涉及以下核心技术:

数据管理:使用List存储笔记数据,Map结构存储单条笔记的各个属性。

搜索过滤:实现标题和内容的模糊搜索,支持实时过滤。

排序功能:支持按时间、按标题等多种排序方式。

状态管理:使用setState管理笔记列表、搜索条件、排序方式等状态。

2.3 Flutter与原生鸿蒙开发的对比

对比维度Flutter for OpenHarmony原生鸿蒙开发(ArkTS)
编程语言DartArkTS
列表组件ListView功能完善List组件需适配
搜索实现简洁高效需要手动实现
跨平台能力支持多平台仅限鸿蒙平台
开发效率热重载支持需要重新编译

三、功能设计

3.1 需求分析

记事本功能的核心需求包括:

  1. 笔记管理:支持创建、编辑、删除笔记
  2. 搜索功能:支持按标题和内容搜索笔记
  3. 排序功能:支持按时间、按标题排序
  4. 置顶功能:支持将重要笔记置顶显示
  5. 颜色标记:支持为笔记选择不同颜色
  6. 空状态展示:无笔记时显示引导信息

3.2 数据结构设计

每条笔记采用Map结构存储,包含以下字段:

1{
2  'id': int,           // 唯一标识
3  'title': String,     // 标题
4  'content': String,   // 内容
5  'date': DateTime,    // 创建/修改时间
6  'color': int,        // 颜色索引
7  'isPinned': bool,    // 是否置顶
8}
9

3.3 界面设计

界面分为以下几个部分:

搜索栏:包含搜索输入框和排序按钮

笔记列表:展示所有笔记卡片,置顶笔记优先显示

浮动按钮:点击创建新笔记

编辑弹窗:底部弹出的笔记编辑界面


四、核心实现

4.1 状态变量定义

使用以下状态变量管理记事本状态:

1// 笔记列表
2final List<Map<String, dynamic>> _notes = [];
3
4// 标题输入控制器
5final TextEditingController _titleController = TextEditingController();
6
7// 内容输入控制器
8final TextEditingController _contentController = TextEditingController();
9
10// 选中的颜色索引
11int _selectedColorIndex = 0;
12
13// 搜索关键词
14String _searchQuery = '';
15
16// 排序方式
17String _sortBy = 'date';
18
19// 可选颜色列表
20final List<Color> _colors = [
21  Colors.yellow.shade100,
22  Colors.green.shade100,
23  Colors.blue.shade100,
24  Colors.pink.shade100,
25  Colors.purple.shade100,
26  Colors.orange.shade100,
27];
28

4.2 搜索与排序实现

搜索和排序的过滤逻辑:

1List<Map<String, dynamic>> get _filteredNotes {
2  // 按搜索关键词过滤
3  var notes = _notes.where((n) =>
4      n['title'].toString().toLowerCase().contains(_searchQuery.toLowerCase()) ||
5      n['content'].toString().toLowerCase().contains(_searchQuery.toLowerCase())
6  ).toList();
7  
8  // 排序
9  if (_sortBy == 'date') {
10    notes.sort((a, b) => (b['date'] as DateTime).compareTo(a['date'] as DateTime));
11  } else if (_sortBy == 'title') {
12    notes.sort((a, b) => a['title'].toString().compareTo(b['title'].toString()));
13  }
14  
15  return notes;
16}
17

4.3 添加笔记

添加新笔记的实现:

1void _addNote() {
2  // 验证输入
3  if (_titleController.text.trim().isEmpty && 
4      _contentController.text.trim().isEmpty) return;
5  
6  setState(() {
7    _notes.insert(0, {
8      'id': DateTime.now().millisecondsSinceEpoch,
9      'title': _titleController.text.isEmpty 
10          ? '无标题' 
11          : _titleController.text,
12      'content': _contentController.text,
13      'date': DateTime.now(),
14      'color': _selectedColorIndex,
15      'isPinned': false,
16    });
17    // 清空输入
18    _titleController.clear();
19    _contentController.clear();
20    _selectedColorIndex = 0;
21  });
22  Navigator.pop(context);
23}
24

4.4 编辑笔记

编辑已有笔记的实现:

1void _editNote(int index) {
2  final note = _notes[index];
3  // 填充现有内容
4  _titleController.text = note['title'];
5  _contentController.text = note['content'];
6  _selectedColorIndex = note['color'];
7  
8  // 显示编辑弹窗
9  showModalBottomSheet(
10    context: context,
11    isScrollControlled: true,
12    builder: (context) => _buildNoteEditor(isEdit: true, editIndex: index),
13  );
14}
15
16void _updateNote(int index) {
17  setState(() {
18    _notes[index]['title'] = _titleController.text.isEmpty 
19        ? '无标题' 
20        : _titleController.text;
21    _notes[index]['content'] = _contentController.text;
22    _notes[index]['color'] = _selectedColorIndex;
23    _notes[index]['date'] = DateTime.now();
24  });
25  _titleController.clear();
26  _contentController.clear();
27  Navigator.pop(context);
28}
29

4.5 删除笔记

删除笔记的实现,包含确认对话框:

1void _deleteNote(int index) {
2  showDialog(
3    context: context,
4    builder: (context) => AlertDialog(
5      title: const Text('删除笔记'),
6      content: const Text('确定要删除这条笔记吗?'),
7      actions: [
8        TextButton(
9          onPressed: () => Navigator.pop(context), 
10          child: const Text('取消')
11        ),
12        TextButton(
13          onPressed: () {
14            setState(() => _notes.removeAt(index));
15            Navigator.pop(context);
16          },
17          child: const Text('删除', style: TextStyle(color: Colors.red)),
18        ),
19      ],
20    ),
21  );
22}
23

4.6 置顶功能

置顶笔记的实现:

1void _togglePin(int index) {
2  setState(() {
3    _notes[index]['isPinned'] = !_notes[index]['isPinned'];
4  });
5}
6

五、完整代码实现

1import 'package:flutter/material.dart';
2
3class NotesFeature extends StatefulWidget {
4  const NotesFeature({super.key});
5
6  
7  State<NotesFeature> createState() => _NotesFeatureState();
8}
9
10class _NotesFeatureState extends State<NotesFeature> {
11  final List<Map<String, dynamic>> _notes = [];
12  final TextEditingController _titleController = TextEditingController();
13  final TextEditingController _contentController = TextEditingController();
14  int _selectedColorIndex = 0;
15  String _searchQuery = '';
16  String _sortBy = 'date';
17
18  final List<Color> _colors = [
19    Colors.yellow.shade100,
20    Colors.green.shade100,
21    Colors.blue.shade100,
22    Colors.pink.shade100,
23    Colors.purple.shade100,
24    Colors.orange.shade100,
25  ];
26
27  List<Map<String, dynamic>> get _filteredNotes {
28    var notes = _notes.where((n) =>
29        n['title'].toString().toLowerCase().contains(_searchQuery.toLowerCase()) ||
30        n['content'].toString().toLowerCase().contains(_searchQuery.toLowerCase())
31    ).toList();
32
33    if (_sortBy == 'date') {
34      notes.sort((a, b) => (b['date'] as DateTime).compareTo(a['date'] as DateTime));
35    } else if (_sortBy == 'title') {
36      notes.sort((a, b) => a['title'].toString().compareTo(b['title'].toString()));
37    }
38
39    return notes;
40  }
41
42  void _addNote() {
43    if (_titleController.text.trim().isEmpty && _contentController.text.trim().isEmpty) return;
44
45    setState(() {
46      _notes.insert(0, {
47        'id': DateTime.now().millisecondsSinceEpoch,
48        'title': _titleController.text.isEmpty ? '无标题' : _titleController.text,
49        'content': _contentController.text,
50        'date': DateTime.now(),
51        'color': _selectedColorIndex,
52        'isPinned': false,
53      });
54      _titleController.clear();
55      _contentController.clear();
56      _selectedColorIndex = 0;
57    });
58    Navigator.pop(context);
59  }
60
61  void _editNote(int index) {
62    final note = _notes[index];
63    _titleController.text = note['title'];
64    _contentController.text = note['content'];
65    _selectedColorIndex = note['color'];
66
67    showModalBottomSheet(
68      context: context,
69      isScrollControlled: true,
70      builder: (context) => _buildNoteEditor(isEdit: true, editIndex: index),
71    );
72  }
73
74  void _updateNote(int index) {
75    setState(() {
76      _notes[index]['title'] = _titleController.text.isEmpty ? '无标题' : _titleController.text;
77      _notes[index]['content'] = _contentController.text;
78      _notes[index]['color'] = _selectedColorIndex;
79      _notes[index]['date'] = DateTime.now();
80    });
81    _titleController.clear();
82    _contentController.clear();
83    Navigator.pop(context);
84  }
85
86  void _deleteNote(int index) {
87    showDialog(
88      context: context,
89      builder: (context) => AlertDialog(
90        title: const Text('删除笔记'),
91        content: const Text('确定要删除这条笔记吗?'),
92        actions: [
93          TextButton(onPressed: () => Navigator.pop(context), child: const Text('取消')),
94          TextButton(
95            onPressed: () {
96              setState(() => _notes.removeAt(index));
97              Navigator.pop(context);
98            },
99            child: const Text('删除', style: TextStyle(color: Colors.red)),
100          ),
101        ],
102      ),
103    );
104  }
105
106  void _togglePin(int index) {
107    setState(() {
108      _notes[index]['isPinned'] = !_notes[index]['isPinned'];
109    });
110  }
111
112  
113  Widget build(BuildContext context) {
114    return Scaffold(
115      body: Column(
116        children: [
117          _buildSearchBar(),
118          Expanded(
119            child: _filteredNotes.isEmpty ? _buildEmptyState() : _buildNotesList(),
120          ),
121        ],
122      ),
123      floatingActionButton: FloatingActionButton(
124        onPressed: () {
125          _titleController.clear();
126          _contentController.clear();
127          _selectedColorIndex = 0;
128          showModalBottomSheet(
129            context: context,
130            isScrollControlled: true,
131            builder: (context) => _buildNoteEditor(),
132          );
133        },
134        child: const Icon(Icons.add),
135      ),
136    );
137  }
138
139  Widget _buildSearchBar() {
140    return Container(
141      padding: const EdgeInsets.all(12),
142      child: Row(
143        children: [
144          Expanded(
145            child: TextField(
146              onChanged: (v) => setState(() => _searchQuery = v),
147              decoration: InputDecoration(
148                hintText: '搜索笔记...',
149                prefixIcon: const Icon(Icons.search),
150                border: OutlineInputBorder(borderRadius: BorderRadius.circular(12)),
151                contentPadding: const EdgeInsets.symmetric(horizontal: 12),
152              ),
153            ),
154          ),
155          const SizedBox(width: 8),
156          PopupMenuButton<String>(
157            icon: const Icon(Icons.sort),
158            onSelected: (v) => setState(() => _sortBy = v),
159            itemBuilder: (context) => [
160              const PopupMenuItem(value: 'date', child: Text('按时间排序')),
161              const PopupMenuItem(value: 'title', child: Text('按标题排序')),
162            ],
163          ),
164        ],
165      ),
166    );
167  }
168
169  Widget _buildEmptyState() {
170    return Center(
171      child: Column(
172        mainAxisAlignment: MainAxisAlignment.center,
173        children: [
174          Icon(Icons.note_alt_outlined, size: 64, color: Colors.grey.shade400),
175          const SizedBox(height: 16),
176          Text('暂无笔记', style: TextStyle(fontSize: 18, color: Colors.grey.shade400)),
177          const SizedBox(height: 8),
178          Text('点击右下角按钮创建新笔记', style: TextStyle(fontSize: 14, color: Colors.grey.shade400)),
179        ],
180      ),
181    );
182  }
183
184  Widget _buildNotesList() {
185    final pinnedNotes = _filteredNotes.where((n) => n['isPinned']).toList();
186    final otherNotes = _filteredNotes.where((n) => !n['isPinned']).toList();
187
188    return ListView(
189      padding: const EdgeInsets.all(12),
190      children: [
191        if (pinnedNotes.isNotEmpty) ...[
192          const Padding(
193            padding: EdgeInsets.symmetric(vertical: 8),
194            child: Text('已置顶', style: TextStyle(fontWeight: FontWeight.bold, color: Colors.grey)),
195          ),
196          ...pinnedNotes.map((note) => _buildNoteCard(_notes.indexOf(note), note)),
197        ],
198        if (otherNotes.isNotEmpty) ...[
199          if (pinnedNotes.isNotEmpty)
200            const Padding(
201              padding: EdgeInsets.symmetric(vertical: 8),
202              child: Text('其他', style: TextStyle(fontWeight: FontWeight.bold, color: Colors.grey)),
203            ),
204          ...otherNotes.map((note) => _buildNoteCard(_notes.indexOf(note), note)),
205        ],
206      ],
207    );
208  }
209
210  Widget _buildNoteCard(int index, Map<String, dynamic> note) {
211    return Card(
212      margin: const EdgeInsets.only(bottom: 8),
213      color: _colors[note['color']],
214      child: InkWell(
215        onTap: () => _editNote(index),
216        borderRadius: BorderRadius.circular(12),
217        child: Padding(
218          padding: const EdgeInsets.all(16),
219          child: Column(
220            crossAxisAlignment: CrossAxisAlignment.start,
221            children: [
222              Row(
223                children: [
224                  Expanded(
225                    child: Text(
226                      note['title'],
227                      style: const TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
228                    ),
229                  ),
230                  if (note['isPinned'])
231                    const Icon(Icons.push_pin, size: 16, color: Colors.grey),
232                ],
233              ),
234              const SizedBox(height: 8),
235              Text(
236                note['content'],
237                style: const TextStyle(fontSize: 14),
238                maxLines: 3,
239                overflow: TextOverflow.ellipsis,
240              ),
241              const SizedBox(height: 8),
242              Row(
243                mainAxisAlignment: MainAxisAlignment.spaceBetween,
244                children: [
245                  Text(
246                    _formatDate(note['date']),
247                    style: const TextStyle(fontSize: 12, color: Colors.grey),
248                  ),
249                  Row(
250                    mainAxisSize: MainAxisSize.min,
251                    children: [
252                      IconButton(
253                        icon: Icon(note['isPinned'] ? Icons.push_pin : Icons.push_pin_outlined, size: 20),
254                        onPressed: () => _togglePin(index),
255                        padding: EdgeInsets.zero,
256                        constraints: const BoxConstraints(),
257                      ),
258                      const SizedBox(width: 8),
259                      IconButton(
260                        icon: const Icon(Icons.delete_outline, size: 20, color: Colors.red),
261                        onPressed: () => _deleteNote(index),
262                        padding: EdgeInsets.zero,
263                        constraints: const BoxConstraints(),
264                      ),
265                    ],
266                  ),
267                ],
268              ),
269            ],
270          ),
271        ),
272      ),
273    );
274  }
275
276  Widget _buildNoteEditor({bool isEdit = false, int? editIndex}) {
277    return Padding(
278      padding: EdgeInsets.only(
279        bottom: MediaQuery.of(context).viewInsets.bottom,
280        left: 16,
281        right: 16,
282        top: 16,
283      ),
284      child: SingleChildScrollView(
285        child: Column(
286          mainAxisSize: MainAxisSize.min,
287          crossAxisAlignment: CrossAxisAlignment.stretch,
288          children: [
289            Text(
290              isEdit ? '编辑笔记' : '新建笔记',
291              style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
292            ),
293            const SizedBox(height: 16),
294            TextField(
295              controller: _titleController,
296              decoration: const InputDecoration(
297                hintText: '标题',
298                border: OutlineInputBorder(),
299              ),
300              style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
301            ),
302            const SizedBox(height: 12),
303            TextField(
304              controller: _contentController,
305              decoration: const InputDecoration(
306                hintText: '内容',
307                border: OutlineInputBorder(),
308              ),
309              maxLines: 6,
310            ),
311            const SizedBox(height: 12),
312            const Text('选择颜色:', style: TextStyle(fontSize: 14)),
313            const SizedBox(height: 8),
314            Wrap(
315              spacing: 8,
316              children: List.generate(_colors.length, (index) => GestureDetector(
317                onTap: () => setState(() => _selectedColorIndex = index),
318                child: Container(
319                  width: 36,
320                  height: 36,
321                  decoration: BoxDecoration(
322                    color: _colors[index],
323                    shape: BoxShape.circle,
324                    border: _selectedColorIndex == index
325                        ? Border.all(color: Colors.black, width: 2)
326                        : null,
327                  ),
328                  child: _selectedColorIndex == index
329                      ? const Icon(Icons.check, size: 20)
330                      : null,
331                ),
332              )),
333            ),
334            const SizedBox(height: 16),
335            ElevatedButton(
336              onPressed: isEdit ? () => _updateNote(editIndex!) : _addNote,
337              style: ElevatedButton.styleFrom(padding: const EdgeInsets.symmetric(vertical: 12)),
338              child: Text(isEdit ? '保存' : '创建'),
339            ),
340            const SizedBox(height: 16),
341          ],
342        ),
343      ),
344    );
345  }
346
347  String _formatDate(DateTime date) {
348    return '${date.year}/${date.month}/${date.day} ${date.hour}:${date.minute.toString().padLeft(2, '0')}';
349  }
350}
351

六、运行效果

在这里插入图片描述


七、关键技术点解析

7.1 ListView与笔记列表

Flutter的ListView组件非常适合构建笔记列表:

1ListView(
2  padding: const EdgeInsets.all(12),
3  children: [
4    // 置顶笔记区域
5    if (pinnedNotes.isNotEmpty) ...[
6      const Text('已置顶'),
7      ...pinnedNotes.map((note) => _buildNoteCard(note)),
8    ],
9    // 其他笔记区域
10    if (otherNotes.isNotEmpty) ...[
11      const Text('其他'),
12      ...otherNotes.map((note) => _buildNoteCard(note)),
13    ],
14  ],
15)
16

通过将置顶笔记和其他笔记分开处理,实现了置顶优先显示的效果。

7.2 showModalBottomSheet编辑弹窗

使用showModalBottomSheet实现底部弹出的编辑界面:

1showModalBottomSheet(
2  context: context,
3  isScrollControlled: true,  // 允许弹窗高度自适应
4  builder: (context) => _buildNoteEditor(),
5);
6

设置isScrollControlled为true,可以让弹窗根据内容自适应高度,配合MediaQuery.of(context).viewInsets.bottom处理键盘弹出时的布局。

7.3 TextEditingController输入控制

TextEditingController用于控制输入框的内容:

1final TextEditingController _titleController = TextEditingController();
2
3// 设置内容
4_titleController.text = note['title'];
5
6// 清空内容
7_titleController.clear();
8
9// 获取内容
10String title = _titleController.text;
11

7.4 PopupMenuButton排序菜单

PopupMenuButton用于实现排序选项菜单:

1PopupMenuButton<String>(
2  icon: const Icon(Icons.sort),
3  onSelected: (v) => setState(() => _sortBy = v),
4  itemBuilder: (context) => [
5    const PopupMenuItem(value: 'date', child: Text('按时间排序')),
6    const PopupMenuItem(value: 'title', child: Text('按标题排序')),
7  ],
8)
9

7.5 OpenHarmony平台适配要点

在OpenHarmony设备上运行Flutter应用,需要注意:

  1. 签名配置:需要在DevEco Studio中配置应用签名
  2. 数据持久化:本示例使用内存存储,实际应用需集成shared_preferences或hive
  3. 触摸交互:使用InkWell和IconButton处理触摸事件

八、总结与展望

本文详细介绍了使用Flutter for OpenHarmony开发记事本功能的完整过程。通过合理的数据结构设计、清晰的增删改查逻辑、规范的UI组件构建,实现了一个功能完善、交互友好的记事本模块。

技术要点回顾

  • 使用List存储笔记数据
  • 使用TextEditingController控制输入
  • 使用showModalBottomSheet实现编辑弹窗
  • 使用PopupMenuButton实现排序菜单
  • 实现搜索过滤和置顶功能

扩展方向

  • 数据持久化:集成shared_preferences或hive实现数据本地存储
  • 分类功能:支持笔记分类管理
  • 富文本编辑:支持格式化文本和图片
  • 云同步:接入后端服务实现多设备同步

Flutter for OpenHarmony为开发者提供了便捷的跨平台开发能力,使得记事本等常见功能能够高效地在鸿蒙设备上实现。随着鸿蒙生态的不断发展,Flutter跨平台技术将在更多应用场景中发挥重要作用。


Flutter for OpenHarmony 跨平台开发:记事本功能实战指南》 是转载文章,点击查看原文


相关推荐


linux之进程优先与切换调度
feng_you_ying_li2026/4/22

1.进程优先优先级 是进程得到CPU的先后顺序,由于CPU少但进程多,因此要通过优先级确定谁先谁后的问题。 (1)优先级VS权限 优先级:得到资源的前提下获取资源的先后问题。 权限:能否得到某种资源的资格。 优先级在struct_task中是一个整形,其的值越低表明优先级越高,反之越低。 (2)基于时间片的分时操作系统 每一个进程依次占用CPU的时间是有限的,即时间片的时间到了该进程就只能等下一轮了。 OS在分配顺序时要考虑公平性,即进程的优先级可能会发生变化,但变化的幅度不能太


【节点】[SquareRoot节点]原理解析与实际应用
SmalBox2026/4/13

【Unity Shader Graph 使用与特效实现】专栏-直达 SquareRoot节点核心功能与数学原理 SquareRoot节点是Unity ShaderGraph中用于执行平方根运算的基础数学工具,其核心功能为接收输入值(标量或向量)并返回各分量的平方根结果。数学表达式为:输出值 = √输入值。该运算在图形渲染中具有明确的物理意义,常用于距离衰减、光照强度调节等场景。 技术原理解析 ‌硬件加速‌:基于HLSL的sqrt函数实现,直接调用GPU硬件优化指令,相较于组合运算(如乘方再开


告别Vibe Coding:为什么SDD(Spec-Driven Development)才是AI项目开发的正确打开方式
码事漫谈2026/4/5

从Vibe Coding的混沌中醒来,拥抱确定性 一段似曾相识的对话 “帮我加个深色模式。” “好的,已添加深色模式。” ——半小时后,你发现深色模式把所有的图标都反色了,按钮不见了,而白色模式下的文字变成了灰色。 “不对,我说的是只改背景,不改图标和文字...” “明白了,已修复。” ——十分钟后,深色模式是好了,但白色模式下那个新加的按钮消失了。 “你把我白色模式的样式也改了?” “抱歉,我重新实现...” 这不是段子,这是无数开发者正在经历的日常。这就是所谓的 Vibe Coding—


构建无障碍组件之Tabs Pattern
anOnion2026/3/28

标签页(Tabs)是一种分层的内容展示组件,通过标签列表(Tab List)和对应的内容面板(Tab Panel)来组织和展示内容。本文基于 W3C WAI-ARIA Tabs Pattern 规范,详解如何构建无障碍的标签页组件。 一、Tabs 的定义与核心概念 1.1 什么是 Tabs Tabs 是一种将内容分层展示的界面模式: Tab List(标签列表):包含一组标签元素的容器 Tab(标签):作为对应内容面板的标签,激活后显示该面板 Tab Panel(标签面板):包含与标签关联的内


GitHub Copilot SDK 入门:五分钟构建你的第一个 AI Agent
乱世不浮生2026/3/20

TL;DR The core value of the GitHub Copilot SDK is not the convenience of "calling an LLM" (that's already been solved by the OpenAI SDK, LangChain, etc.), but rather providing a production-proven Agent runtime. The problems it actually solves are: O


【浏览器MCP组件】 chrome-devtools的快捷方式和MCP配置
伊玛目的门徒2026/3/11

创建Chrome调试快捷方式 右键点击桌面空白处,选择"新建"-"快捷方式"。在目标位置输入以下命令: C:\Users\luke\AppData\Local\ms-playwright\chromium-1208\chrome-win64\chrome.exe --remote-debugging-port=9222 --user-data-dir="%USERPROFILE%\ChromeDebugProfile" 为快捷方式命名,例如"Chrome调试模式"。双击此快捷方式将启动指定版


从零开始的Web3学习 10| Solidity 视图和纯函数 (View and Pure Functions)
庭前云落2026/3/3

在 Solidity 中,view 和 pure 是用于修饰函数的关键字,它们描述了函数对区块链状态的读写行为。正确使用这两个修饰符可以提高代码的可读性,并帮助编译器进行静态检查。 1. view 函数 承诺:不修改状态,但可以读取状态变量。允许的操作: 读取状态变量(如 uint public data)。调用其他 view 或 pure 函数。访问 address(this).balance 或 block.number 等区块链数据(这些不属于“状态修改”)。 禁止的操作:任何会改变状态的


再论自然数全加和 - 质数螺旋
铸人2026/2/23

下面考虑质数螺旋 曾经以1开始绘制螺旋图,但是计算质数坐标的时候就出现困难。所以我们用0开始,并把它放在螺旋的中心。 观察如下图像, 最中心的数字0,不算大小。圈数为 ,对应的数的个数,也就是面积为, 这些圈的最小值是0,最大值是, 相邻两项的差为, 这是一个二阶等差数列,对应的数值的和为, 这些数值,并不关心旋转的起点。仔细观察我们发现这些质数构成的线都几乎都是对角线,相当于旋转了45°的结果,既然如此,我们把起点旋转45°,看看能不能把斜线变成横竖的直线。


字节发力,豆包大模型2.0 震撼来袭(附 Trae 实测)
苍何2026/2/15

这是苍何的第 496 篇原创! 大家好,我是苍何。 其实在早些时候,我就深度参与了豆包大模型2.0 的内测。 今天,终于,豆包大模型 2.0 正式发布了。 说实话,这次的升级幅度,属实把我整不会了。 先说结论:「豆包 2.0 Pro 全面对标 GPT 5.2 和 Gemini 3 Pro」。 「人类最后的考试」HLE-Text 拿下 54.2 分最高分,ICPC 编程竞赛金牌,IMO 数学奥赛也是金牌。 好家伙,字节这是要掀桌子啊。 豆包 2.0,到底升级了啥 这次发布的是一整个系列,包含 P


2026 AI Agent 风口必看|四大技术变革+多Agent实战
User_芊芊君子2026/2/6

🎁个人主页:User_芊芊君子 🎉欢迎大家点赞👍评论📝收藏⭐文章 🔍系列专栏:AI 文章目录: 一、先破后立:2026年AI Agent的核心变革(新颖切入点)1.1 变革1:架构升级——从“四段式”到“PDA+记忆+反思”闭环1.2 变革2:协同升级——A2A协议主导,多Agent协作常态化1.3 变革3:工具升级——MCP协议统一,工具调用标准化1.4 变革4:能力升级——Skills模块化,Agent能力可复用 二、实战落地:2026年多Agent协作项目(

首页编辑器站点地图

本站内容在 CC BY-SA 4.0 协议下发布

Copyright © 2026 XYZ博客