Browse Source

ComPDFKit(flutter) - android PlatformView嵌入测试

liuxiaolong 1 year ago
parent
commit
0c8258ab6e

+ 3 - 1
android/src/main/AndroidManifest.xml

@@ -1,5 +1,7 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-  package="com.compdfkit.flutter.compdfkit_flutter">
+    xmlns:tools="http://schemas.android.com/tools"
+    package="com.compdfkit.flutter.compdfkit_flutter">
+
     <application>
 
     </application>

+ 2 - 1
android/src/main/java/com/compdfkit/flutter/compdfkit_flutter/CompdfkitFlutterPlugin.java

@@ -27,7 +27,8 @@ public class CompdfkitFlutterPlugin implements FlutterPlugin, ActivityAware {
     @Override
     public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) {
         mMessenger = flutterPluginBinding.getBinaryMessenger();
-        new ComPDFKitSDKPlugin(flutterPluginBinding.getApplicationContext(), mMessenger);
+        new ComPDFKitSDKPlugin(flutterPluginBinding.getApplicationContext(), mMessenger,
+                flutterPluginBinding.getPlatformViewRegistry());
     }
 
     @Override

+ 3 - 0
android/src/main/java/com/compdfkit/flutter/compdfkit_flutter/plugin/BaseMethodChannelPlugin.java

@@ -23,8 +23,11 @@ public abstract class BaseMethodChannelPlugin implements MethodChannel.MethodCal
 
     protected Context context;
 
+    protected BinaryMessenger binaryMessenger;
+
     public BaseMethodChannelPlugin(Context context, BinaryMessenger binaryMessenger) {
         this.context = context;
+        this.binaryMessenger = binaryMessenger;
         methodChannel = new MethodChannel(binaryMessenger, methodName());
         methodChannel.setMethodCallHandler(this);
     }

+ 34 - 4
android/src/main/java/com/compdfkit/flutter/compdfkit_flutter/plugin/ComPDFKitSDKPlugin.java

@@ -18,18 +18,20 @@ import com.compdfkit.core.document.CPDFSdk;
 import com.compdfkit.tools.common.pdf.CPDFConfigurationUtils;
 import com.compdfkit.tools.common.pdf.CPDFDocumentActivity;
 import com.compdfkit.tools.common.pdf.config.CPDFConfiguration;
-import com.compdfkit.tools.common.utils.CToastUtil;
 
-import org.json.JSONObject;
+import com.compdfkit.flutter.compdfkit_flutter.ui.reader.platformview.CPDFViewCtrlFactory;
 
 import java.util.Map;
 
+import io.flutter.embedding.engine.plugins.activity.ActivityAware;
+import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding;
 import io.flutter.plugin.common.BinaryMessenger;
 import io.flutter.plugin.common.MethodCall;
 import io.flutter.plugin.common.MethodChannel;
