No Description

liuxiaolong b9ba433d5a PDFView Flutter - 超链接注释交互完善,超链接注释内容修改交互 1 year ago
android b9ba433d5a PDFView Flutter - 超链接注释交互完善,超链接注释内容修改交互 1 year ago
assets 342c6ce9a9 PDFView Flutter - 超链接注释UI、交互 1 year ago
ios 9d4424b1dc PDFView Flutter - 注释接口封装 部分示例 1 year ago
lib b9ba433d5a PDFView Flutter - 超链接注释交互完善,超链接注释内容修改交互 1 year ago
linux b5fc4562e3 PDFView Flutter - 1.PDF阅读页开发 2.阅读设置交互 2 years ago
macos ee816ed085 PDFView Flutter - 签名注释 2 years ago
test 131c0306b0 ConversionFlutter - 初始化工程 2 years ago
web 131c0306b0 ConversionFlutter - 初始化工程 2 years ago
windows c77a1b0459 PDFView Flutter - 初始化工程 2 years ago
.gitignore 8e7615ab6b PDFView Flutter - 高亮、下划线、删除线、波浪线注释功能接入 2 years ago
.metadata 131c0306b0 ConversionFlutter - 初始化工程 2 years ago
README.md cfa9b2b312 PDFView Flutter - README.md 文档更新 1 year ago
analysis_options.yaml 131c0306b0 ConversionFlutter - 初始化工程 2 years ago
pubspec.lock 49482ab45e PDFView Flutter - 优化图章注释预览UI 1 year ago
pubspec.yaml 49482ab45e PDFView Flutter - 优化图章注释预览UI 1 year ago

README.md

ComPDFKit SDK Flutter接入文档

接入方案

ComPDFKit SDK在Flutter中采用混合兼容方式进行对接。Android和iOS端分别采用PlatformViewLink和UiKitView,并通过MethodChannel和EventChannel进行交互。我们只封装了CPDFReaderView,而其他注释工具和书签列表等功能则使用Flutter开发。 关于MethodChannel、EventChannel使用方法请参考以下文章 Flutter Native交互

graph TD
A[Flutter] --> B(init Configuration)
B --> C[ComPDFKitWidget.dart]
C -->|Platform.isAndroid| D[PlatformViewlink]
C -->|Platform.isIOS| E[UiKitView]
D --> F[Android]
E --> G[iOS]
F --> H[FlutterCPDFReaderView]
G --> H[FlutterCPDFReaderView]
H --> |return| I[PDFReaderView]
I --> |add| ComPDFKitSDK-CPDFReaderView

交互流程

Flutter与Native端通信使用MethodChannel、EventChannel进行交互,以下将以设置CPDFReaderView翻页模式举例展示交互流程

sequenceDiagram
setIsContinueMode->>MethodChannel: true
MethodChannel->> Native(Android、iOS): invokeMethod(functionName, true)
NOTE right of Native(Android、iOS): CPDFReaderView set isContinueMode = true
Native(Android、iOS)--> MethodChannel: return continue mode
MethodChannel--> setIsContinueMode:get continue mode

对接流程

  1. 原生端继承PlatformView/FlutterPlatFormView 返回CPDFReaderView
  2. PlatformViewFactory 中获取初始化参数,包括PDF文件路径,注释等初始化参数
  3. 通过EventChannel、MethodChannel通信传递数据,完成注释等功能操作

接口列表

