尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

HarmonyOS 7 文本选区交互:点到别处不消失,setTextSelectionClearPolicy 该怎么用

发布时间:2026/9/28 21:23:12

资讯中心
01
ARTICLE

HarmonyOS 7 文本选区交互:点到别处不消失,setTextSelectionClearPolicy 该怎么用

HarmonyOS 7 文本选区交互:点到别处不消失,setTextSelectionClearPolicy 该怎么用
HarmonyOS 7 文本选区交互点到别处不消失setTextSelectionClearPolicy 该怎么用在阅读页长按选了一段话接着点旁边的留白蓝色选区和两个手柄还在。换到临时信息面板又希望点到外面就结束选中。两种需求都合理但如果每个页面随手设置一次返回阅读页后很容易留下另一种交互。HarmonyOS 7 的 API 26 新增 setTextSelectionClearPolicy给出了明确的文本选择清除策略。这里先做一个能对照观察的页面再把临时策略的进入、退出管理起来。重点不是强制所有页面都清除而是让一处设置的影响有明确归属。先纠正一个容易看错的词外部官方枚举说的是“触摸到文本组件外部”不是“点到当前选区以外的任何地方”。一段长文本中没有被选中的字仍可能位于同一个 Text 组件内。测试时把这两种位置混在一起就会把正确结果当成接口失效。策略外部触摸后的文本选择默认情况KEEP_SELECTED_TEXT_ON_EXTERNAL_TOUCH保留选中与手柄未设置时采用此策略CLEAR_SELECTED_TEXT_ON_EXTERNAL_TOUCH清除选中与手柄需要显式设置清除选中不等于删除正文也不是清空剪贴板更不是一条通用的焦点重置命令。已经复制出去的内容不会因为换了这个策略就获得额外的安全保护。如果需求是敏感信息不可复制需要另行设计复制权限和内容呈现不应借用一个交互策略来实现。本文核对的 UIContext 文档更新于2026年9月23日核对日期为9月27日。接口及枚举从26.0.0开始支持仅用于Stage模型系统能力为 SystemCapability.ArkUI.ArkUI.FullAPI26同时支持元服务。UIContext模块本身更早存在不能把模块的起始版本当作这个方法的起始版本。图中下半部分的策略栈是应用自己实现的管理方式不是系统提供了自动入栈、出栈接口。恢复 KEEP 仅恢复后续交互策略不会把已经清掉的选区重新选回来。案例一把“看起来没生效”变成可重复的对照实验先不接业务把下面页面放进API26 Stage工程的页面目录并注册到页面配置。两个按钮只切换策略中间Text可以选择底部留白区则明确位于Text组件之外。切换策略后重新长按选择文字再触摸留白区不要拿按钮点击前遗留的状态判断结果。import { TextSelectionClearPolicy } from kit.ArkUI; Entry Component struct SelectionLab { State policyName: string KEEP; private apply(clear: boolean): void { this.getUIContext().setTextSelectionClearPolicy(clear ? TextSelectionClearPolicy.CLEAR_SELECTED_TEXT_ON_EXTERNAL_TOUCH : TextSelectionClearPolicy.KEEP_SELECTED_TEXT_ON_EXTERNAL_TOUCH); this.policyName clear ? CLEAR : KEEP; } build() { Column({ space: 18 }) { Text(当前策略 this.policyName).fontSize(18) Row({ space: 12 }) { Button(保留选区).onClick(() this.apply(false)) Button(外部触摸清除).onClick(() this.apply(true)) } Text(这段文字可用于选择实验。先长按选中几个字再触摸下面的留白区域。) .fontSize(22) .copyOption(CopyOptions.LocalDevice) .width(100%) .padding(12) .backgroundColor(#EDF3FF) Column() { Text(文本组件外部的测试区域).fontSize(14) } .width(100%) .height(180) .backgroundColor(#F2F2F2) } .padding(24) .width(100%) .height(100%) } }这里的 LocalDevice 来自 Text 的复制配置作用是让Text具备相应复制选择交互不是清除策略本身。不要把一个未配置可选择能力、根本无法建立选区的Text当成CLEAR成功案例。按以下顺序验证一次只改变一个变量初次进入长按建立选区触摸下方留白。观察默认KEEP。点击“外部触摸清除”重新建立选区触摸同一留白。观察CLEAR。再设置KEEP再次建立选区重复相同操作。对比触摸Text内部未选中的字与Text外部留白分别记录不合并成一个结论。观察点包括选中背景、两端手柄、正文内容以及触摸位置是否真的越过组件边界。正文前后应相同。为了定位布局问题可以给组件临时添加明显背景但不要添加会吞掉触摸事件的业务手势后才做第一次测试。此处提供的是按官方签名编写的ArkUI接入代码当前验证环境没有API26 SDK和可连接真机未完成该页面的API26编译及设备交互验证。官方UIContext参考也提示效果以真机为准不能把预览器无效果直接判为平台缺陷。下文实际执行的是公开策略模型及断言不是这一段UI代码的设备测试。案例二临时面板关了阅读页为什么仍然自动清除假设阅读页需要KEEP临时面板需要CLEAR。最直接的代码是在进入面板时设CLEAR退出时设KEEP。单层场景能工作但以后又出现第二个面板就容易出现较早面板退出时覆盖较新面板策略的情况。不能只把“退出恢复默认值”写在每个页面的消失回调里。默认值不一定等于上一个活动场景的要求而且组件存在也不等于页面当前可见。缓存页面、Navigation目的页、弹层和子窗的可见生命周期需要由应用入口协调。我会选一个很小的所有者列表每次进入返回唯一token退出仅移除自己的token最后进入且仍有效的所有者决定当前策略。基础策略由应用明确传入而不是读取一个本文没有验证存在的系统getter。export type SelectionPolicy KEEP | CLEAR; interface PolicyOwner { token: number; name: string; policy: SelectionPolicy; } export class SelectionPolicyScope { private nextToken: number 0; private owners: PolicyOwner[] []; private base: SelectionPolicy; private apply: (policy: SelectionPolicy) void; constructor( base: SelectionPolicy, apply: (policy: SelectionPolicy) void ) { this.base base; this.apply apply; this.apply(base); } current(): SelectionPolicy { return this.owners.length 0 ? this.base : this.owners[this.owners.length - 1].policy; } enter(name: string, policy: SelectionPolicy): number { const owner: PolicyOwner { token: this.nextToken, name, policy }; this.owners.push(owner); try { this.apply(this.current()); } catch (error) { this.owners.pop(); throw error; } return owner.token; } leave(token: number): boolean { const index this.owners.findIndex(owner owner.token token); if (index 0) return false; const removed: PolicyOwner this.owners[index]; this.owners.splice(index, 1); try { this.apply(this.current()); } catch (error) { this.owners.splice(index, 0, removed); throw error; } return true; } }enter/leave是本例自定义方法与系统接口没有同名对应关系。列表按“最近进入优先”工作是这里选择的产品规则若应用要求显式优先级应该改变规则并补测试不能暗示框架原本就有这个优先级。应用只在一个位置把字符串策略映射到平台枚举import { UIContext, TextSelectionClearPolicy } from kit.ArkUI; import { SelectionPolicyScope, SelectionPolicy } from ./SelectionPolicyScope; export function createSelectionScope(ui: UIContext): SelectionPolicyScope { return new SelectionPolicyScope(KEEP, (policy: SelectionPolicy): void { ui.setTextSelectionClearPolicy(policy KEEP ? TextSelectionClearPolicy.KEEP_SELECTED_TEXT_ON_EXTERNAL_TOUCH : TextSelectionClearPolicy.CLEAR_SELECTED_TEXT_ON_EXTERNAL_TOUCH); }); }一个UIContext对应一份这样的管理对象由对应窗口或页面容器持有。不要把第一个窗口的UIContext存成跨窗口全局单例再拿去改第二个窗口。调用示意是进入可见阅读场景时enter打开面板时再enter真正结束该场景时leave这些动作接到哪一种生命周期取决于实际使用的路由和弹层而不是统一塞进aboutToDisappear就算结束。用两种退出顺序检查是否相互覆盖下面代码与上面的模型放在同一TypeScript文件可以直接执行。第一组覆盖正常嵌套退出第二组故意让较早所有者先退出并重复退出旧token。它们验证的是应用管理规则不能替代真机文本选择行为测试。function expectPolicy(actual: SelectionPolicy, expected: SelectionPolicy): void { if (actual ! expected) throw new Error(actual ! expected); } let applied: SelectionPolicy KEEP; const scope new SelectionPolicyScope(KEEP, policy { applied policy; }); const reader scope.enter(reader, KEEP); const panel scope.enter(panel, CLEAR); expectPolicy(applied, CLEAR); scope.leave(panel); expectPolicy(applied, KEEP); scope.leave(reader); expectPolicy(applied, KEEP); const oldPanel scope.enter(old-panel, CLEAR); const newReader scope.enter(new-reader, KEEP); scope.leave(oldPanel); expectPolicy(applied, KEEP); if (scope.leave(oldPanel)) throw new Error(old token must not be reused); scope.leave(newReader); expectPolicy(applied, KEEP); console.log(nested and out-of-order policy cases passed);再增加一次平台适配器抛错的测试避免模型声称进入成功而平台设置失败let fail: boolean false; const failureScope new SelectionPolicyScope(KEEP, () { if (fail) throw new Error(simulated adapter failure); }); fail true; let rejected: boolean false; try { failureScope.enter(failed-panel, CLEAR); } catch { rejected true; } if (!rejected) throw new Error(failure was swallowed); expectPolicy(failureScope.current(), KEEP); console.log(adapter failure rollback passed);这是内存模型回退不是承诺系统调用出错后一定没有任何副作用。适配器异常仍应交由上层记录并处理不要用空catch把错误藏起来也不要无限重试一个已经失效的UIContext。简单设置和统一管理什么时候选哪一种只有一个固定阅读页、策略从不切换时直接设置一次就够。引入所有者列表反而增加维护点。出现多个会临时改变策略的场景后统一入口的价值才体现出来查日志能知道当前是谁持有CLEAR而不是在十几个页面里搜索最后一次调用。方案适用情况要承担的成本固定场景直接设置单页面、没有临时覆盖后续新增场景时重新评估各页面退出时写回KEEP严格单层且基础需求永远KEEP嵌套与乱序退出容易覆盖其他场景每UIContext一个所有者管理器多场景临时切换、存在嵌套必须准确对接可见生命周期并释放token不要为了让选区消失去重建整棵Text节点也不要把触摸事件全局拦截来模拟CLEAR。前者增加不必要的状态变化后者可能影响滚动、链接和无障碍交互。官方明确提供了这一策略时优先采用它再把应用侧的归属管理好。接入后我会保留四项回归KEEP与CLEAR分别触摸组件外部嵌套场景按两种顺序退出两个窗口分别改变策略页面缓存后返回。每一项都把触摸位置、当前UIContext、持有者和期望策略记在一起。问题再发生时才能区分接口行为、布局边界和应用状态覆盖而不是继续增加一次“恢复默认”的调用。官方参考UIContext.setTextSelectionClearPolicy起始版本、默认策略、示例TextSelectionClearPolicy外部触摸的两种行为UIContext获取方式与Stage模型限制
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

◈

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

◐

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

▲

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。