No Description

liuxiaolong 1112f9fb51 Merge remote-tracking branch 'origin/pdf_flutter' into pdf_flutter 2 years ago
android 86d0f5463b PDFView Flutter - 注释属性widget拆分 2 years ago
assets a1f39181d9 PDFView Flutter - 1.新增调整阅读背景颜色功能 2 years ago
ios 2e4e549cab PDFView Flutter - 加载iOS内部视图 2 years ago
lib 86d0f5463b PDFView Flutter - 注释属性widget拆分 2 years ago
linux b5fc4562e3 PDFView Flutter - 1.PDF阅读页开发 2.阅读设置交互 2 years ago
macos b5fc4562e3 PDFView Flutter - 1.PDF阅读页开发 2.阅读设置交互 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 86d0f5463b PDFView Flutter - 注释属性widget拆分 2 years ago
analysis_options.yaml 131c0306b0 ConversionFlutter - 初始化工程 2 years ago
pubspec.lock 636a77bfff PDFView Flutter - ios端切换为swift 2 years ago
pubspec.yaml 8e7615ab6b PDFView Flutter - 高亮、下划线、删除线、波浪线注释功能接入 2 years 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

初始化参数

PlatformView(Android)/UIKitView(iOS) 创建时,flutter会携带部分参数在PlatformViewFactory(Android)/FlutterPlatformViewFactory(iOS)中,从而设置默认的CPDFReaderView显示效果

  • 数据格式:Map
  • 参数Key value 说明
    scrollDirection "vertical","horizontal" 滑动方向
    isDoublePage true,false 是否双页显示
    isContinueMode true,false 是否为连续翻页模式
    isCoverPageMode true,false 封面模式
    isCropPageMode true,false 裁剪模式
    readBackgroundColor -1 阅读背景颜色,int类型
    annotAttribute map 注释属性设置,此处将传递map类型
    highlight:{'color' : -1 , 'alpha' : 255 } 设置高亮注释默认属性值,此处为map类型
    strikeout:{'color' : -1 , 'alpha' : 255 } 设置删除线注释默认属性值,此处为map类型
    underline:{'color' : -1 , 'alpha' : 255 } 设置下划线注释默认属性值,此处为map类型
    squiggly:{'color' : -1 , 'alpha' : 255 } 设置波浪线注释默认属性值,此处为map类型
    • 示例
    {
      'scrollDirection' : ScrollDirection.vertical,
      'isDoublePage' : false,
      'isContinueMode' : true,
      'isCoverPageMode' : false,
      'isCropPageMode' : false,
      'readBackgroundColor' : 0xFFFFFFFF,
      'annotAttribute' : {
        'highlight' : {
          'color' : Colors.red.value,
          'alpha' : 255
        },
        'strikeout' : {
          'color' : Colors.green.value,
          'alpha' : 255
        },
        'underline' : {
          'color' : Colors.blue.value,
          'alpha' : 255
        },
        'squiggly' : {
          'color' : Colors.purple.value,
          'alpha' : 255
        }
      }
    }
    

    接口列表

    #### Flutter接入CPDFReaderView * viewType : com.compdfkit.pdf.flutter * [教程](https://flutter.cn/docs/development/platform-integration/ios/platform-views)

    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
      ..addOnPlatformViewCreatedListener((id) {
          setReaderViewCallbackListener();
      })
      
      • UIKitView
      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
      @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
      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
      @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
      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
      • 响应数据:
      参数名称 类型 说明
      -1 int int类型颜色值

      示例:请参考isVerticalMode

      2. 设置阅读背景颜色

      请求

      方法名 通讯方式 数据格式 key value 说明
      setReaderViewBackgroundColor MethodChannel Map backgroundColor -1 传入int类型颜色值

      响应

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

      示例:请参考isVerticalMode


      注释设置

      1. 获取注释属性

      请求

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

      响应

      • 响应数据类型:Map
      • 响应数据:
      • Key Value 类型 说明
        annotAttrColor -1 int 注释颜色
        annotAttrAlpha -1 int 注释颜色透明度
        2. 设置注释属性

        请求

        方法名 通讯方式 数据格式 key value 说明
        setAnnotAttribute MethodChannel Map annotType "highlight","strikeout","underline","squiggly"... 注释类型
        annotAttribute {'color': color, 'alpha':alpha} 此处为map格式数据,alpha范围:0~255

        响应

        • 响应数据类型:Map
        • 响应数据:
        • Key Value 类型 说明
          annotAttrColor -1 int 注释颜色
          annotAttrAlpha -1 int 注释颜色透明度

          设置焦点类型(currentFocusedType)

          请求

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

          响应


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

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

          1. 在原生端Android注册EventChannel,iOS注册FlutterEventChannel,将onListen方法中的EventChannel.EventSink对象保存,以Android示例,iOS基本一致
          
                  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,
                              "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 说明
            annotationType "highlight","strikeout","underline","squiggly"... 注释类型,用于展示不同注释类型的属性调整界面
            annotAttrColor -1 注释颜色
            annotAttrAlpha 0~255 注释颜色透明度

            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
                            }
                        }
                    }
            
            • 修改注释属性
            方法名 通讯方式 数据格式 key value 说明
            modifyAnnotationAttribute MethodChannel Map annotType "highlight","strikeout","underline","squiggly"... 注释类型
            color -1 注释颜色
            alpha 0~255 注释颜色透明度

            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界面关闭属性调整弹窗后发送到原生端