#### Flutter接入CPDFReaderView * viewType : com.compdfkit.pdf.flutter * [教程](https://flutter.cn/docs/development/platform-integration/ios/platform-views) #### 初始化参数 在**PlatformView(Android)/UIKitView(iOS)** 创建时,flutter会携带部分参数在PlatformViewFactory(Android)/FlutterPlatformViewFactory(iOS)中,从而设置默认的CPDFReaderView显示效果 * 数据格式:Map | 参数Key | value | 说明 | | --- | --- | --- | | document | | pdf文档路径 | | configuration | | 配置参数 | | scrollDirection | "vertical","horizontal" | 滑动方向 | | isDoublePage | true,false | 是否双页显示 | | isContinueMode | true,false | 是否为连续翻页模式| | isCoverPageMode | true,false | 封面模式 | | isCropPageMode | true,false | 裁剪模式 | | readBackgroundColor | ”#FFFFFF“ | 阅读背景颜色,Hex String类型 | | annotAttribute | map | 注释属性设置,此处将传递map类型 | ||highlight:{'color' : ”#FFFFFF“ , 'alpha' : 255 }| 设置高亮注释默认属性值,此处为map类型 | ||strikeout:{'color' : ”#FFFFFF“ , 'alpha' : 255 }| 设置删除线注释默认属性值,此处为map类型 | ||underline:{'color' : ”#FFFFFF“ , 'alpha' : 255 }| 设置下划线注释默认属性值,此处为map类型 | ||squiggly:{'color' : ”#FFFFFF“ , 'alpha' : 255 }| 设置波浪线注释默认属性值,此处为map类型 | * 示例 ```dart { 'document' : pdfDocumentPath, 'configuration' : { 'scrollDirection' : ScrollDirection.vertical, 'isDoublePage' : false, 'isContinueMode' : true, 'isCoverPageMode' : false, 'isCropPageMode' : false, 'readBackgroundColor' : '#FFFFFF', 'annotAttribute' : { 'highlight' : { 'color' : '#FF0000', 'alpha' : 255 }, 'strikeout' : { 'color' : '#FF0000', 'alpha' : 255 }, 'underline' : { 'color' : '#FF0000', 'alpha' : 255 }, 'squiggly' : { 'color' : '#FF0000', 'alpha' : 255 }, 'shape' : { 'borderColor' : '#FF0000', 'borderColorAlpha' : 255, 'fillColor' : '#FF0000', 'fillColorAlpha' : 0, 'borderWidth' : 2 }, 'freetext' : { 'fontBold' : false, 'fontItalic' : false, 'textColor' : Colors.black.toHex(), 'textColorAlpha' : 255, 'fontSize' : 40, 'fontType' : FontType.helvetica.name } } } } ```

CPDFReaderView响应事件

请求

方法名 通讯方式 参数 说明
event_reader_view_call_back EventChannel "readerViewCallBack" 监听CPDFReaderView滑动位置、点击文档区域、滑动状态监听

