Procházet zdrojové kódy

Feature: PDF bookmark in left toolbar

cooperku_kdanmobile před 5 roky
rodič
revize
c2bad3e514

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

@@ -15,6 +15,7 @@ import android.view.MotionEvent
 import android.view.View
 import com.kdanmobile.kmpdfkit.pdfcommon.KMPDFReaderView
 import com.kdanmobile.reader.Utils.applyConstraintSet
+import com.kdanmobile.reader.screen.view.BookmarkView
 import com.kdanmobile.reader.screen.view.OutlineView
 import com.kdanmobile.reader.screen.view.SearchView
 import com.kdanmobile.reader.screen.view.ThumbnailView
@@ -283,8 +284,8 @@ open class ReaderActivity : AppCompatActivity() {
         if (isLeftToolbarOpen) {
             if (leftToolbarType != type) {
                 linearLayout_readerActivity_leftToolbarContainer.removeAllViews()
-                val child = layoutInflater.inflate(R.layout.view_thumbnail, null)
-                linearLayout_readerActivity_leftToolbarContainer.addView(child)
+                val bookmarkView = BookmarkView(this, viewModel)
+                linearLayout_readerActivity_leftToolbarContainer.addView(bookmarkView)
             }
             iv_readerActivity_bookmark.setImageResource(R.drawable.ic_pagelist_bookmk_h)
         } else {

+ 11 - 5
reader/src/main/java/com/kdanmobile/reader/ReaderViewModel.kt

@@ -10,15 +10,13 @@ import com.kdanmobile.kmpdfkit.annotation.bean.*
 import com.kdanmobile.kmpdfkit.globaldata.Config
 import com.kdanmobile.kmpdfkit.manager.KMPDFFactory
 import com.kdanmobile.kmpdfkit.manager.controller.KMPDFDocumentController
+import com.kdanmobile.kmpdfkit.pdfcommon.Bookmark
 import com.kdanmobile.kmpdfkit.pdfcommon.KMPDFReaderView
 import com.kdanmobile.kmpdfkit.pdfcommon.OutlineItem
 import com.kdanmobile.kmpdfkit.pdfcommon.TextWord
-import com.kdanmobile.reader.screen.handler.OutlineHandler
-import com.kdanmobile.reader.screen.handler.PdfInfoHandler
-import com.kdanmobile.reader.screen.handler.SearchHandler
-import com.kdanmobile.reader.screen.handler.ThumbnailHandler
+import com.kdanmobile.reader.screen.handler.*
 
-class ReaderViewModel(private val pdfSdkLicense: String, private val pdfSdkRsaMsg: String) : ViewModel(), PdfInfoHandler, ThumbnailHandler, OutlineHandler, SearchHandler {
+class ReaderViewModel(private val pdfSdkLicense: String, private val pdfSdkRsaMsg: String) : ViewModel(), PdfInfoHandler, ThumbnailHandler, BookmarkHandler, OutlineHandler, SearchHandler {
     enum class ViewDirection(val mode: Config.PDFViewMode) {
         VerticalSinglePageContinues(Config.PDFViewMode.VERTICAL_SINGLE_PAGE_CONTINUES),
         VerticalSinglePage(Config.PDFViewMode.VERTICAL_SINGLE_PAGE),
@@ -201,6 +199,14 @@ class ReaderViewModel(private val pdfSdkLicense: String, private val pdfSdkRsaMs
         return kmpdfDocumentController?.covertPDFToBitmap(position, picWidth, mode, isDrawAnnot)
     }
 
+    //  ====================================================================
+    //  implement BookmarkHandler
+    //  ====================================================================
+
+    override fun getBookmarks(): Array<Bookmark>? {
+        return kmpdfDocumentController?.bookmarks
+    }
+
     //  ====================================================================
     //  implement OutlineHandler
     //  ====================================================================

+ 117 - 0
reader/src/main/java/com/kdanmobile/reader/screen/adapter/BookmarkAdapter.kt

@@ -0,0 +1,117 @@
+package com.kdanmobile.reader.screen.adapter
+
+import android.graphics.Bitmap
+import android.support.v4.util.LruCache
+import android.support.v7.widget.RecyclerView
+import android.support.v7.widget.RecyclerView.ViewHolder
+import android.view.View
+import android.view.ViewGroup
+import android.widget.ImageView
+import android.widget.LinearLayout
+import android.widget.RelativeLayout
+import android.widget.TextView
+import com.kdanmobile.kmpdfkit.pdfcommon.Bookmark
+import com.kdanmobile.reader.R
+import com.kdanmobile.reader.screen.handler.ThumbnailHandler
+import io.reactivex.Observable
+import io.reactivex.android.schedulers.AndroidSchedulers
+import io.reactivex.disposables.Disposable
+import io.reactivex.schedulers.Schedulers
+
+class BookmarkAdapter(private val thumbnailHandler: ThumbnailHandler, private var bookmarkItems: Array<Bookmark>?): RecyclerView.Adapter<BookmarkAdapter.BookmarkViewHolder>() {
+
+    companion object {
+        lateinit var mMemoryCache: LruCache<String, Bitmap>
+        internal var maxMemory = Runtime.getRuntime().maxMemory() / 8
+    }
+
+    init {
+        mMemoryCache = object: LruCache<String, Bitmap>(maxMemory.toInt()) {
+            override fun sizeOf(key: String, value: Bitmap): Int {
+                return value.byteCount
+            }
+        }
+    }
+
+    fun setOutlineItems(outlineItems: Array<Bookmark>?) {
+        this.bookmarkItems = outlineItems
+        notifyDataSetChanged()
+    }
+
+    override fun getItemCount(): Int {
+        return bookmarkItems?.size ?: 0
+    }
+
+    fun getItem(position: Int): Bookmark? {
+        return bookmarkItems?.get(position)
+    }
+
+    override fun onBindViewHolder(holder: BookmarkViewHolder, position: Int) {
+        val bookmark = bookmarkItems!![holder.adapterPosition]
+        holder.msg.text = bookmark.title
+        holder.page.text = (bookmark.pageNum + 1).toString()
+        holder.loadThumbSync(bookmark.title + bookmark.pageNum + bookmark.createTime, bookmark.pageNum)
+    }
+
+    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BookmarkViewHolder {
+        val view = View.inflate(parent.context, R.layout.item_bookmark, null)
+        return BookmarkViewHolder(parent, view)
+    }
+
+    override fun onViewRecycled(holder: BookmarkViewHolder) {
+        super.onViewRecycled(holder)
+        holder.stopLoadThumbSync()
+    }
+
+    inner class BookmarkViewHolder(parent: ViewGroup, itemView: View): ViewHolder(itemView) {
+        private val thumb: ImageView
+        internal val page: TextView
+        internal val msg: TextView
+        private var disposable: Disposable? = null
+
+        init {
+            var idReaderBookmarkFl = itemView.findViewById<View>(R.id.tv_fragmentPdfReaderBookmarkLvItem_rl) as RelativeLayout
+            val params = LinearLayout.LayoutParams((parent.measuredWidth - 20) / 2, (parent.measuredWidth - 20) * 9 / 14)
+            params.setMargins(10, 5, 10, 5)
+            idReaderBookmarkFl.layoutParams = params
+
+            thumb = itemView.findViewById<View>(R.id.iv_fragmentPdfReaderBookmarkLvItem_) as ImageView
+            page = itemView.findViewById<View>(R.id.tv_fragmentPdfReaderBookmarkLvItem_page) as TextView
+            msg = itemView.findViewById<View>(R.id.tv_fragmentPdfReaderBookmarkLvItem_name) as TextView
+        }
+
+        internal fun loadThumbSync(filename: String, page: Int) {
+            stopLoadThumbSync()
+
+            disposable = Observable.create<Bitmap> { emitter ->
+                val pageNameTag = filename + page
+                var bitmap: Bitmap
+                if (null != mMemoryCache[pageNameTag]) {
+                    bitmap = mMemoryCache[pageNameTag]!!
+                } else {
+                    bitmap = thumbnailHandler.getPdfBitmap(page, 180, ThumbnailHandler.MODE_DAY, true) !!
+                    mMemoryCache.put(pageNameTag, bitmap)
+                }
+                emitter.onNext(bitmap)
+                emitter.onComplete()
+            }
+                    .subscribeOn(Schedulers.io())
+                    .observeOn(AndroidSchedulers.mainThread())
+                    .subscribe({
+                        thumb.setImageBitmap(it)
+                        thumb.invalidate()
+                    }, {
+                        it.printStackTrace()
+                    })
+        }
+
+        internal fun stopLoadThumbSync() {
+            if (null != disposable && !disposable!!.isDisposed) {
+                disposable?.dispose()
+                disposable = null
+                thumb.setImageBitmap(null)
+                thumb.invalidate()
+            }
+        }
+    }
+}

+ 8 - 0
reader/src/main/java/com/kdanmobile/reader/screen/handler/BookmarkHandler.kt

@@ -0,0 +1,8 @@
+package com.kdanmobile.reader.screen.handler
+
+import com.kdanmobile.kmpdfkit.pdfcommon.Bookmark
+
+interface BookmarkHandler {
+
+    fun getBookmarks(): Array<Bookmark>?
+}

+ 78 - 0
reader/src/main/java/com/kdanmobile/reader/screen/view/BookmarkView.kt

@@ -0,0 +1,78 @@
+package com.kdanmobile.reader.screen.view
+
+import android.content.Context
+import android.support.v7.widget.LinearLayoutManager
+import android.support.v7.widget.RecyclerView
+import android.util.AttributeSet
+import android.view.LayoutInflater
+import android.widget.RelativeLayout
+import com.kdanmobile.kmpdfkit.pdfcommon.Bookmark
+import com.kdanmobile.reader.R
+import com.kdanmobile.reader.ReaderViewModel
+import com.kdanmobile.reader.screen.adapter.BookmarkAdapter
+import com.kdanmobile.reader.screen.handler.BookmarkHandler
+import com.kdanmobile.reader.screen.handler.PdfInfoHandler
+import com.kdanmobile.reader.screen.handler.ThumbnailHandler
+import com.kdanmobile.reader.widget.drag.OnRecyclerItemClickListener
+import kotlinx.android.synthetic.main.view_bookmark.view.*
+import java.util.*
+
+class BookmarkView: RelativeLayout {
+    private lateinit var adapter: BookmarkAdapter
+    private lateinit var handler: ThumbnailHandler
+    private var bookmarkItems: Array<Bookmark>? = null
+
+    constructor(context: Context, viewModel: ReaderViewModel) : super(context) {
+        initView(viewModel, viewModel, viewModel)
+    }
+
+    constructor(context: Context, attributeSet: AttributeSet, viewModel: ReaderViewModel) : super(context, attributeSet) {
+        initView(viewModel, viewModel, viewModel)
+    }
+
+    constructor(context: Context, attributeSet: AttributeSet, defStyleAttr: Int, viewModel: ReaderViewModel) : super(context, attributeSet, defStyleAttr) {
+        initView(viewModel, viewModel, viewModel)
+    }
+
+    private fun initView(pdfInfoHandler: PdfInfoHandler, thumbnailHandler: ThumbnailHandler, bookmarkHandler: BookmarkHandler) {
+        LayoutInflater.from(context).inflate(R.layout.view_bookmark, this)
+        val layoutManager = LinearLayoutManager(context)
+        layoutManager.orientation = LinearLayoutManager.VERTICAL
+
+        this.handler = thumbnailHandler
+
+        id_km_bookmark_recycler.setHasFixedSize(true)
+        id_km_bookmark_recycler.layoutManager = layoutManager
+        id_km_bookmark_recycler.layoutManager = LinearLayoutManager(context)
+        id_km_bookmark_recycler.addOnItemTouchListener(object : OnRecyclerItemClickListener(id_km_bookmark_recycler) {
+            override fun onItemClick(viewHolder: RecyclerView.ViewHolder) {
+                val bookmark = adapter.getItem(viewHolder.adapterPosition)
+                if (null != bookmark) {
+                    pdfInfoHandler.setCurrentPage(bookmark.pageNum)
+                }
+            }
+
+            override fun onItemLongClick(viewHolder: RecyclerView.ViewHolder) {
+
+            }
+        })
+
+        adapter = BookmarkAdapter(handler, bookmarkItems)
+        id_km_bookmark_recycler.adapter = adapter
+        onRefreshBookmarkDatas(bookmarkHandler.getBookmarks()!!)
+    }
+
+
+    private fun onRefreshBookmarkDatas(items: Array<Bookmark>) {
+        try {
+            this.bookmarkItems = items
+            if (bookmarkItems?.isNotEmpty() != null) {
+                Arrays.sort(bookmarkItems) { lhs, rhs -> if (lhs.pageNum > rhs.pageNum) 1 else -1 }
+            }
+            adapter.setOutlineItems(bookmarkItems)
+        } catch (e: Exception) {
+            e.printStackTrace()
+        }
+
+    }
+}