瀏覽代碼

Apply custom KMPDFPageAdapter, KMPDFPageView & KMPDFReaderView

cooperku_kdanmobile 5 年之前
父節點
當前提交
5dd8abd02c

+ 30 - 3
src/main/java/com/kdanmobile/reader/ReaderActivity.kt

@@ -3,6 +3,7 @@ package com.kdanmobile.reader
 import android.annotation.SuppressLint
 import android.app.Activity
 import android.app.Dialog
+import android.content.Context
 import androidx.lifecycle.Observer
 import android.content.Intent
 import android.net.Uri
@@ -18,9 +19,11 @@ import android.view.*
 import android.view.animation.AnimationUtils
 import android.widget.*
 import com.kdanmobile.base.KdanBaseActivity
-import com.kdanmobile.kmpdfkit.pdfcommon.KMPDFReaderView
 import com.kdanmobile.kmpdfkit.pdfcommon.PDFInfo
+import com.kdanmobile.kmpdfkit.manager.KMPDFFactory
+import com.kdanmobile.kmpdfkit.pdfcommon.*
 import com.kdanmobile.reader.Utils.applyConstraintSet
+import com.kdanmobile.reader.adpage.AbstractPageAdapter
 import com.kdanmobile.reader.annotationattribute.AnnotationAttribute
 import com.kdanmobile.reader.annotationattribute.AnnotationColor
 import com.kdanmobile.reader.annotationattribute.InkAttribute
@@ -37,6 +40,8 @@ import com.kdanmobile.reader.screen.view.*
 import com.kdanmobile.reader.screen.view.SearchView
 import com.kdanmobile.reader.setting.ReaderSettingDialogFragment
 import com.kdanmobile.reader.setting.ReaderSettingListener
+import com.kdanmobile.reader.adpage.MyReaderView
+import com.kdanmobile.reader.adpage.AdPageHelper
 import com.kdanmobile.reader.thumb.PdfThumbDialogFragment
 import com.kdanmobile.reader.thumb.PdfThumbFragmentListener
 import com.kdanmobile.reader.utils.AnimationUtil
@@ -77,6 +82,8 @@ abstract class ReaderActivity :
     open fun loadCurrentPageIndex(filename: String, defaultValue: Int): Int = 0
     open fun onOpenedFile() { /* do nothing */ }
     open fun onFilePathOrUriError(filePath: String?) { println("onFilePathOrUriError: $filePath") }