响应

  • 响应数据类型:Map
  • 响应数据:
  • Key Value 类型 说明
    eventType onTapMainDocArea String 点击主文档区域监听
    eventType onScrollEnd String 滑动结束
    eventType onScrolling String 滑动中
    eventType onMoveToChild String 滑动到指定页码
    eventType onRecordLastJumpPageNum String 记录上次跳转页码
    eventType pageIndex String 页码,仅onMoveToChild、onRecordLastJumpPageNum

    示例: 1. Flutter中创建EventChannel对象

    const _readerViewCallBackEventChannel =
        EventChannel('event_reader_view_call_back');
    

    2. 定义一个方法例如setReaderViewCallbackListener

    CancelListener setReaderViewCallbackListener() {
      var subscription = _readerViewCallBackEventChannel
          .receiveBroadcastStream(eventSinkId.readerViewCallBack.index)//任何参数都可
          .listen((data) {
        Map<dynamic, dynamic> result = data;
        String eventType = result[EventParameters.eventType];
        switch (eventType) {
          case EventParameters.onTapMainDocArea:
            ...
            break;
          case EventParameters.onMoveToChild:
            int pageIndex = result[EventParameters.pageIndex];
            ...
            break;
          case EventParameters.onRecordLastJumpPageNum:
            int pageIndex = result[EventParameters.pageIndex];
            ...
            break;
          case EventParameters.onScrollEnd:
            ...
            break;
          case EventParameters.onScrolling:
            ...
            break;
          default:
            break;
        }
      }, cancelOnError: true);
      return () {
        subscription.cancel();
      };
    }
    

    3. 在混合集成模式Widget创建完成的回调中调用setReaderViewCallbackListener

    • PlatformViewLink dart ..addOnPlatformViewCreatedListener((id) { setReaderViewCallbackListener(); })
    • UIKitView dart onPlatformViewCreated: (id){ setReaderViewCallbackListener(); }

    4. 事件回调 在IReaderViewCallback中通过EventChannel.EventSink.success返回结果

    Android

    • 注册EventChannel

          val readerViewCallbackEventChannel = EventChannel(messenger, EVENT_CHANNEL_READER_VIEW_CALL_BACK)
          readerViewCallbackEventChannel.setStreamHandler(object : EventChannel.StreamHandler {
              override fun onListen(arguments: Any?, events: EventChannel.EventSink?) {
                  readerView.setReaderViewCallbackEventEmitter1(events)
              }
      
              override fun onCancel(arguments: Any?) {
              }
          })
      
    • 在CPDFReaderView对应的回调中返回数据

      override fun onTapMainDocArea() {
          readerViewCallbackEventEmitter?.success(mapOf("eventType" to “onTapMainDocArea”))
      }
      
      override fun onMoveToChild(pageIndex: Int) {
          readerViewCallbackEventEmitter?.success(mapOf("eventType" to “onMoveToChild”, "pageIndex" to pageIndex))
      }
      
      override fun onEndScroll() {
          readerViewCallbackEventEmitter?.success(mapOf("eventType" to “onScrollEnd”))
      }
      
      override fun onScrolling() {
          readerViewCallbackEventEmitter?.success(mapOf("eventType" to “onScrolling”))
      }
      
      override fun onRecordLastJumpPageNum(pageIndex: Int) {
          readerViewCallbackEventEmitter?.success(mapOf("eventType" to “onRecordLastJumpPageNum”, "pageIndex" to pageIndex))
      }
      

    iOS

    • 注册FlutterEventChannel

    阅读页设置


    设置获取滚动方向(isVerticalMode)

    1.获取滚动方向

    请求

    方法名 通讯方式 参数 说明
    getScrollDirection MethodChannel 获取当前CPDFReaderView滚动方向

    响应

    • 响应数据类型:String
    • 响应数据:
    参数名称 类型 说明
    vertical String 垂直滑动
    horizontal String 水平滑动

    示例

    Flutter获取滚动方向

    ///这里可以定义一个共用的MethodChannel
    const _methodChannel = MethodChannel('com.compdfkit.pdf.flutter');
    
    //获取滚动方向
    Future<bool> scrollDirectionIsVerticalMode() async {
      String scrollDirection =
          await _methodChannel.invokeMethod(Functions.getScrollDirection);
      return scrollDirection == ScrollDirection.vertical;
    }
    

    Android 返回当前滚动方向

    //定义MethodChannel对象
    val methodChannel = MethodChannel(messenger, "com.compdfkit.pdf.flutter")
    methodChannel.setMethodCallHandler(this)
    
    //在onMethodCall方法中返回结果
    override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) {
        when (call.method) {
           “getScrollDirection” -> {
              result.success(if (cpdfReaderView.isVerticalMode) “vertical” else “horizontal”)
         }
    }
    

    iOS 返回当前滚动方向

    • Objective-C ```objc @implementation AppDelegate

    • (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary )launchOptions { FlutterViewController controller = (FlutterViewController)self.window.rootViewController; FlutterMethodChannel methodChannel = [FlutterMethodChannel

                                            methodChannelWithName:@"com.compdfkit.pdf.flutter"
                                            binaryMessenger:controller.binaryMessenger];
      

      [methodChannel setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) {

      if([@"getScrollDirection" isEqualToString:call.method]) {
          result(@"horizontal");//此处仅示例作为参考,请从CPDFReaderView中获取滚动方向
      }
      

      }];

    [GeneratedPluginRegistrant registerWithRegistry:self]; // Override point for customization after application launch. return [super application:application didFinishLaunchingWithOptions:launchOptions]; } @end

    * Swift
    ```swift
    class ComPDFKitPlugin {
        init(messenger : FlutterBinaryMessenger){
            let channel = FlutterMethodChannel(name: "com.compdfkit.pdf.flutter", binaryMessenger: messenger)
            channel.setMethodCallHandler{(call : FlutterMethodCall, result : @escaping FlutterResult) in
                if (call.method == "getScrollDirection"){
                    result("vertical")//此处仅示例作为参考,请从CPDFReaderView中获取滚动方向
                }
            }
        }
    }
    
    @UIApplicationMain
    @objc class AppDelegate: FlutterAppDelegate {
      override func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
      ) -> Bool {
          let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
          ComPDFKitPlugin(messenger: controller.binaryMessenger)//register FlutterMethodChannel
        GeneratedPluginRegistrant.register(with: self)
        return super.application(application, didFinishLaunchingWithOptions: launchOptions)
      }
    }
    
    2. 设置滚动方向

    请求

    方法名 通讯方式 数据格式 key value 说明
    setScrollDirection MethodChannel Map scrollDirection "vertical","horizontal" 设置CPDFReaderView滚动方向

    响应

    • 响应数据传递类型:String
    • 响应事件:
    参数名称 类型 说明
    vertical String 垂直滑动
    horizontal String 水平滑动

    示例

    Flutter 设置CPDFReaderView滚动方向

    ///direction : vertical or horizontal
    Future<bool> setScrollDirection(String direction) async {
      String scrollDirection = await _methodChannel.invokeMethod('setScrollDirection',
          {'scrollDirection': direction});
      //原生端返回当前的滚动状态
      return scrollDirection == ScrollDirection.vertical;
    }
    

    Android端

    MethodChannelonMethodCall方法中获取到Flutter传输的数据

    //在onMethodCall方法中返回结果
    override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) {
        val configuration = call.arguments as? HashMap<String, Any>
        when (call.method) {
           “setScrollDirection” -> {
           (configuration?.get("scrollDirection") as? String)?.let { direction->
                pdfReaderView.pdfReaderView.isVerticalMode = direction == "vertical"
                result.success(if (pdfReaderView.pdfReaderView.isVerticalMode) "vertical" else "horizontal")
           }
           else ->{
            ...
           }
         }
    }
    

    iOS

    • Objective-C ```objc @implementation AppDelegate

    • (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary )launchOptions { FlutterViewController controller = (FlutterViewController)self.window.rootViewController; FlutterMethodChannel methodChannel = [FlutterMethodChannel

                                            methodChannelWithName:@"com.compdfkit.pdf.flutter"
                                            binaryMessenger:controller.binaryMessenger];
      

      [methodChannel setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) {

      if([@"setScrollDirection" isEqualToString:call.method]) {
          NSDictionary* arguments = call.arguments;
          NSString* scrollDirection = arguments[@"scrollDirection"];
          //请从CPDFReaderView获取当前滑动方向并返回
          result(scrollDirection);
      }
      

      }]; [GeneratedPluginRegistrant registerWithRegistry:self]; // Override point for customization after application launch. return [super application:application didFinishLaunchingWithOptions:launchOptions]; } @end ```

    • Swift swift channel.setMethodCallHandler{(call : FlutterMethodCall, result : @escaping FlutterResult) in if (call.method == "setScrollDirection"){ var convertData = arguments as! [String: String]; var scrollDirection = convertData["scrollDirection"] result(scrollDirection)//请从CPDFReaderView获取当前滑动方向并返回 } ... }
    #### 设置获取滚动方式(isContinueMode) ##### **1. 获取滚动模式** **请求** | 方法名 | 通讯方式 | 参数 | 说明 | | --- | --- | --- | --- | | getPageContinue | MethodChannel | 无 |获取当前滚动方式:连续滚动、翻页滚动 | **响应** * 响应数据类型:**Boolean** * 响应数据: | 参数名称 | 类型 | 说明 | | --- | --- | --- | | true | boolean | 连续滚动 | | false | boolean | 翻页滚动 | >示例:请参考[isVerticalMode](#2.1) ##### **2. 设置滚动方式** **请求** | 方法名 | 通讯方式 | 数据格式 | key | value | 说明 | | --- | --- | --- | --- | --- | --- | | setPageContinue | MethodChannel | Map| isContinueMode | true,false| 设置CPDFReaderView滚动方式:连续滚动、翻页滚动 | **响应** * 响应数据传递类型:**Boolean** * 响应事件: | 参数名称 | 类型 | 说明 | | --- | --- | --- | | true | boolean | 连续滚动 | | false | boolean | 翻页滚动 | >示例:请参考[isVerticalMode](#2.1) * * *
    #### 显示模式(isDoublePage) ##### **1. 获取显示模式** **请求** | 方法名 | 通讯方式 | 参数 | 说明 | | --- | --- | --- | --- | | getPageMode | MethodChannel | 无 |单页显示、双页显示 | **响应** * 响应数据类型:**Boolean** * 响应数据: | 参数名称 | 类型 | 说明 | | --- | --- | --- | | true | boolean | 双页显示 | | false | boolean | 单页显示 | >示例:请参考[isVerticalMode](#2.1) ##### **2. 设置显示模式** **请求** | 方法名 | 通讯方式 | 数据格式 | key | value | 说明 | | --- | --- | --- | --- | --- | --- | | setPageMode | MethodChannel | Map| isDoublePage | true,false| 单页显示、双页显示 | **响应** * 响应数据类型:**Boolean** * 响应事件: | 参数名称 | 类型 | 说明 | | --- | --- | --- | | true | boolean | 双页显示 | | false | boolean | 单页显示 | >示例:请参考[isVerticalMode](#2.1) * * *
    #### 封面模式(isCoverPageMode) ##### **1. 获取是否为封面显示模式** **请求** | 方法名 | 通讯方式 | 参数 | 说明 | | --- | --- | --- | --- | | isCoverPageMode | MethodChannel | 无 |显示模式:默认模式、封面模式 | **响应** * 响应数据类型:**Boolean** * 响应数据: | 参数名称 | 类型 | 说明 | | --- | --- | --- | | true | boolean | 封面模式 | | false | boolean | 默认模式 | >示例:请参考[isVerticalMode](#2.1) ##### **2. 设置为封面显示模式** **请求** | 方法名 | 通讯方式 | 数据格式 | key | value | 说明 | | --- | --- | --- | --- | --- | --- | | setCoverPageMode | MethodChannel | Map| isCoverPageMode | true,false| true:双页显示、false:单页显示 | **响应** * 响应数据类型:**Boolean** * 响应事件: | 参数名称 | 类型 | 说明 | | --- | --- | --- | | true | boolean | 封面模式 | | false | boolean | 默认模式 | >示例:请参考[isVerticalMode](#2.1) * * *
    #### 裁剪显示(isCropPageMode) ##### **1. 获取当前是否为裁剪模式** | 方法名 | 通讯方式 | 参数 | 说明 | | --- | --- | --- | --- | | isCropPageMode | MethodChannel | 无 |页面显示模式:默认模式、裁剪模式 | **响应** * 响应数据类型:**Boolean** * 响应数据: | 参数名称 | 类型 | 说明 | | --- | --- | --- | | true | boolean | 裁剪模式 | | false | boolean | 默认模式 | >示例:请参考[isVerticalMode](#2.1) ##### **2. 设置为裁剪显示模式** **请求** | 方法名 | 通讯方式 | 数据格式 | key | value | 说明 | | --- | --- | --- | --- | --- | --- | | setIsCropPageMode | MethodChannel | Map| isCropPageMode | true,false| true:裁剪模式、false:默认模式 | **响应** * 响应数据传递类型:**Boolean** * 响应事件: | 参数名称 | 类型 | 说明 | | --- | --- | --- | | true | boolean | 裁剪模式 | | false | boolean | 默认模式 | >示例:请参考[isVerticalMode](#2.1) * * *

    设置阅读背景颜色(readerBackgroundColor)

    1. 获取当前阅读背景颜色
    方法名 通讯方式 参数 说明
    getReaderViewBackgroundColor MethodChannel 背景颜色

    响应

    • 响应数据类型:Int
    • 响应数据:
    参数名称 类型 说明
    '#FF0000' String String Hex类型颜色值

    示例:请参考isVerticalMode

    2. 设置阅读背景颜色

    请求

    方法名 通讯方式 数据格式 key value 说明
    setReaderViewBackgroundColor MethodChannel Map backgroundColor '#FF0000' 传入String类型颜色值

    响应

    • 响应数据传递类型:int
    • 响应事件:
    参数名称 类型 说明
    "#FF0000" String 当前设置的背景颜色值

    示例:请参考isVerticalMode


    注释设置

    注释类型
    注释类型 说明
    unknown 未知类型,在设置currentFocusedType使用
    highlight 高亮
    strikeout 删除线
    underline 下划线
    squiggly 波浪线
    ink 自由绘制
    shape 形状注释归类,不直接使用
    circle 圆形形状注释
    square 矩形形状注释
    line 线条形状注释
    arrow 箭头形状注释,本质还是line类型注释,增加线条结尾lineType即可
    freetext 自由文本
    signature 签名注释,本质还是图章注释
    stamp 图章注释
    1. 获取注释属性
    • 传入对应注释类型从CPDFReaderView获取对应注释的属性值,但请注意以下问题
      • 图形注释(矩形、圆形、线条、箭头)都属于shape, 获取图形注释请传入AnnotationType.shape会返回矩形注释属性
      • signature、stamp由于是图片,无属性数据

    请求

    方法名 通讯方式 数据格式 key value 说明
    getAnnotAttribute MethodChannel Map annotType "highlight","strikeout","underline","squiggly"... 注释类型

    响应

    • 响应数据类型:Map
    • 响应数据:
    • 注释类型 Key value 类型 说明
      highlight color "#FF0000" String 注释颜色
      alpha 0~255 int 注释颜色透明度
      strokeout color "#FF0000" String 注释颜色
      alpha 0~255 int 注释颜色透明度
      underline color "#FF0000" String 注释颜色
      alpha 0~255 int 注释颜色透明度
      squiggly color "#FF0000" String 注释颜色
      alpha 0~255 int 注释颜色透明度
      shape borderColor "#FF0000" String square边框颜色
      borderColorAlpha 0~255 int square边框颜色透明度
      borderWidth 1~10 int square边框宽度
      fillColor "#FF0000" String square填充颜色
      fillColorAlpha 0~255 int square填充颜色透明度
      shapeType square String 当前获取的形状类型,只返回square
      freetext fontBold true,false bool 字体是否加粗
      fontItalic true,false bool 文字是否斜体
      textColor "#FF0000" String 文字字体颜色
      textColorAlpha 0~255 int 文字颜色透明度
      fontSize 1~100 int 文字大小
      fontType courier,helvetica,times_roman String 字体类型,仅支持三种字体
      signature
      stamp

      signature、stamp由于是图片,无属性数据

      2. 设置注释属性

      请求 根据不同的注释,将会通过Map传递给原生端不同的数据

      注释类型 Key value 类型 说明
      highlight color "#FF0000" String 注释颜色
      alpha 0~255 int 注释颜色透明度
      strokeout color "#FF0000" String 注释颜色
      alpha 0~255 int 注释颜色透明度
      underline color "#FF0000" String 注释颜色
      alpha 0~255 int 注释颜色透明度
      squiggly color "#FF0000" String 注释颜色
      alpha 0~255 int 注释颜色透明度
      shape borderColor "#FF0000" String square边框颜色
      borderColorAlpha 0~255 int square边框颜色透明度
      borderWidth 1~10 int square边框宽度
      fillColor "#FF0000" String square填充颜色
      fillColorAlpha 0~255 int square填充颜色透明度
      shapeType square String 当前获取的形状类型,只返回square
      freetext fontBold true,false bool 字体是否加粗
      fontItalic true,false bool 文字是否斜体
      textColor "#FF0000" String 文字字体颜色
      textColorAlpha 0~255 int 文字颜色透明度
      fontSize 1~100 int 文字大小
      fontType courier,helvetica,times_roman String 字体类型,仅支持三种字体
      signature imagePath data/data/... String 签名图片本地文件路径
      stamp standardStampName 'notapproved'... String SDK内置图章名称
      textStampContent 'Hello world' String 文本图章内容
      textStampDate '2023/03/28' String 文本图章时间
      textStampStyleShapeType 'TEXT_STAMP_NONE','TEXT_STAMP_RECT'... String 文本图章样式,一共四种,无、圆角矩形、左箭头,右箭头
      textStampStyleColorType textStampWhite,textStampRed... String 文本图章颜色类型,白色,红色,绿色,蓝色

      响应

      • 原生端无需返回设置注释属性结果

      设置焦点类型(currentFocusedType)

      请求

      方法名 通讯方式 数据格式 key value 说明
      setCurrentFocusedType MethodChannel Map touchMode "browse","add_annot" 设置触摸模式,browse:浏览模式, add_annot:添加注释模式
      Map focusedType "highlight","strikeout","underline","squiggly"... 注释类型

      请注意,如果需要设置添加形状注释(AnnotationType.shape) 请传入真实的注释类型

      • AnnotationType.circle
      • AnnotationType.square
      • AnnotationType.line
      • AnnotationType.arrow

      响应


      选中注释上下文菜单交互(CPDFContextMenuShowHelper)

      在CPDFReaderView视图中选中注释(例如:高亮),会弹出选择菜单,菜单中可以进行注释的属性调整、复制、删除等操作,其中属性调整需要与Flutter进行交互,通知Flutter弹出注释属性调整界面

      1. 在原生端Android注册EventChannel,iOS注册FlutterEventChannel,将onListen方法中的EventChannel.EventSink对象保存,以Android示例,iOS基本一致 kotlin val readerViewContextMenuHelperEventChannel = EventChannel(messenger, “event_reader_view_context_menu_helper”) readerViewContextMenuHelperEventChannel.setStreamHandler { onListen { arguments, events -> //此处保存events对象 readerView.setContextMenuHelperEventEmitter(events) } }

      2.在自行实现的CPDFContextMenuShowHelper中例如getMarkupContentView方法,点击attribute按钮需要调整注释属性时,通知Flutter展示属性调整界面

          override fun getMarkupContentView(pageView: CPDFPageView, annotImpl: CPDFBaseAnnotImpl<*>, layoutInflater: LayoutInflater): View {
              val contentView = layoutInflater.inflate(R.layout.t_markup_annot_menu_layout, null)
              val markupAnnotImpl = annotImpl as CPDFMarkupAnnotImpl
              val markupAnnotation = markupAnnotImpl.onGetAnnotation()
              invokeOnClickListener(contentView, { v: View ->
                  val id = v.id
                  if (id == R.id.attr) {
                      //此处需要将当前注释、CPDFPageView对象保存到全局变量,以便于后续调整注释属性
                      selectMarkupAnnotImpl = markupAnnotImpl
                      selectPageView = pageView
                      //Notify the flutter side to open the annotation attribute modification interface
                      contextMenuHelperEventEmitter?.success(mapOf(
                          "annotationType" to markupAnnotation.type.name.lowercase(),
                          "annotAttrColor" to markupAnnotation.color.toHex(),
                          "annotAttrAlpha" to markupAnnotation.alpha
                      ))
                  } else if (id == R.id.copy) {
                      ...
                  } else if (id == R.id.delete) {
                      ...
                  }
                  popupWindow.dismiss()
              }, R.id.attr, R.id.copy, R.id.delete)
              return contentView
          }
      
      
      • 传递数据类型:Map
      • 方法名 注释类型 key value 说明
        getMarkupContentView highlight... annotType highlight,strikeout,underline,squiggly 注释类型
        color "#FF0000" 注释颜色
        alpha 0~255 注释颜色透明度
        getInkContentView ink annotType ink 注释类型
        color "#FF0000" 注释颜色
        alpha 0~255 注释颜色透明度
        borderWidth 注释颜色
        alpha 1~70 画笔宽度
        getShapeContentView circle... annotType circle,square,line,arrow 注释类型
        borderColor "#FF0000" 边框线条颜色
        borderColorAlpha 0~255 边框线条颜色透明度
        borderWidth 1~10 边框线条宽度
        fillColor "#FF0000" 填充颜色
        fillColorAlpha 0~255 填充颜色透明度
        shapeType circle,square,line,arrow 选中的形状注释类型,4种
        getFreetextContentView freetext annotType freetext 注释类型
        fontBold true,false 文字是否加粗
        fontItalic true,false 文字是否斜体
        fontType courier,helvetica,times_roman 字体类型
        textColor "#FF0000" 文字颜色
        textColorAlpha 0~255 文字透明度
        fontSize 1~100 文字大小

        3.在实现的CPDFContextMenuShowHelper中定义MethodChannel获取Flutter端传入的需要修改的注释属性

                modifyAnnotationAttrChannel = MethodChannel(messenger,“method_modify_annotation_attribute”)
                modifyAnnotationAttrChannel.setMethodCallHandler { call, result ->
                    //这里获取flutter传入的颜色、透明度等参数
                    val configuration = call.arguments as? HashMap<String, Any>
                    when(call.method){
                        “modifyAnnotationAttribute” ->{
                            //颜色、透明度可能为空,注意判断,可能用户只调节一个属性
                            val annotAttrColor = configuration.getLong("color")
                            val annotAttrAlpha = configuration.getInt("alpha")
                            val annotationType = configuration.getString(PluginUtils.KEY_ANNOT_TYPE)
                            selectMarkupAnnotImpl?.let {
                                if (it.onGetAnnotation().type.name.equals(annotationType, true)) {
                                    it.onGetAnnotation()?.let {annotation->
                                        if (annotAttrColor != null) {
                                            annotation.color = annotAttrColor.toInt()
                                        }
                                        if (annotAttrAlpha != null) {
                                            annotation.alpha = annotAttrAlpha
                                        }
                                        annotation.updateAp()
                                        selectMarkupAnnotImpl?.onAnnotAttrChange()
                                        selectPageView?.invalidate()
                                    }
                                }
                            }
                        }
                        ...
                        KEY_DISMISS_MODIFY_ANNOTATION_ATTRIBUTE -> {
                            selectMarkupAnnotImpl = null
                            selectPageView = null
                        }
                    }
                }
        
        • 修改注释属性
          • 通信方式:MethodChannel
          • MethodChannel Name: modifyAnnotationAttribute
          • 数据格式:Map
        • 注释类型 Key value 类型 说明
          highlight color "#FF0000" String 注释颜色
          alpha 0~255 int 注释颜色透明度
          strokeout color "#FF0000" String 注释颜色
          alpha 0~255 int 注释颜色透明度
          underline color "#FF0000" String 注释颜色
          alpha 0~255 int 注释颜色透明度
          squiggly color "#FF0000" String 注释颜色
          alpha 0~255 int 注释颜色透明度
          shape borderColor "#FF0000" String square边框颜色
          borderColorAlpha 0~255 int square边框颜色透明度
          borderWidth 1~10 int square边框宽度
          fillColor "#FF0000" String square填充颜色
          fillColorAlpha 0~255 int square填充颜色透明度
          shapeType square String 当前获取的形状类型,只返回square
          freetext fontBold true,false bool 字体是否加粗
          fontItalic true,false bool 文字是否斜体
          textColor "#FF0000" String 文字字体颜色
          textColorAlpha 0~255 int 文字颜色透明度
          fontSize 1~100 int 文字大小
          fontType courier,helvetica,times_roman String 字体类型,仅支持三种字体
          signature
          stamp

          4.在用户关闭调节选项弹窗后会发出dismissModifyAnnotationAttr通知,请在此通知中释放之前赋值的全局变量

                  modifyAnnotationAttrChannel = MethodChannel(messenger,“method_modify_annotation_attribute”)
                  modifyAnnotationAttrChannel.setMethodCallHandler { call, result ->
                      //这里获取flutter传入的颜色、透明度等参数
                      val configuration = call.arguments as? HashMap<String, Any>
                      when(call.method){
                          “modifyAnnotationAttribute” ->{
                          ...
                          }
                          "dismissModifyAnnotationAttr" -> {
                              selectMarkupAnnotImpl = null
                              selectPageView = null
                          }
                      }
                  }
          
          方法名 通讯方式 说明
          dismissModifyAnnotationAttr MethodChannel flutter界面关闭属性调整弹窗后发送到原生端

          CPDFReaderView 注释状态变化监听

          在设置完签名注释、图章注释后,当前的currentFocusedType、touchMode会改变,当前焦点会从添加注释状态改为阅读状态,所以需要监听cpdfReaderView.setOnFocusedTypeChangedListener 通知flutter端当前的状态,以便于底部注释工具类选中状态变更

          请求

          方法名 通讯方式 参数 说明
          event_reader_view_focused_change_call_back EventChannel "readerViewFocusedChange" 监听CPDFReaderView焦点类型改变

          原生端响应 原生端请实现cpdfReaderView.setOnFocusedTypeChangedListener方法,并返回当前的注释类型(CPDFAnnotation.Type) iOS端请通过FlutterEventChannel返回当前焦点类型

          • Android示例 ```kotlin

            // 首先定义EventChannel
            val readerViewFocusedChangEventChannel = EventChannel(messenger, "event_reader_view_focused_change_call_back")
            readerViewFocusedChangEventChannel.setStreamHandler {
                onListen { arguments, events ->
                    readerView.setFocusedChangeEventEmitter(events)
                }
            }
            
            //CPDFReaderView监听焦点类型变化,通过EventChannel传递给flutter端,直接传入注释类型即可,CPDFAnnotation.Type
            pdfReaderView.setOnFocusedTypeChangedListener {
                focusedChangeCallbackEventEmitter?.success(it.name)
            }
            

          ```