鸿蒙Flutter应用Emoji渲染适配:从Unicode解析到文本增强实践
前阵子我在鸿蒙设备上调试一款社交类Flutter应用消息列表里一串串emoji直接渲染成“豆腐块”有的干脆显示成方框加问号。查了半天发现不是网络问题也不是数据库编码问题而是系统字体和当前Flutter引擎对Unicode新emoji的覆盖跟不上。后来我把Flutter生态里常用的emoji_extension这类三方库整体做了一遍鸿蒙化适配把文本增强、社交符号解析这些能力全部迁了过来才算彻底解决。这篇文章就把整个适配过程的思路、坑位和核心代码拆开讲清楚适合正在做鸿蒙Flutter应用、尤其是做IM、社区、评论、聊天这类强文本场景的开发者参考。1. 先认清问题鸿蒙上缺的不是表情是一套能识别Unicode 17.0的新emoji解析层很多人第一次接触emoji_extension时都会有个疑问系统不是自带emoji吗为什么还要单独引入一个Flutter三方库来做“Emoji文本增强”这个问题在鸿蒙平台上尤其值得认真回答因为很多人把“显示不出emoji”简单归结为字体问题但实际在鸿蒙上跑一遍就会意识到字体只是表层真正缺的是一个能按Unicode标准解析字符序列的逻辑层。1.1 emoji_extension这类库到底在解决什么问题先从一个基础事实说起我们眼中“一个emoji”在计算机内部往往不是一个字符而是一串Unicode码点序列。比如“”这个家庭组合实际上由三个emoji和两个零宽连接符组成如果把整个字符串当作单个字符去截断、去统计长度、去正则匹配很容易切出半个字符最终渲染出一堆乱码。emoji_extension这类库的核心价值就在于它把“识别一个完整emoji序列”这件事从业务代码里剥离出来统一按照Unicode标准处理。具体来说它至少能帮你做这几件事解析字符串里哪些位置属于同一个emoji字素簇避免切割错位提取出所有emoji序列按类别归类笑脸、旗帜、食物、交通等统计文本中emoji的占比、位置、起始偏移量把emoji从正文中剥离出来单独做样式增强或情感分析。在传统Android和iOS上这些能力更多是“锦上添花”因为两端系统字体更新相对及时String的基础API也能应付大多数场景。但在鸿蒙上情况会复杂不少下面细说。1.2 为什么在鸿蒙上这个问题被放大了鸿蒙生态的Flutter应用通常跑在OpenHarmony分支的Flutter引擎上这带来两个直接影响。其一Dart虚拟机、引擎层和平台通道都对接的是鸿蒙的图形栈和字体管理服务系统字体对最新Unicode版本的收录节奏并不完全同步尤其是一些较新发布的Unicode 17.0字符在旧设备上很大概率查无此字。其二鸿蒙用户的输入法来源非常杂很多第三方输入法在输入组合emoji时使用的码点和系统字体不匹配导致文本在底层是合法的Unicode序列上层却渲染不出来。还有一个很容易被忽略的场景剪贴板。我在适配过程中发现很多从旧系统迁移过来的用户数据、聊天记录里嵌入的是历史版本的码点序列其中一部分已经被Unicode 17.0重新定义或弃用。如果应用里只有“按单字符渲染”的朴素逻辑这些历史数据就会在界面里变成一排排空白或问号。所以鸿蒙应用对emoji的处理不能只停留在“显示”层面而是需要一个独立于系统的解析层先把序列识别正确再做字体回退和渲染决策。这也是我后来坚定选择把emoji_extension整体鸿蒙化的原因。2. 适配的第一站把Flutter工程接到OpenHarmony引擎上并解决字体回退鸿蒙化改造的第一步不是改dart源码而是先把整个Flutter工程在鸿蒙侧编译跑通。这一步看起来简单实际有一堆工程化细节处理不好后面所有代码改动都会白费。2.1 搭建OpenHarmony Flutter工程时最容易忽略的配置目前做鸿蒙Flutter开发主流方式是在已有Flutter项目基础上通过OpenHarmony提供的Flutter SDK和鸿蒙原生工程模板生成hap包。所以第一个操作就是确认你使用的Flutter SDK版本是否支持OpenHarmony目标平台。如果你用的是社区维护的OpenHarmony Flutter版本建议直接用FVM这类多版本管理工具固定SDK版本避免后面升级Flutter时引擎和鸿蒙平台插件全部重新适配。我这里提供一个最小化的pubspec.yaml调整思路environment: sdk: 3.0.0 4.0.0 flutter: 3.16.0 flutter: assets: - assets/fonts/ - assets/emoji_data/注意鸿蒙工程会读取Flutter侧的assets目录所以所有字体文件和emoji数据文件都要显式声明在pubspec里。这个坑我踩过一次当时把字体文件放进了harmony工程目录结果Flutter引擎根本读不到因为鸿蒙侧的资源索引和Android的资源索引机制并不一致最终统一收敛到Flutter的assets目录才算稳定。2.2 字体资源打包与fontFamily回退链设计emoji_extension本身做的是解析和增强但它的输出最终要落到渲染。在鸿蒙上我强烈建议在应用包里内置一份较完整的Emoji字体而不是完全依赖系统字体。原因很简单截至我写这篇文章时部分鸿蒙真机系统的内置字体对新版Unicode emoji的覆盖仍然跳跃某个版本覆盖了换个老设备又缺了。字体接入的最直接方式是Flutter的FontLoaderimport dart:io; import package:flutter/services.dart; Futurevoid loadEmojiFont() async { final data await rootBundle.load(assets/fonts/EmojiFont.ttf); final loader FontLoader(EmojiFallback)..addFont(Future.value(data)); await loader.load(); }加载之后在TextStyle里按顺序配置字体族和回退字体TextStyle( fontSize: 16, fontFamily: HarmonyOS Sans, fontFamilyFallback: const [EmojiFallback], )这里有一个我实测下来的心得fontFamilyFallback并不是全部生效的Flutter的文本排版引擎在遇到某个码点当前字体不支持时会逐个尝试回退链但如果你的主字体本身把那个码点映射成了一个空字形部分版本引擎会直接“认为支持”从而中断回退。解决思路是尽量选择严格遵循Unicode标准、缺失即缺的字体作为主字体或者干脆把Emoji字体放在主字体位置优先保证emoji正确普通文本交给系统字体。这个取舍看业务场景聊天类应用建议emoji优先阅读类应用建议正文字体优先。3. 重写词法层用Dart实现基于码点扫描的Emoji序列提取器工程跑通、字体能兜底之后真正的硬核部分来了emoji_extension的核心逻辑怎么在鸿蒙Flutter环境里正常工作。由于这个库的核心处理逻辑几乎全在Dart层理论上跨平台能力很强但实际跑起来会发现它内部对Unicode版本的判定、对字符串边界的处理需要针对鸿蒙场景重新踩一遍。3.1 先搞懂Dart三个码点层次的差别在处理emoji时Dart字符串有三个不同层次的“字符”概念很多人在这里翻车层次说明例子以“1️⃣”为例UTF-16 code unitDart String直接可操作的最小单元3个code unitUnicode code point一个完整的Unicode字符3个code pointExtended grapheme cluster用户感知的一个字符1个grapheme cluster注意Dart的String.length返回的是UTF-16 code unit数量String.runes返回的是code point数量但这些都不等于用户眼中的“一个emoji”。比如“1️⃣”这个按键表情实际由数字“1”、变体选择符、组合用装饰符组成按code point算有三个但用户看到的就是一个字符。处理这类问题正确姿势是用Dart官方characters包它按Extended Grapheme Cluster迭代字符串正好符合“用户感知字符”的定义。而emoji_extension这类库的工作本质就是在这个基础上继续做“哪些grapheme cluster是emoji、属于哪个类别、如何组合”的判断同时还要兼容Unicode 17.0新增的各种序列。3.2 一个最小可用的Emoji序列提取器我不建议在业务代码里手搓完整的emoji识别规则工程量大且极其容易漏边界。更合理的做法是用Unicode官方发布的emoji-test.txt数据文件在构建期或运行时解析成码点区间和序列表单再配合一个轻量扫描器去匹配文本。先看一个直接扫描文本中所有emoji序列的Dart实现思路import package:characters/characters.dart; class EmojiScanner { final Listint Function(int) ? _emojiSet; ListEmojiMatch scan(String input) { final result EmojiMatch[]; final chars input.characters; var index 0; var buffer StringBuffer(); for (final char in chars) { if (_isEmojiStart(char)) { if (buffer.isNotEmpty) { // 结算上一段非emoji文本 buffer.clear(); } result.add(EmojiMatch(start: index, end: index char.length, value: char)); // 这里要处理ZWJ续接实际工程里需要向前回溯上一个匹配 } else { buffer.write(char); } index char.length; } return result; } bool _isEmojiStart(String char) { // 按Unicode 17.0的emoji数据表判断 // 核心逻辑是判断char的码点是否命中已加载的emoji-data区间 return false; } } class EmojiMatch { final int start; final int end; final String value; EmojiMatch({required this.start, required this.end, required this.value}); }这段代码只是一个骨架重点在于思路按characters包迭代字素簇再用维护好的emoji数据表判断每个字素簇是否为emoji一旦命中就记录位置和内容。真正工程化时需要把ZWJ续接、修饰符、旗帜序列、tag序列全部纳入状态机否则会出现“认出一个男人漏掉后面跟着的女人和孩子”这种尴尬。3.3 Unicode 17.0带来的数据更新问题说句实在话emoji解析这个领域算法永远不是最难的数据才是最难的。Unicode 17.0更新后新增了若干字符并调整了一些序列的合法状态如果你的匹配规则是硬编码的正则或码点区间就只能跟着版本反复改代码。我的做法是把emoji数据外置每次升级直接替换数据文件具体流程是从Unicode官网下载最新版emoji-test.txt解析出fully-qualified、minimally-qualified和unqualified三种状态的序列按类别和序列长度归类存成紧凑的二进制或JSON放进assets/emoji_data启动时加载进内存构建一个前缀匹配树供扫描器使用。这样做的两个直接收益一是版本升级不再需要改dart代码换数据文件即可二是匹配速度比正则快很多因为前缀树的遍历是线性扫过的不会有多余的回溯。实测在聊天列表这种大文本场景下性能差距能达到一个数量级。4. 把解析能力变成产品功能文本增强API与社交符号语义切分核心解析器跑通之后用户并不会因此直接受益——解析只是手段最终还是要落在产品功能上。emoji_extension的鸿蒙化重点在于把这套解析能力转化成上层可以直接调用的、符合业务直觉的API尤其是文本增强和社交符号切分这两块。4.1 设计一套“顺手”的文本增强API所谓文本增强在最基础的层面是这三件事定位、统计、装饰。定位是指给到某个emoji在原始字符串中的精确偏移统计是指计算文本中emoji的数量与密度装饰是指把emoji从普通文本里区分出来单独加样式或触发动作。我在鸿蒙适配版本里是这样组织API的extension EmojiTextX on String { ListEmojiMatch extractEmoji() EmojiScanner().scan(this); double get emojiDensity { final matches extractEmoji(); if (isEmpty) return 0; final emojiLen matches.foldint(0, (sum, m) sum m.value.length); return emojiLen / length; } String stripEmoji() { final buffer StringBuffer(); var lastEnd 0; for (final m in extractEmoji()) { buffer.write(substring(lastEnd, m.start)); lastEnd m.end; } buffer.write(substring(lastEnd)); return buffer.toString(); } }注意stripEmoji里我用的是characters包对应的安全切分逻辑而不是直接substring原始String这一点在后面讲坑的时候会专门展开。文本增强的落地场景非常多比如消息气泡里把emoji放大一点、把特定表情做成可以点击触发快捷回复、在列表页把纯emoji消息显示得更大更居中。这些功能在鸿蒙端没有现成原生组件可以依赖全靠这层解析结果来定位和绘制。4.2 社交符号解析的语义边界问题“社交符号解析引擎”这个说法听起来高大上落到代码上其实就是把消息文本拆成若干个语义块同时识别出昵称、#话题#、URL、引用内容和emoji情感标记。难点在于这些片段经常交织在一起比如“小明 这个也太好笑了吧 #今日份快乐#”。如果先按空白字符切分再去匹配emoji会发现很多emoji和文本是粘连的位置偏移全都错位。正确的做法是做一个统一的tokenizer一次性扫完整段文本按优先级把“URL、话题、、emoji序列”分别抽出来并保留每个token的起止位置。这里有一个我在鸿蒙适配时的关键决定不在Dart侧额外引入旷日持久的正则地狱而是把解析结果做成一个扁平token流交给状态管理去驱动UI。我当时的实现思路大致是这样enum SemanticTokenType { text, emoji, mention, topic, url } class SemanticToken { final SemanticTokenType type; final String raw; final int start; final int end; final EmojiCategory? emojiCategory; } ListSemanticToken tokenizeSemantic(String text) { ... }这段tokenizer在IM界面里的作用是点击跳转个人主页点击话题跳转话题聚合页点击URL唤起浏览器而emoji则单独进入表情浮层或作为情感标记传给分析服务。在鸿蒙上没有现成的RichText原生替代品所以tokenizer产出的token流直接喂给TextSpan构建富文本一套逻辑同时满足渲染和交互不用写第二套解析规则。5. 真实设备上踩过的五个坑以及我最终采用的规避方案适配做到这里demo基本能跑但真机上一放大数据量、一换老设备、一碰第三方输入法各种问题就冒出来了。我把这次适配中实际遇到、反复排查最终解决的几个问题整理在下面每一个都对应一段真实踩坑经历希望能帮后来者省点时间。5.1 剪贴板和输入法造成的代理对截断鸿蒙的剪贴板服务在某些版本上有一个问题往社会性App粘贴长文本时如果原始文本中含有超出基本多语言平面的emoji也就是落在U10000之后的字符剪切板会在同步过程中丢失半个代理对。原本是U1F600的会变成UD83D孤立的代理项后续任何substring操作都可能产生乱码。规避方案分两层。数据层所有从剪贴板进来的字符串先做一遍代理对修复遇到孤立高代理或低代理时直接丢弃不要尝试脑补补全。展示层所有substring操作统一通过characters包完成禁止用String.substring截取可能包含emoji的文本。我在代码里加了统一封装所有涉及切割的地方都走同一个工具函数排查成本立刻降了下来。5.2 老设备上CallKit和通知栏的Emoji降级鸿蒙系统的通知栏、来电浮层这类系统UI不会走Flutter的文本渲染管线而是用系统字体直接渲染。这就导致一个现象App内emoji正常一旦退到后台通知文案里的emoji就变成方框。这个问题在Android上就有鸿蒙上更明显尤其是老设备。我的处理方式是做一个系统层降级表在构造通知栏文案时先通过emoji解析层检测含有的emoji凡是系统字体覆盖不了的一律用文字别名替换比如“”换成“[庆祝]”“❤️”保留红心字符。这里不是最优解但能在不动系统字体的情况下保证用户不看到豆腐块稳定优先。5.3 正则回溯导致的列表页卡顿第一次把完整emoji扫描器接进聊天列表时列表快速滑动明显掉帧。定位后发现问题不在扫描器本身而在我为了兼容某些非标准输入法临时加了几个宽松正则做预过滤其中一个针对肤色修饰符的正则在极端长文本上出现了灾难性回溯。最终方案很粗暴也有效彻底移除预过滤正则把所有匹配逻辑收拢到前缀树扫描器里同时给扫描结果加两级缓存。一级缓存是输入字符串级别的同一个文本重复进入列表渲染时直接返回上次的结果二级缓存是字素簇级别的已经判定过的字符序列不再重复计算。另外扫描器放在后台Isolate里跑在低端鸿蒙设备上留出UI线程的余量。5.4 字体文件过大与启动耗时的权衡内置完整Emoji字体确实能解决渲染覆盖问题但代价是字体文件动辄十几兆。我在一台比较老的鸿蒙开发板上实测冷启动多花了几百毫秒而且内存占用也不低。做了一次取舍后我的方案是把字体包拆成基础版和完整版基础版只覆盖Unicode 15.0之前最常用的表情体积能压缩到2-3兆完整版按需从应用内下载或打包进hap的另一个独立模块里。启动时先加载基础版完整版加载完成后通过ValueNotifier通知界面重建。这样既保证了新版本的表情在复杂社交场景里可用又不牺牲冷启动体验。5.5 测试数据里必须覆盖的边界序列最后说一个测试层面的建议这一条很可能帮你省下一整晚的排查时间。适配完emoji解析层之后我在测试用例里固定放了一批容易翻车的序列每次演出或改版前都会跑一遍家庭组合序列测试ZWJ续接是否正确肤色修饰符序列测试修饰符与基础字符的绑定关系旗帜序列测试区域指示符对是否被拆开携带变体选择符的字符❤️和❤不带VS16的对比测试文本和图形呈现的区分按键序列1️⃣测试组合用装饰符是否被错误截断方向性标记测试最新Unicode版本中的情感中性序列。这些序列只要有一个被截断或误判极大概率会让整个文本渲染链条出问题。把测试用例和数据文件一起跟着Unicode版本升级能少走很多弯路。我在实际适配鸿蒙版本时最深的一个体会是emoji这类看似“小功能”的东西真正做深了之后牵扯的是字符集标准、字体渲染链路、文本排版引擎和业务数据兼容性四个层面任何一层缺席都会在真实用户那里露馅。如果你也在做类似的鸿蒙Flutter适配我的建议很简单——先搭好带字体回退的渲染底层再把emoji数据外置成可更新文件最后才动手写解析逻辑。顺序反了的话后面大概率会推倒重来。

相关新闻

前缀和与前缀积:从LeetCode 724和238看数组累积思想

前缀和与前缀积:从LeetCode 724和238看数组累积思想

1. 为什么要用“前缀和”解数组题这套题单把“寻找数组的中心下标”和“除自身以外数组的乘积”放在一起,编号分别是27和28,对应到LeetCode上就是第724题和第238题。两道题表面上一个在数组里找位置,一个在算乘积,乍看没啥关联&am…

2026/10/9 8:29:17 阅读更多 →
Java+MySQL挂号系统设计与实战:原子性事务与号源管理

Java+MySQL挂号系统设计与实战:原子性事务与号源管理

简介:本资源是一个面向高校计算机专业学生的Java课程设计项目——基于Java与MySQL开发的GUI医院简易挂号管理系统,聚焦软件工程实践中的桌面应用开发全流程。系统完整实现用户登录、挂号/退号、号源管理、费用计算、角色权限控制及数据统计打印等核心功能…

2026/10/9 8:29:17 阅读更多 →
氨储能耦合风光火综合能源系统双层优化调度Matlab代码详解

氨储能耦合风光火综合能源系统双层优化调度Matlab代码详解

过去小半年我一直在折腾综合能源系统的优化调度,发现圈子里讨论最多的已经不是单纯的“风光储”,而是“风光火储氢氨”这种多能耦合的大家庭。氨储能这个方向之所以让我感兴趣,是因为它把“电转氢”和“氢转电”中间的储存痛点用液态氨的形态…

2026/10/9 8:29:17 阅读更多 →

最新新闻

pstack-claude:Linux下Claude服务进程级诊断方法论

pstack-claude:Linux下Claude服务进程级诊断方法论

1. “pstack-claude”不是工具名,而是调试现场的命名习惯——先破除一个普遍误解很多人第一次在GitHub Issues、运维日志或团队内部文档里看到pstack-claude这个词,第一反应是:“这是个新出的Claude配套CLI工具?还是某个开源项目代…

2026/10/9 8:54:19 阅读更多 →
Agent-Reach:构建大模型工具触达层,让智能体接稳外部工具

Agent-Reach:构建大模型工具触达层,让智能体接稳外部工具

1. Agent-Reach是干什么的:一个想清楚再动手的工具触达方案1.1 一个问题:Agent“够得着”工具,但“接不稳”先聊一个我在做AI应用落地时反复遇到的场景。你用大模型做Agent,让它可以自己调用工具、查数据、操作业务系统。第一步通…

2026/10/9 8:54:19 阅读更多 →
电子病历NER实战:基于BERT的命名实体识别源码解析与避坑指南

电子病历NER实战:基于BERT的命名实体识别源码解析与避坑指南

简介:这份源码面向医疗信息化开发者、自然语言处理学习者与科研人员,提供一套基于BERT模型的电子病历命名实体识别完整实现,用于从病历文本中抽取疾病、药物、治疗手段等关键实体,支撑临床决策与医疗数据分析。资源包共38个文件&a…

2026/10/9 8:54:19 阅读更多 →
YashanDB落地实践:避开部署、迁移、备份与性能调优的6个坑

YashanDB落地实践:避开部署、迁移、备份与性能调优的6个坑

YashanDB最近在技术社区里的讨论热度一直在涨,身边陆续有朋友开始做POC,有些团队甚至已经把核心业务跑在上面了。去年我深度参与了一套业务系统的YashanDB落地项目,从版本选型、架构评审开始,到迁移上线和后续的持续调优&#xff…

2026/10/9 8:54:18 阅读更多 →
生产级Coding Agent调优实战:Harness工程从Vibe Coding到可交付

生产级Coding Agent调优实战:Harness工程从Vibe Coding到可交付

1. 从 Vibe Coding 到生产可用:一个 Coding Agent 调优项目的完整复盘Vibe Coding 这个词从去年火到现在,很多人已经用它写了不少小工具、脚本、甚至完整的 Demo 项目。但真正把 Coding Agent 丢进生产环境跑起来的人都知道,Demo 能跑通和线上…

2026/10/9 8:54:18 阅读更多 →
网页右键被禁?从JavaScript事件到浏览器扩展彻底解除限制

网页右键被禁?从JavaScript事件到浏览器扩展彻底解除限制

你打开某个网站,想复制一段特别有用的内容,右键一点,弹出的不是你熟悉的“刷新、检查、另存为”,而是一句冷冰冰的“该页面禁止右键”或者干脆什么反应都没有。再按一下F12,浏览器底部连影子都不出,或者弹个…

2026/10/9 8:53:18 阅读更多 →

日新闻

Java时间API实战:LocalDate、Date与ZonedDateTime的转换与避坑指南

Java时间API实战:LocalDate、Date与ZonedDateTime的转换与避坑指南

Java时间API这个话题,隔三差五就会在群里被翻出来讨论一次。上周还有个同事线上处理一个订单超时问题,排查到最后发现是ZonedDateTime序列化后时区丢了,用户在下单当天晚上看到的时间整整差了8个小时。这类问题几乎每个做Java开发的人都遇到过…

2026/10/9 0:00:49 阅读更多 →
EasyTier实践:从NAT穿透到子网代理的异地组网部署与排错

EasyTier实践:从NAT穿透到子网代理的异地组网部署与排错

前几个月我手头有好几台机器需要互相访问:办公室台式机、家里 NAS、还有一台云主机。如果只是偶尔传个文件倒还好,问题是工作场景经常要在几处环境之间来回切换,每次都先登录跳板机再层层代理,实在折腾。我先后试过端口映射、自建…

2026/10/9 0:00:49 阅读更多 →
AI Agent工程实战:从七要素到七个决策点的系统设计指南

AI Agent工程实战:从七要素到七个决策点的系统设计指南

AI Agent 这个词在过去一年里被反复提及,但真正动手搭过一套能跑起来的 Agent 系统的人都知道,从"知道它是什么"到"让它稳定干活"之间隔着一整套工程决策。我前后参与过几个 Agent 项目的落地,从最初用现成框架拼装&…

2026/10/9 0:01:50 阅读更多 →

周新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 15:26:32 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 15:26:40 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 10:10:36 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 21:13:17 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 15:26:17 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 6:17:20 阅读更多 →