+    //  子類別可複寫此方法以客製化KMPDFPageAdapter
+    abstract fun providePdfPageAdapter(context: Context, filePickerSupport: FilePicker.FilePickerSupport, kmpdfFactory: KMPDFFactory): KMPDFPageAdapter
     protected open fun onEvent(hookEvent: HookEvent) { /* do nothing */ }
 
     companion object {
@@ -115,6 +122,10 @@ abstract class ReaderActivity :
         get() {
             return viewModel.readerModel
         }
+    protected val adPageHelper: AdPageHelper
+        get() {
+            return viewModel.adPageHelper
+        }
 
     private val viewModel: ReaderViewModel by viewModel {
         val filePath = intent.getStringExtra(KEY_FILE_ABSOLUTE)
@@ -449,13 +460,13 @@ abstract class ReaderActivity :
         container.removeAllViews()
         if (!isOpened) return
         val context = this
-        val readerView = object : KMPDFReaderView(context) {
+        //  採用客製化的KMPDFReaderView以覆寫畫面點擊判斷和當前頁面計算方法
+        val readerView = object : MyReaderView(context, adPageHelper) {
             @SuppressLint("ClickableViewAccessibility")
             override fun onTouchEvent(motionEvent: MotionEvent): Boolean {
                 if (motionEvent.action == MotionEvent.ACTION_UP) {
                     if (viewModel.isCopyModeLiveData.value == true) {
                         if (viewModel.copySelection()) {
-                            val context = this@ReaderActivity
                             Toast.makeText(context, R.string.reader_copy_text_success, Toast.LENGTH_SHORT).show()
                         }
                     }
@@ -465,6 +476,8 @@ abstract class ReaderActivity :
 
             override fun onMoveToChild(pageIndex: Int) {
                 viewModel.setPageIndex(pageIndex)
+                //  畫面更新時應通知adPageHelper
+                adPageHelper.onPageChanged(pageIndex)
             }
 
             override fun onScrolling() {
@@ -493,6 +506,20 @@ abstract class ReaderActivity :
             }
         }
         viewModel.setReaderView(readerView)
+
+        /**
+         * 使用客製化KMPDFPageAdapter取代內建的Adapter
+         * 注意,需要在KMPDFFactory::setReaderView之後調用才不會被複寫
+         */
+        viewModel.getReaderView()?.apply {
+            adapter = providePdfPageAdapter(
+                    context,
+                    FilePicker.FilePickerSupport {},
+                    viewModel.readerModel.kmpdfFactory!!
+            )
+            refresh(true)
+        }
+
         if (!filePath.isNullOrEmpty()) {
             val defaultValue = viewModel.pageIndexLiveData.value ?: 0
             val pageIndex = loadCurrentPageIndex(filePath as String, defaultValue)

+ 15 - 3
src/main/java/com/kdanmobile/reader/ReaderModel.kt

@@ -11,6 +11,7 @@ import com.kdanmobile.kmpdfkit.pdfcommon.OutlineItem
 import com.kdanmobile.kmpdfkit.pdfcommon.TextChar
 import com.kdanmobile.kmpdfkit.pdfcommon.TextWord
 import com.kdanmobile.reader.screen.handler.*
+import com.kdanmobile.reader.adpage.AdPageHelper
 
 class ReaderModel {
     private var filename: String? = null
@@ -18,6 +19,8 @@ class ReaderModel {
     var password: String = ""
         private set
 
+    var adPageHelper: AdPageHelper? = null
+
     var kmpdfFactory: KMPDFFactory? = null
         private set
 
@@ -43,9 +46,16 @@ class ReaderModel {
         this.isInitialized = true
     }
 
+    fun initPdfAdPageHelper(adPageHelper: AdPageHelper?) {
+        this.adPageHelper = adPageHelper
+    }
+
     fun initKMPDFDocumentController() {
         kmpdfDocumentController = kmpdfFactory?.getController(KMPDFFactory.ControllerType.DOCUMENT) as KMPDFDocumentController
         kmpdfSignatureController = kmpdfFactory?.getController(KMPDFFactory.ControllerType.SIGNATURE) as KMPDFSignatureController
+        kmpdfDocumentController?.also {
+            adPageHelper?.kmpdfDocumentController = it
+        }
     }
 
     @Synchronized
@@ -58,6 +68,7 @@ class ReaderModel {
         kmpdfDocumentController = null
         kmpdfSignatureController = null
         onPdfChangedListener = null
+        adPageHelper = null
     }
 
     val pdfInfoHandler = object : PdfInfoHandler {
@@ -66,7 +77,7 @@ class ReaderModel {
         }
 
         override fun getPdfPageCount(isNativeRefresh: Boolean): Int {
-            return kmpdfDocumentController?.getDocumentPageCount(isNativeRefresh) ?: 0
+            return adPageHelper?.getRawPageCount(isNativeRefresh) ?: 0
         }
 
         override fun getCurrentPage(): Int {
@@ -114,7 +125,7 @@ class ReaderModel {
         }
 
         override fun setSearchResult(page: Int, keyword: String, rectArray: Array<RectF>): Boolean {
-            return kmpdfDocumentController?.setSearchResult(keyword, page, rectArray) ?: false
+            return kmpdfDocumentController?.setSearchResult(keyword, adPageHelper?.convertToPageIndex(page) ?: 0, rectArray) ?: false
         }
 
         override fun stopSearchKeyWord(): Boolean {
@@ -130,12 +141,13 @@ class ReaderModel {
         override fun deletePages(pages: IntArray): Boolean {
             return kmpdfDocumentController?.deletePages(pages) ?: false
         }
+
         override fun save(): Boolean {
             return kmpdfDocumentController?.save() ?: false
         }
 
         override fun reorderPage(fromPage: Int, toPage: Int): Boolean {
-            return kmpdfDocumentController?.reorderPages(fromPage,toPage) ?: false
+            return kmpdfDocumentController?.reorderPages(fromPage, toPage) ?: false
         }
 
         override fun splitPDFWithPages(path: String, selectPage: IntArray): Boolean {

+ 24 - 6
src/main/java/com/kdanmobile/reader/ReaderViewModel.kt

@@ -33,6 +33,7 @@ import com.kdanmobile.reader.screen.data.SignatureAttribute
 import com.kdanmobile.reader.screen.data.StampAttribute
 import com.kdanmobile.reader.screen.data.TextBoxAttribute
 import com.kdanmobile.reader.screen.handler.*
+import com.kdanmobile.reader.adpage.AdPageHelper
 import java.io.File
 import java.util.*
 import kotlin.collections.ArrayList
@@ -206,6 +207,10 @@ class ReaderViewModel(
 
     private var onClickLinkListener: OnClickLinkListener? = null
 
+    var adPageHelper = AdPageHelper().also {
+        readerModel.initPdfAdPageHelper(it)
+    }
+
     @JvmOverloads
     fun openPdfFile(context: Context, password: String, onRequestPassword: Runnable, type: String? = null): OpenFileResult {
         if (!isVerified) {
@@ -456,7 +461,6 @@ class ReaderViewModel(
             }
 
             override fun onAttachAnnotWidgetFinished(type: Annotation.Type) {
-                println("KMPDFAddAnnotCallback::onAttachAnnotWidgetFinished")
                 val mode = when (type) {
                     Annotation.Type.FREETEXT -> KMPDFAnnotEditMode.Mode.FREETEXT_MODIFY
                     Annotation.Type.STAMP -> KMPDFAnnotEditMode.Mode.STAMP_MODIFY
@@ -537,10 +541,14 @@ class ReaderViewModel(
         restoreStateBeforeDestroy()
     }
 
+    /**
+     * 之前採用以下方式會遮蔽廣告頁拖曳,原因尚不清楚...
+     * kmpdfFactory?.setAnnotationEditMode(KMPDFAnnotationBean.AnnotationType.NULL)
+     * kmpdfFactory?.kmpdfAnnotEditMode?.pdfAnnotEditMode = KMPDFAnnotEditMode.Mode.NULL
+     * annotationEitModeLiveData.postValue(AnnotationEitMode.NULL)
+     */
     fun clearSelection() {
-        kmpdfFactory?.setAnnotationEditMode(KMPDFAnnotationBean.AnnotationType.NULL)
-        kmpdfFactory?.kmpdfAnnotEditMode?.pdfAnnotEditMode = KMPDFAnnotEditMode.Mode.NULL
-        annotationEitModeLiveData.postValue(AnnotationEitMode.NULL)
+        kmpdfDocumentController?.deselectCurrentPageAnnotation()
     }
 
     fun deleteSelectedTextBox() {
@@ -559,8 +567,9 @@ class ReaderViewModel(
         (kmpdfFactory?.getController(KMPDFFactory.ControllerType.FREETEXT) as KMPDFFreeTextController).copyFreeTextContent()
     }
 
-    fun setPageIndex(pageIndex: Int){
-        mPageIndexLiveData.value = pageIndex
+    fun setPageIndex(pageIndex: Int) {
+        //  設定為原始文件頁數
+        mPageIndexLiveData.value = adPageHelper.convertToRawPageIndex(pageIndex)
     }
 
     fun addBookmark(title: String) {
@@ -608,9 +617,18 @@ class ReaderViewModel(
         return errorCode == 0
     }
 
+    /**
+     * 目前在水平閱覽模式時會移除頁間廣告,導致兩者總頁數不一致
+     * 更動總頁數需要重新設定當前頁面
+     */
     private fun updateViewDirection() {
+        val pageCount = adPageHelper.getPageCount(false)
+        val pageIndex = pdfInfoHandler.getCurrentPage()
         kmpdfDocumentController?.pdfViewMode = viewDirection.mode
         kmpdfDocumentController?.refresh(false)
+        if (pageCount != adPageHelper.getPageCount(false)) {
+            pdfInfoHandler.goToCurrentPage(pageIndex)
+        }
     }
 
     private fun updateReadMode() {