+import io.flutter.plugin.platform.PlatformViewRegistry;
 
 
-public class ComPDFKitSDKPlugin extends BaseMethodChannelPlugin {
+public class ComPDFKitSDKPlugin extends BaseMethodChannelPlugin implements ActivityAware {
 
     public static final String INIT_SDK = "init_sdk";
 
@@ -39,8 +41,16 @@ public class ComPDFKitSDKPlugin extends BaseMethodChannelPlugin {
 
     public static final String SDK_BUILD_TAG = "sdk_build_tag";
 
-    public ComPDFKitSDKPlugin(Context context, BinaryMessenger binaryMessenger) {
+    private static final String PDF_DOCUMENT_VIEW_TYPE_ID = "com.compdfkit.flutter.ui.pdfviewer";
+
+    private PlatformViewRegistry mRegistry;
+
+    public ComPDFKitSDKPlugin(Context context, BinaryMessenger binaryMessenger, PlatformViewRegistry registry) {
         super(context, binaryMessenger);
+        this.mRegistry = registry;
+        if (mRegistry != null) {
+            mRegistry.registerViewFactory(PDF_DOCUMENT_VIEW_TYPE_ID,new CPDFViewCtrlFactory(binaryMessenger));
+        }
     }
 
     @Override
@@ -87,4 +97,24 @@ public class ComPDFKitSDKPlugin extends BaseMethodChannelPlugin {
     public String methodName() {
         return "com.compdfkit.flutter.plugin";
     }
+
+    @Override
+    public void onAttachedToActivity(@NonNull ActivityPluginBinding binding) {
+
+    }
+
+    @Override
+    public void onDetachedFromActivityForConfigChanges() {
+
+    }
+
+    @Override
+    public void onReattachedToActivityForConfigChanges(@NonNull ActivityPluginBinding binding) {
+
+    }
+
+    @Override
+    public void onDetachedFromActivity() {
+
+    }
 }

+ 40 - 0
android/src/main/java/com/compdfkit/flutter/compdfkit_flutter/ui/reader/platformview/CPDFViewCtrlFactory.java

@@ -0,0 +1,40 @@
+/**
+ * Copyright © 2014-2024 PDF Technologies, Inc. All Rights Reserved.
+ * <p>
+ * THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW
+ * AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE ComPDFKit LICENSE AGREEMENT.
+ * UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.
+ * This notice may not be removed from this file.
+ */
+
+package com.compdfkit.flutter.compdfkit_flutter.ui.reader.platformview;
+
+
+import android.content.Context;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import java.util.Map;
+
+import io.flutter.plugin.common.BinaryMessenger;
+import io.flutter.plugin.common.StandardMessageCodec;
+import io.flutter.plugin.platform.PlatformView;
+import io.flutter.plugin.platform.PlatformViewFactory;
+
+public class CPDFViewCtrlFactory extends PlatformViewFactory {
+
+    private BinaryMessenger binaryMessenger;
+
+    public CPDFViewCtrlFactory(BinaryMessenger binaryMessenger) {
+        super(StandardMessageCodec.INSTANCE);
+        this.binaryMessenger = binaryMessenger;
+    }
+
+    @NonNull
+    @Override
+    public PlatformView create(Context context, int viewId, @Nullable Object args) {
+        Map<String, Object> creationParams = (Map<String, Object>) args;
+        return new CPDFViewCtrlFlutter(context, binaryMessenger, viewId, creationParams);
+    }
+}

+ 124 - 0
android/src/main/java/com/compdfkit/flutter/compdfkit_flutter/ui/reader/platformview/CPDFViewCtrlFlutter.java

@@ -0,0 +1,124 @@
+/**
+ * Copyright © 2014-2024 PDF Technologies, Inc. All Rights Reserved.
+ * <p>
+ * THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW
+ * AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE ComPDFKit LICENSE AGREEMENT.
+ * UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.
+ * This notice may not be removed from this file.
+ */
+
+package com.compdfkit.flutter.compdfkit_flutter.ui.reader.platformview;
+
+
+import android.content.Context;
+import android.content.MutableContextWrapper;
+import android.view.View;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.fragment.app.FragmentActivity;
+import androidx.fragment.app.FragmentContainerView;
+
+import com.compdfkit.tools.common.pdf.CPDFConfigurationUtils;
+import com.compdfkit.tools.common.pdf.CPDFDocumentFragment;
+import com.compdfkit.tools.common.pdf.config.CPDFConfiguration;
+
+import java.util.Map;
+
+import io.flutter.plugin.common.BinaryMessenger;
+import io.flutter.plugin.platform.PlatformView;
+
+public class CPDFViewCtrlFlutter implements PlatformView {
+
+    private FragmentContainerView fragmentContainerView;
+
+    private CPDFDocumentFragment documentFragment;
+
+    private BinaryMessenger binaryMessenger;
+
+    private int viewId;
+
+    public CPDFViewCtrlFlutter(Context context, BinaryMessenger binaryMessenger, int viewId, Map<String, Object> creationParams) {
+        this.binaryMessenger = binaryMessenger;
+        this.viewId = viewId;
+        // Initialize CPDFViewCtrl and initialize related configuration information
+        initCPDFViewCtrl(context, creationParams);
+    }
+
+    private void initCPDFViewCtrl(Context context, Map<String, Object> creationParams) {
+        fragmentContainerView = new FragmentContainerView(context);
+        fragmentContainerView.setId(View.generateViewId());
+        String filePath = (String) creationParams.get("document");
+        String password = (String) creationParams.get("password");
+        CPDFConfiguration configuration = CPDFConfigurationUtils.normalConfig(context, "tools_default_configuration.json");
+
+        documentFragment = CPDFDocumentFragment.newInstance(filePath, password, configuration);
+
+        fragmentContainerView.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
+            @Override
+            public void onViewAttachedToWindow(@NonNull View v) {
+                FragmentActivity fragmentActivity = getFragmentActivity(context);
+                if (fragmentActivity != null) {
+                    fragmentActivity.getSupportFragmentManager()
+                            .beginTransaction()
+                            .add(fragmentContainerView.getId(), documentFragment)
+                            .setReorderingAllowed(true)
+                            .commitNow();
+                }
+            }
+
+            @Override
+            public void onViewDetachedFromWindow(@NonNull View v) {
+                FragmentActivity fragmentActivity = getFragmentActivity(context);
+                if (fragmentActivity != null) {
+                    fragmentActivity.getSupportFragmentManager()
+                            .beginTransaction()
+                            .remove(documentFragment)
+                            .setReorderingAllowed(true)
+                            .commit();
+                }
+            }
+        });
+    }
+
+    @Nullable
+    @Override
+    public View getView() {
+        return fragmentContainerView;
+    }
+
+    @Override
+    public void onFlutterViewAttached(@NonNull View flutterView) {
+        PlatformView.super.onFlutterViewAttached(flutterView);
+    }
+
+    @Override
+    public void onFlutterViewDetached() {
+        PlatformView.super.onFlutterViewDetached();
+    }
+
+    @Override
+    public void dispose() {
+       fragmentContainerView = null;
+    }
+
+    @Override
+    public void onInputConnectionLocked() {
+        PlatformView.super.onInputConnectionLocked();
+    }
+
+    @Override
+    public void onInputConnectionUnlocked() {
+        PlatformView.super.onInputConnectionUnlocked();
+    }
+
+    private FragmentActivity getFragmentActivity(Context context) {
+        if (context instanceof FragmentActivity){
+            return (FragmentActivity) context;
+        } else if (context instanceof MutableContextWrapper) {
+            return getFragmentActivity(((MutableContextWrapper) context).getBaseContext());
+        } else {
+            return null;
+        }
+    }
+}

+ 4 - 0
example/android/app/build.gradle

@@ -78,4 +78,8 @@ flutter {
 dependencies {
 
     api fileTree(include: ['*.jar', '*.aar'], dir: 'libs')
+    implementation 'com.google.android.material:material:1.8.0'
+    implementation 'androidx.appcompat:appcompat:1.6.1'
+    implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
+
 }

+ 1 - 0
example/android/app/src/main/AndroidManifest.xml

@@ -1,4 +1,5 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
     package="com.compdfkit.flutter.example">
 
     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

+ 11 - 2
example/android/app/src/main/java/com/compdfkit/flutter/example/MainActivity.java

@@ -9,7 +9,16 @@
 
 package com.compdfkit.flutter.example;
 
-import io.flutter.embedding.android.FlutterActivity;
+import android.os.Bundle;
 
-public class MainActivity extends FlutterActivity {
+import androidx.annotation.Nullable;
+
+import io.flutter.embedding.android.FlutterFragmentActivity;
+
+public class MainActivity extends FlutterFragmentActivity {
+
+    @Override
+    protected void onCreate(@Nullable Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+    }
 }

+ 1 - 1
example/android/app/src/main/res/values-night/styles.xml

@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <resources>
     <!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is on -->
-    <style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
+    <style name="LaunchTheme" parent="Theme.AppCompat.DayNight.NoActionBar">
         <!-- Show a splash screen on the activity. Automatically removed when
              the Flutter engine draws its first frame -->
         <item name="android:windowBackground">@drawable/launch_background</item>

+ 11 - 2
example/android/app/src/main/res/values/styles.xml

@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
-<resources>
+<resources xmlns:tools="http://schemas.android.com/tools">
     <!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is off -->
-    <style name="LaunchTheme" parent="@android:style/Theme.Light.NoTitleBar">
+    <style name="LaunchTheme" parent="Theme.AppCompat.Light.NoActionBar">
         <!-- Show a splash screen on the activity. Automatically removed when
              the Flutter engine draws its first frame -->
         <item name="android:windowBackground">@drawable/launch_background</item>
@@ -15,4 +15,13 @@
     <style name="NormalTheme" parent="@android:style/Theme.Light.NoTitleBar">
         <item name="android:windowBackground">?android:colorBackground</item>
     </style>
+
+
+    <style name="Basic_Theme" parent="Theme.MaterialComponents.DayNight.NoActionBar">
+        <item name="android:statusBarColor">@color/tools_color_primary</item>
+        <item name="android:windowLightStatusBar" tools:targetApi="m">true</item>
+        <item name="android:colorAccent">@color/tools_color_accent</item>
+        <item name="android:colorPrimary">@color/tools_color_accent</item>
+    </style>
+
 </resources>

+ 2 - 0
example/android/build.gradle

@@ -3,6 +3,7 @@ buildscript {
     repositories {
         google()
         mavenCentral()
+        mavenLocal()
     }
 
     dependencies {
@@ -15,6 +16,7 @@ allprojects {
     repositories {
         google()
         mavenCentral()
+        mavenLocal()
     }
 }
 

+ 0 - 47
example/ios/Podfile

@@ -1,47 +0,0 @@
-# Uncomment this line to define a global platform for your project
-# platform :ios, '12.0'
-
-# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
-ENV['COCOAPODS_DISABLE_STATS'] = 'true'
-
-project 'Runner', {
-  'Debug' => :debug,
-  'Profile' => :release,
-  'Release' => :release,
-}
-
-def flutter_root
-  generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
-  unless File.exist?(generated_xcode_build_settings_path)
-    raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
-  end
-
-  File.foreach(generated_xcode_build_settings_path) do |line|
-    matches = line.match(/FLUTTER_ROOT\=(.*)/)
-    return matches[1].strip if matches
-  end
-  raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
-end
-
-require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
-
-flutter_ios_podfile_setup
-
-target 'Runner' do
-  use_frameworks!
-  use_modular_headers!
-
-  pod 'ComPDFKit', :git => 'https://github.com/ComPDFKit/compdfkit-pdf-sdk-ios-swift.git', :tag => '1.13.0'
-  pod 'ComPDFKit_Tools', :git => 'https://github.com/ComPDFKit/compdfkit-pdf-sdk-ios-swift.git', :tag => '1.13.0'
-
-  flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
-  target 'RunnerTests' do
-    inherit! :search_paths
-  end
-end
-
-post_install do |installer|
-  installer.pods_project.targets.each do |target|
-    flutter_additional_ios_build_settings(target)
-  end
-end

+ 4 - 1
example/lib/l10n/app_en.arb

@@ -20,5 +20,8 @@
   "compdf_technical_support_url":"https://www.compdf.com/support",
   "compdf_contact_sales_url":"https://www.compdf.com/contact-sales",
   "compdf_privacy_policy_url":"https://www.compdf.com/privacy-policy",
-  "compdf_terms_of_service_url":"https://www.compdf.com/terms-of-service"
+  "compdf_terms_of_service_url":"https://www.compdf.com/terms-of-service",
+  "show_pdf_reader_widget_title":"Show CPDFReaderWidget",
+  "show_pdf_reader_widget_desc":"Display PDF view in flutter widget",
+  "loading" : "Loading..."
 }

+ 5 - 1
example/lib/l10n/app_zh.arb

@@ -20,5 +20,9 @@
   "compdf_technical_support_url":"https://www.compdf.com/support",
   "compdf_contact_sales_url":"https://www.compdf.com/zh-cn/contact-sales",
   "compdf_privacy_policy_url":"https://www.compdf.com/zh-cn/privacy-policy/",
-  "compdf_terms_of_service_url":"https://www.compdf.com/zh-cn/terms-of-service"
+  "compdf_terms_of_service_url":"https://www.compdf.com/zh-cn/terms-of-service",
+  "show_pdf_reader_widget_title":"展示 CPDFReaderWidget",
+  "show_pdf_reader_widget_desc":"在Flutter Widget中展示PDF视图",
+  "loading" : "加载中..."
+
 }

+ 5 - 1
example/lib/l10n/app_zh_Hant.arb

@@ -20,5 +20,9 @@
   "compdf_technical_support_url":"https://www.compdf.com/support",
   "compdf_contact_sales_url":"https://www.compdf.com/zh-cn/contact-sales",
   "compdf_privacy_policy_url":"https://www.compdf.com/zh-cn/privacy-policy/",
-  "compdf_terms_of_service_url":"https://www.compdf.com/zh-cn/terms-of-service"
+  "compdf_terms_of_service_url":"https://www.compdf.com/zh-cn/terms-of-service",
+  "show_pdf_reader_widget_title":"展示 CPDFReaderWidget",
+  "show_pdf_reader_widget_desc":"在Flutter Widget中展示PDF視圖",
+  "loading" : "載入中..."
+
 }

+ 11 - 0
example/lib/main.dart

@@ -10,6 +10,7 @@ import 'dart:io';
 import 'package:compdfkit_flutter/compdfkit.dart';
 import 'package:compdfkit_flutter/cpdf_configuration.dart';
 import 'package:compdfkit_flutter_example/features.dart';
+import 'package:compdfkit_flutter_example/page/pdf/pdf_page.dart';
 import 'package:compdfkit_flutter_example/page/settings_page.dart';
 import 'package:compdfkit_flutter_example/theme/themes.dart';
 import 'package:compdfkit_flutter_example/utils/file_util.dart';
@@ -86,6 +87,12 @@ class _HomePageState extends State<HomePage> {
     }
   }
 
+  void showCPDFReaderWidget(){
+    Navigator.push(context, MaterialPageRoute(builder: (context){
+      return const PDFDocumentPage();
+    }));
+  }
+
   @override
   Widget build(BuildContext context) {
     final exampleList = <Widget>[
@@ -101,6 +108,10 @@ class _HomePageState extends State<HomePage> {
           title: AppLocalizations.of(context)!.pick_document_title,
           description: AppLocalizations.of(context)!.pick_document_desc,
           onTap: () => pickDocument()),
+      FeatureItem(
+          title: AppLocalizations.of(context)!.show_pdf_reader_widget_title,
+          description: AppLocalizations.of(context)!.show_pdf_reader_widget_desc,
+          onTap: () => showCPDFReaderWidget())
     ];
 
     return Scaffold(

+ 63 - 0
example/lib/page/pdf/pdf_page.dart

@@ -0,0 +1,63 @@
+///  Copyright © 2014-2024 PDF Technologies, Inc. All Rights Reserved.
+///
+///  THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW
+///  AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE ComPDFKit LICENSE AGREEMENT.
+///  UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.
+///  This notice may not be removed from this file.
+///
+
+import 'dart:io';
+
+import 'package:compdfkit_flutter/cpdf_configuration.dart';
+import 'package:compdfkit_flutter/widgets/cpdf_reader_widget.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_gen/gen_l10n/app_localizations.dart';
+
+import '../../utils/file_util.dart';
+
+
+class PDFDocumentPage extends StatefulWidget {
+  const PDFDocumentPage({super.key});
+
+  @override
+  State<PDFDocumentPage> createState() => _PDFDocumentPageState();
+}
+
+class _PDFDocumentPageState extends State<PDFDocumentPage> {
+  @override
+  Widget build(BuildContext context) {
+    return Scaffold(
+        appBar: AppBar(title: const Text('CPDFReaderWidget'),),
+        body: SafeArea(
+            child: Column(
+          children: [
+            Expanded(
+                child: FutureBuilder(
+                    future: getPDFPath(),
+                    builder: (context, snapShot) {
+                      if (snapShot.connectionState == ConnectionState.done &&
+                          snapShot.hasData) {
+                        String document = snapShot.data!;
+                        return CPDFReaderWidget(
+                            document: document,
+                            configuration: CPDFConfiguration());
+                      } else {
+                        return Center(
+                          child: Column(
+                            children: [
+                              const CircularProgressIndicator(),
+                              Text(AppLocalizations.of(context)!.loading)
+                            ],
+                          ),
+                        );
+                      }
+                    }))
+          ],
+        )));
+  }
+
+  Future<String> getPDFPath() async {
+    File document = await extractAsset(context, 'pdfs/PDF_Document.pdf');
+    return document.path;
+  }
+}

+ 91 - 0
ios/Classes/reader/CPDFViewCtrlFactory.swift

@@ -0,0 +1,91 @@
+//
+//  CPDFViewCtrlFactory.swift
+//
+//  Copyright © 2014-2023 PDF Technologies, Inc. All Rights Reserved.
+//
+//  THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW
+//  AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE ComPDFKit LICENSE AGREEMENT.
+//  UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.
+//  This notice may not be removed from this file.
+
+
+import Flutter
+import UIKit
+import ComPDFKit
+import ComPDFKit_Tools
+
+class CPDFViewCtrlFactory: NSObject, FlutterPlatformViewFactory {
+    private let messenger: FlutterBinaryMessenger
+
+    init(messenger: FlutterBinaryMessenger) {
+        self.messenger = messenger
+        super.init()
+    }
+
+    func create(
+        withFrame frame: CGRect,
+        viewIdentifier viewId: Int64,
+        arguments args: Any?
+    ) -> FlutterPlatformView {
+        return CPDFViewCtrlFlutter(
+            frame: frame,
+            viewIdentifier: viewId,
+            arguments: args,
+            binaryMessenger: messenger)
+    }
+    
+    func createArgsCodec() -> FlutterMessageCodec & NSObjectProtocol {
+        return FlutterStandardMessageCodec.sharedInstance()
+    }
+}
+
+class CPDFViewCtrlFlutter: NSObject, FlutterPlatformView,CPDFViewBaseControllerDelete {
+    
+    private var _pdfViewController : CPDFViewController
+    
+    private var _navigationController : CNavigationController
+    
+
+    init(
+        frame: CGRect,
+        viewIdentifier viewId: Int64,
+        arguments args: Any?,
+        binaryMessenger messenger: FlutterBinaryMessenger?
+    ) {
+        
+        // 解析 文档路径、密码、配置信息
+        let initInfo = args as? [String: Any]
+        let jsonString = initInfo?["configuration"] ?? ""
+        let password = initInfo?["password"] ?? ""
+        let path = initInfo?["document"] as? String ?? ""
+        
+        let jsonDataParse = CPDFJSONDataParse(String: jsonString as! String)
+        let configuration = jsonDataParse.configuration
+        
+        // 创建pdfview controller视图
+        _pdfViewController = CPDFViewController(filePath: path, password: password as! String, configuration: configuration!)
+        
+        _navigationController = CNavigationController(rootViewController: _pdfViewController)
+        _navigationController.view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
+        _navigationController.view.frame = frame
+        
+        super.init()
+        
+        // 设置代理,但是未生效
+        _pdfViewController.delegate = self
+        
+        _navigationController.setViewControllers([_pdfViewController], animated: false)
+
+    }
+
+    func view() -> UIView {
+        return _navigationController.view
+    }
+        
+    public func PDFViewBaseControllerDissmiss(_ baseControllerDelete: CPDFViewBaseController) {
+        baseControllerDelete.dismiss(animated: true)
+    }
+}
+
+
+

+ 5 - 0
lib/cpdf_configuration.dart

@@ -29,6 +29,7 @@ import 'cpdf_options.dart';
 ///
 /// ```
 class CPDFConfiguration {
+
   ModeConfig modeConfig;
 
   ToolbarConfig toolbarConfig;
@@ -498,6 +499,7 @@ class CPDFBorderStyle {
 }
 
 class CPDFContentEditorConfig {
+
   final List<CPDFContentEditorType> availableTypes;
 
   final List<CPDFConfigTool> availableTools;
@@ -525,6 +527,7 @@ class CPDFContentEditorAttribute {
 }
 
 class CPDFContentEditorAttr {
+
   final Color fontColor;
 
   final int fontColorAlpha;
@@ -560,6 +563,7 @@ class CPDFContentEditorAttr {
 }
 
 class CPDFFormsConfig {
+
   final List<CPDFFormType> availableTypes;
 
   final List<CPDFFormConfigTool> availableTools;
@@ -579,6 +583,7 @@ class CPDFFormsConfig {
 }
 
 class CPDFFormAttribute {
+
   final CPDFFormAttr textField;
 
   final CPDFFormAttr checkBox;

+ 2 - 1
lib/util/extension/cpdf_color_extension.dart

@@ -9,7 +9,8 @@ import 'package:flutter/material.dart';
 ///  UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.
 ///  This notice may not be removed from this file.
 
-extension HexColor on Color {
+
+extension HexColor on Color{
   String toHex({bool leadingHashSign = true}) => '${leadingHashSign ? '#' : ''}'
       '${alpha.toRadixString(16).padLeft(2, '0')}'
       '${red.toRadixString(16).padLeft(2, '0')}'

+ 91 - 0
lib/widgets/cpdf_reader_widget.dart

@@ -0,0 +1,91 @@
+///  Copyright © 2014-2024 PDF Technologies, Inc. All Rights Reserved.
+///
+///  THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW
+///  AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE ComPDFKit LICENSE AGREEMENT.
+///  UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.
+///  This notice may not be removed from this file.
+
+import 'dart:io';
+
+import 'package:compdfkit_flutter/cpdf_configuration.dart';
+import 'package:flutter/foundation.dart';
+import 'package:flutter/gestures.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter/rendering.dart';
+import 'package:flutter/services.dart';
+
+class CPDFReaderWidget extends StatefulWidget {
+  /// pdf file path
+  final String document;
+
+  final String? password;
+
+  /// init ComPDFKit SDK configuration
+  final CPDFConfiguration configuration;
+
+  /// init callback
+  const CPDFReaderWidget({
+    Key? key,
+    required this.document,
+    this.password = '',
+    required this.configuration,
+  }) : super(key: key);
+
+  @override
+  State<CPDFReaderWidget> createState() => _CPDFReaderWidgetState();
+}
+
+class _CPDFReaderWidgetState extends State<CPDFReaderWidget> {
+  @override
+  Widget build(BuildContext context) {
+    const String viewType = 'com.compdfkit.flutter.ui.pdfviewer';
+    final Map<String, dynamic> creationParams = <String, dynamic>{
+      'document': widget.document,
+      'password': widget.password,
+      'configuration': widget.configuration.toJson()
+    };
+
+    if (Platform.isAndroid) {
+      return PlatformViewLink(
+          surfaceFactory:
+              (BuildContext context, PlatformViewController controller) {
+            return AndroidViewSurface(
+                controller: controller as AndroidViewController,
+                hitTestBehavior: PlatformViewHitTestBehavior.opaque,
+                gestureRecognizers: const <Factory<
+                    OneSequenceGestureRecognizer>>{});
+          },
+          onCreatePlatformView: (PlatformViewCreationParams params) {
+            return PlatformViewsService.initSurfaceAndroidView(
+                id: params.id,
+                viewType: viewType,
+                creationParams: creationParams,
+                creationParamsCodec: const StandardMessageCodec(),
+                layoutDirection: TextDirection.ltr)
+              ..addOnPlatformViewCreatedListener(params.onPlatformViewCreated)
+              ..addOnPlatformViewCreatedListener(onPlatformViewCreated)
+              ..create();
+          },
+          viewType: viewType);
+    } else if (Platform.isIOS) {
+      return UiKitView(
+        viewType: viewType,
+        layoutDirection: TextDirection.ltr,
+        hitTestBehavior: PlatformViewHitTestBehavior.opaque,
+        creationParams: creationParams,
+        creationParamsCodec: const StandardMessageCodec(),
+        onPlatformViewCreated: (id) {
+          onPlatformViewCreated(id);
+        },
+      );
+    } else {
+      return const Center(child: Text('only support android and ios'));
+    }
+  }
+
+  Future<void> onPlatformViewCreated(int id) async {
+    // if (widget.onComPDFKitWidgetCreate != null) {
+    //   widget.onComPDFKitWidgetCreate!(CPDFViewCtrl(id));
+    // }
+  }
+}