注释概述
福昕 PDF SDK 安卓版支持 PDF 规范中定义的大多数注释(Annotation)类型,通过 Core SDK 提供注释的创建、属性访问与修改、外观生成与绘制等能力。
UI Extensions 内置注释功能
如果您使用的是完整阅读器(UI Extensions),常用注释(高亮、便笺、绘图、图章等)的创建与编辑已通过工具栏内置,用户可直接在 UI 中操作,无需额外编码。本文档主要面向需要通过代码操控注释的场景。
注释类型
下表列出了 PDF 规范定义的注释类型、是否属于 Markup 注释以及 SDK 的支持情况。
| 注释类型 | 类型常量 | 描述 | Markup | SDK 支持 |
|---|---|---|---|---|
| Text (Note) | Annot.e_Note | 便笺/文本批注 | 是 | 支持 |
| Link | Annot.e_Link | 链接跳转注释 | 否 | 支持 |
| FreeText | Annot.e_FreeText | 自由文本(打字机/文本框/标注框) | 是 | 支持 |
| Line | Annot.e_Line | 直线/箭头等线条标注 | 是 | 支持 |
| Square | Annot.e_Square | 矩形框标注 | 是 | 支持 |
| Circle | Annot.e_Circle | 圆形/椭圆标注 | 是 | 支持 |
| Polygon | Annot.e_Polygon | 多边形标注 | 是 | 支持 |
| PolyLine | Annot.e_PolyLine | 折线标注 | 是 | 支持 |
| Highlight | Annot.e_Highlight | 文本高亮标注 | 是 | 支持 |
| Underline | Annot.e_Underline | 文本下划线标注 | 是 | 支持 |
| Squiggly | Annot.e_Squiggly | 波浪下划线标注 | 是 | 支持 |
| StrikeOut | Annot.e_StrikeOut | 删除线标注 | 是 | 支持 |
| Stamp | Annot.e_Stamp | 图章/印章标注 | 是 | 支持 |
| Caret | Annot.e_Caret | 插入符号标注 | 是 | 支持 |
| Ink | Annot.e_Ink | 手绘墨迹/自由笔迹 | 是 | 支持 |
| Popup | Annot.e_Popup | 弹出窗口(显示/编辑注释内容) | 否 | 支持 |
| FileAttachment | Annot.e_FileAttachment | 文件附件注释 | 是 | 支持 |
| Sound | Annot.e_Sound | 声音注释 | 是 | 不支持 |
| Movie | Annot.e_Movie | 影片注释 | 否 | 不支持 |
| Widget | Annot.e_Widget | 表单字段控件注释 | 否 | 支持 |
| Screen | Annot.e_Screen | 屏幕/媒体播放注释 | 否 | 支持 |
| PrinterMark | Annot.e_PrinterMark | 印刷标记注释 | 否 | 不支持 |
| TrapNet | Annot.e_TrapNet | 陷印网注释 | 否 | 不支持 |
| Watermark | Annot.e_Watermark | 水印注释 | 否 | 不支持 |
| 3D | Annot.e_3D | 3D 注释 | 否 | 不支持 |
| Redact | Annot.e_Redact | 密文脱敏注释 | 是 | 支持 |
备注
SDK 额外支持一种自定义注释类型 PSI(Pressure Sensitive Ink,压感笔迹),对应常量 Annot.e_PSInk。该类型在 PDF 规范中未定义,通常用于手写场景。
SDK 不支持 PDF 规范中的 Watermark(水印注释)类型,但支持以页面内容形式添加的水印,详见水印。
基础类层次
SDK 注释类采用继承结构,不同类型的注释从公共基类派生:
Annot ← 所有注释的基类
├── Markup ← 支持标记特性的注释基类(标题、主题、透明度、回复、分组等)
│ ├── TextMarkup ← 文本标记注释基类(Highlight / Underline / StrikeOut / Squiggly)
│ ├── FreeText ← 自由文本注释
│ ├── Note ← 便笺注释
│ ├── Line ← 直线注释
│ ├── Square ← 矩形注释
│ ├── Circle ← 圆形注释
│ ├── Ink ← 墨迹注释
│ ├── Stamp ← 图章注释
│ ├── Caret ← 插入符注释
│ ├── FileAttachment ← 文件附件注释
│ └── Redact ← 密文脱敏注释
├── Link ← 链接注释
├── Screen ← 屏幕注释
├── Widget ← 表单控件注释
└── Popup ← 弹出窗口注释
Annot 基类 — 通用属性
所有注释共享以下 Annot 基类方法:
| 方法 | 说明 |
|---|---|
getType() | 获取注释类型(返回类型常量,如 Annot.e_Note) |
getPage() | 获取注释所在页面 |
getRect() / setRect(RectF) | 获取/设置注释矩形区域 |
move(RectF) | 移动注释到新位置 |
getContent() / setContent(String) | 获取/设置注释文本内容 |
getBorderColor() / setBorderColor(int) | 获取/设置边框颜色 |
getBorderInfo() / setBorderInfo(BorderInfo) | 获取/设置边框信息(宽度、样式、虚线模式) |
getFlags() / setFlags(int) | 获取/设置注释标志位(如不可见、锁定等) |
getUniqueID() / setUniqueID(String) | 获取/设置注释唯一标识 |
getModifiedDateTime() / setModifiedDateTime(DateTime) | 获取/设置修改时间 |
resetAppearanceStream() | 重新生成注释外观流(属性修改后需调用) |
isEmpty() | 检查注释对象是否为空 |
注意
修改注释属性后,必须调用 resetAppearanceStream() 才能使外观更新生效。
Markup 基类 — 标记注释扩展属性
Markup 注释在 Annot 基础上提供以下扩展能力:
| 方法 | 说明 |
|---|---|
getTitle() / setTitle(String) | 获取/设置作者/标题 |
getSubject() / setSubject(String) | 获取/设置主题 |
getOpacity() / setOpacity(float) | 获取/设置透明度(0.0 ~ 1.0) |
getIntent() / setIntent(String) | 获取/设置意图(如 FreeText 的打字机/标注框子类型) |
getCreationDateTime() / setCreationDateTime(DateTime) | 获取/设置创建时间 |
getPopup() / setPopup(Popup) | 获取/设置关联的弹出窗口 |
getReplyCount() | 获取回复数量 |
getReply(int) / addReply() / removeReply(int) | 获取/添加/删除回复(回复为 Note 类型) |
removeAllReplies() | 删除所有回复 |
isGrouped() | 判断注释是否在分组中 |
getGroupHeader() / getGroupElements() / ungroup() | 获取分组头/分组成员/取消分组 |
getStateAnnots(int) / addStateAnnot(...) | 获取/添加状态注释(审阅、标记状态) |
创建注释
通过 PDFPage.addAnnot() 方法在页面上创建注释:
java
import com.foxit.sdk.common.fxcrt.RectF;
import com.foxit.sdk.pdf.PDFDoc;
import com.foxit.sdk.pdf.PDFPage;
import com.foxit.sdk.pdf.annots.Annot;
import com.foxit.sdk.pdf.annots.Note;
PDFDoc doc = new PDFDoc("path/to/Sample.pdf");
doc.load(null);
PDFPage page = doc.getPage(0);
// 指定类型常量和矩形区域创建注释
RectF rect = new RectF(100, 100, 130, 130);
Note note = new Note(page.addAnnot(Annot.e_Note, rect));
// 设置属性
note.setIconName("Comment");
note.setBorderColor(0xff0000ff);
note.setContent("这是一条便笺注释。");
// 生成外观(必须调用)
note.resetAppearanceStream();
doc.saveAs("path/to/output.pdf", PDFDoc.e_SaveFlagNormal);
删除注释
通过 PDFPage.removeAnnot() 方法删除页面上的注释:
java
PDFPage page = doc.getPage(0);
Annot annot = page.getAnnot(0);
if (annot != null && !annot.isEmpty()) {
page.removeAnnot(annot);
}
注释事件监听
使用 AnnotEventListener 监听注释的增删改事件。该接口需要通过 UI Extensions 的 DocumentManager 注册。
java
import com.foxit.sdk.pdf.PDFPage;
import com.foxit.sdk.pdf.annots.Annot;
import com.foxit.uiextensions.UIExtensionsManager;
import com.foxit.uiextensions.annots.AnnotEventListener;
AnnotEventListener listener = new AnnotEventListener() {
@Override
public void onAnnotAdded(PDFPage page, Annot annot) {
// 注释被添加到页面时触发
}
@Override
public void onAnnotWillDelete(PDFPage page, Annot annot) {
// 注释即将被删除时触发(可在此保存注释信息)
}
@Override
public void onAnnotDeleted(PDFPage page, Annot annot) {
// 注释已被删除后触发
}
@Override
public void onAnnotModified(PDFPage page, Annot annot) {
// 注释属性被修改后触发
}
@Override
public void onAnnotChanged(Annot lastAnnot, Annot currentAnnot) {
// 当前选中注释发生切换时触发
}
};
// 通过 UIExtensionsManager 注册事件监听
UIExtensionsManager uiExtensionsManager = ...;
uiExtensionsManager.getDocumentManager().registerAnnotEventListener(listener);
备注
取消注册使用 unregisterAnnotEventListener(listener) 方法。建议在 Activity 生命周期结束时取消注册,避免内存泄漏。
更多注释类型
各注释类型的详细用法请参阅: