|
@@ -0,0 +1,155 @@
|
|
|
|
+package com.kdanmobile.reader.adpage
|
|
|
|
+
|
|
|
|
+import android.content.Context
|
|
|
|
+import android.graphics.*
|
|
|
|
+import android.view.View
|
|
|
|
+import android.widget.RelativeLayout
|
|
|
|
+import com.kdanmobile.kmpdfkit.manager.KMPDFFactory
|
|
|
|
+import com.kdanmobile.kmpdfkit.pdfcommon.*
|
|
|
|
+import com.kdanmobile.reader.utils.DensityUtil
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * 客製化KMPDFPageView
|
|
|
|
+ *
|
|
|
|
+ * 用以處理廣告顯示
|
|
|
|
+ */
|
|
|
|
+class MyPageView(
|
|
|
|
+ context: Context,
|
|
|
|
+ filePickerSupport: FilePicker.FilePickerSupport,
|
|
|
|
+ kmpdfFactory: KMPDFFactory,
|
|
|
|
+ parentSize: Point,
|
|
|
|
+ // 此頁是否是廣告頁
|
|
|
|
+ private val isAdPage: Boolean
|
|
|
|
+) : KMPDFPageView(context, filePickerSupport, kmpdfFactory, parentSize) {
|
|
|
|
+
|
|
|
|
+ companion object {
|
|
|
|
+ // 預設廣告高度
|
|
|
|
+ const val DEFAULT_AD_HEIGHT = 450
|
|
|
|
+ // 預設廣告頁碼(建議為負值,避免錯誤書籤顯示)
|
|
|
|
+ const val AD_PAGE_NUMBER_ID = -99
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 廣告寬度(螢幕寬度)
|
|
|
|
+ val adWidth = DensityUtil.getScreenWidthPx(context)
|
|
|
|
+ // 廣告高度(執行期變化)
|
|
|
|
+ var adHeight = 0
|
|
|
|
+ // 不可見廣告的寬度
|
|
|
|
+ private val invisibleAdSize = PointF(adWidth.toFloat(), 1f)
|
|
|
|
+ // 不可見廣告的高度
|
|
|
|
+ private val invisibleAdRect = RectF(0f, 0f, invisibleAdSize.x, invisibleAdSize.y)
|
|
|
|
+ // 頁面的縮放值
|
|
|
|
+ private var viewScale = -1f
|
|
|
|
+
|
|
|
|
+ // 用來放置廣告的容器
|
|
|
|
+ val layout = RelativeLayout(context).also {
|
|
|
|
+ it.visibility = View.GONE
|
|
|
|
+ addView(it)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 廣告是否可見
|
|
|
|
+ var isAdShowing = false
|
|
|
|
+ set(value) {
|
|
|
|
+ if (!isAdPage) return
|
|
|
|
+ if (field != value) {
|
|
|
|
+ field = value
|
|
|
|
+ val visibility = when (field) {
|
|
|
|
+ true -> View.VISIBLE
|
|
|
|
+ false -> View.INVISIBLE
|
|
|
|
+ }
|
|
|
|
+ layout.visibility = visibility
|
|
|
|
+ this.visibility = visibility
|
|
|
|
+ initPageSize = false
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ // 是否曾初始化
|
|
|
|
+ private var initPageSize = false
|
|
|
|
+
|
|
|
|
+ init {
|
|
|
|
+ // 如果是廣告
|
|
|
|
+ if (isAdPage) {
|
|
|
|
+ // 設定頁碼
|
|
|
|
+ mPageNumber = AD_PAGE_NUMBER_ID
|
|
|
|
+ // 廣告大小為不可見
|
|
|
|
+ super.setPage(page, invisibleAdSize, invisibleAdRect)
|
|
|
|
+ // 隱藏所有內容
|
|
|
|
+ for (index in 0 until childCount) {
|
|
|
|
+ getChildAt(index).visibility = View.INVISIBLE
|
|
|
|
+ }
|
|
|
|
+ // 設定透明背景
|
|
|
|
+ setBackgroundColor(Color.TRANSPARENT)
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 處理長按事件(顯示Context Menu)
|
|
|
|
+ */
|
|
|
|
+ override fun openLongClickBlankContextMenu(view: View?) {
|
|
|
|
+ // 如果是廣告頁,則遮蔽長按事件
|
|
|
|
+ if (isAdPage) return
|
|
|
|
+ super.openLongClickBlankContextMenu(view)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
|
|
|
|
+ super.onLayout(changed, left, top, right, bottom)
|
|
|
|
+ // 如果不是廣告頁,則不執行以下指令
|
|
|
|
+ if (!isAdPage) return
|
|
|
|
+ // 在某些情況下,頁碼會被重置為0,因此需要重新設定(SDK bug?)
|
|
|
|
+ mPageNumber = AD_PAGE_NUMBER_ID
|
|
|
|
+
|
|
|
|
+ // 如果廣告可見
|
|
|
|
+ if (isAdShowing) {
|
|
|
|
+ // 廣告置中,大小固定為adWidth x adHeight
|
|
|
|
+ layout.layout(-x.toInt(), 0, (adWidth - x).toInt(), adHeight)
|
|
|
|
+ // 更新頁面高度
|
|
|
|
+ updateAdHeight()
|
|
|
|
+ // 更新內容大小
|
|
|
|
+ updateAdContentSize()
|
|
|
|
+ } else if (!initPageSize) {
|
|
|
|
+ super.setPage(page, invisibleAdSize, invisibleAdRect)
|
|
|
|
+ initPageSize = true
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 取得頁面縮放值
|
|
|
|
+ */
|
|
|
|
+ private fun getPageViewScale(): Float {
|
|
|
|
+ return width / mSize.x.toFloat()
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 更新頁面高度
|
|
|
|
+ */
|
|
|
|
+ private fun updateAdHeight() {
|
|
|
|
+ // 如果縮放未改變則不更新
|
|
|
|
+ val scale = getPageViewScale()
|
|
|
|
+ if (scale == viewScale) return
|
|
|
|
+ viewScale = scale
|
|
|
|
+ // 計算頁面大小
|
|
|
|
+ val modifyPageSize = PointF(adWidth.toFloat(), adHeight / viewScale)
|
|
|
|
+ val cropPageSize = RectF(0f, 0f, modifyPageSize.x, modifyPageSize.y)
|
|
|
|
+ // 設定頁面大小
|
|
|
|
+ setPage(page, modifyPageSize, cropPageSize)
|
|
|
|
+ // 隱藏廣告以外的所有內容
|
|
|
|
+ for (index in 0 until childCount) {
|
|
|
|
+ getChildAt(index).also {
|
|
|
|
+ if (it != layout) {
|
|
|
|
+ it.visibility = View.INVISIBLE
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 更新內容大小
|
|
|
|
+ */
|
|
|
|
+ private fun updateAdContentSize() {
|
|
|
|
+ for (i in 0 until layout.childCount) {
|
|
|
|
+ layout.getChildAt(i).apply {
|
|
|
|
+ if (left != 0 || top != 0 || right != adWidth || bottom != adHeight) {
|
|
|
|
+ layout(0, 0, adWidth, adHeight)
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|