Browse Source

Feature: thumbnails in left toolbar

cooperku_kdanmobile 5 years ago
parent
commit
2300da44e2

+ 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.ThumbnailView
 import com.kdanmobile.reader.utils.AnimationUtil
 import com.kdanmobile.reader.utils.DensityUtil
 import kotlinx.android.synthetic.main.activity_reader.*
@@ -253,8 +254,8 @@ open class ReaderActivity : AppCompatActivity() {
         if (isLeftToolbarOpen) {
             if (leftToolbarType != type) {
                 linearLayout_readerActivity_leftToolbarContainer.removeAllViews()
-                val child = layoutInflater.inflate(R.layout.view_km_thumb_layout, null)
-                linearLayout_readerActivity_leftToolbarContainer.addView(child)
+                val thumbnailView = ThumbnailView(this, viewModel)
+                linearLayout_readerActivity_leftToolbarContainer.addView(thumbnailView)
             }
             iv_readerActivity_thumbnail.setImageResource(R.drawable.ic_pagelist_thumbnail_h)
         } else {

+ 138 - 0
reader/src/main/java/com/kdanmobile/reader/screen/view/ThumbnailAdapter.kt

@@ -0,0 +1,138 @@
+package com.kdanmobile.reader.screen.view
+
+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.FrameLayout
+import android.widget.ImageView
+import android.widget.TextView
+import com.kdanmobile.reader.R
+import com.kdanmobile.reader.ReaderViewModel
+import com.kdanmobile.reader.screen.view.ThumbnailAdapter.ThumbnailViewHolder
+import com.kdanmobile.reader.utils.DensityUtil
+import io.reactivex.Observable
+import io.reactivex.android.schedulers.AndroidSchedulers
+import io.reactivex.disposables.Disposable
+import io.reactivex.schedulers.Schedulers
+
+class ThumbnailAdapter(private val handler: ThumbnailHandler, private val filename: String): RecyclerView.Adapter<ThumbnailViewHolder>() {
+
+    companion object {
+        lateinit var mMemoryCache: LruCache<String, Bitmap>
+        internal var maxMemory = Runtime.getRuntime().maxMemory() / 8
+    }
+    private var currentPage = 0
+
+    init {
+        this.currentPage = handler.getCurrentPage() ?: 0
+
+        mMemoryCache = object: LruCache<String, Bitmap>(maxMemory.toInt()) {
+            override fun sizeOf(key: String, value: Bitmap): Int {
+                return value.byteCount
+            }
+        }
+    }
+
+    fun setCurrentPage(currentPage: Int) {
+        val oldCurrentPage = this.currentPage
+        this.currentPage = currentPage
+        notifyItemChanged(oldCurrentPage, false)
+        notifyItemChanged(currentPage, true)
+    }
+
+    fun clearMapSoftNotify() {
+        mMemoryCache.evictAll()
+        notifyDataSetChanged()
+    }
+
+    override fun getItemCount(): Int {
+        return handler.getPdfPageCount() ?: 0
+    }
+
+    override fun onBindViewHolder(holder: ThumbnailViewHolder, position: Int) {
+        holder.page.text = (holder.adapterPosition + 1).toString()
+        holder.onShowBorder(currentPage == holder.adapterPosition)
+        holder.loadThumbSync(filename, handler)
+    }
+
+    override fun onBindViewHolder(holder: ThumbnailViewHolder, position: Int, payloads: List<Any>) {
+        if (payloads.isEmpty()) {
+            onBindViewHolder(holder, position)
+        } else {
+            for (obj in payloads) {
+                if (obj is Boolean) {
+                    holder.onShowBorder(obj)
+                }
+            }
+        }
+    }
+
+    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ThumbnailViewHolder {
+        val view = View.inflate(parent.context, R.layout.item_thumbnail, null)
+        return ThumbnailViewHolder(parent, view)
+    }
+
+    override fun onViewRecycled(holder: ThumbnailViewHolder) {
+        super.onViewRecycled(holder)
+        holder.stopLoadThumbSync()
+    }
+
+    inner class ThumbnailViewHolder(parent: ViewGroup, itemView: View): ViewHolder(itemView) {
+        private val thumb: ImageView
+        internal val page: TextView
+        private val border: View
+        private var disposable: Disposable? = null
+
+        init {
+            var idReaderThumbFl = itemView.findViewById<View>(R.id.id_reader_thumb_fl) as FrameLayout
+            val params = RecyclerView.LayoutParams(parent.measuredWidth - 20, (parent.measuredWidth - 20) * 9 / 7)
+            params.setMargins(10, 5, 10, 5)
+            idReaderThumbFl.layoutParams = params
+
+            thumb = itemView.findViewById<View>(R.id.iv_fragmentPdfReaderThumbLvItem_) as ImageView
+            page = itemView.findViewById<View>(R.id.tv_fragmentPdfReaderThumbLvItem_page) as TextView
+            border = itemView.findViewById(R.id.v_pdfThumbGvItem_)
+        }
+
+        internal fun onShowBorder(isShow: Boolean) {
+            border.visibility = if (isShow) View.VISIBLE else View.GONE
+        }
+
+        internal fun loadThumbSync(filename: String, handler: ThumbnailHandler) {
+            stopLoadThumbSync()
+
+            disposable = Observable.create<Bitmap> { emitter ->
+                val pageNameTag = filename + adapterPosition
+                var bitmap: Bitmap
+                if (null != mMemoryCache[pageNameTag]) {
+                    bitmap = mMemoryCache[pageNameTag]!!
+                } else {
+                    bitmap = handler.getPdfBitmap(adapterPosition, 180, ThumbnailHandler.MODE_DAY, true) !!
+                    mMemoryCache.put(pageNameTag, bitmap)
+                }
+                emitter.onNext(bitmap)
+                emitter.onComplete()
+            }
+                    .subscribeOn(Schedulers.computation())
+                    .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()
+            }
+        }
+    }
+}

+ 69 - 0
reader/src/main/java/com/kdanmobile/reader/screen/view/ThumbnailView.kt

@@ -0,0 +1,69 @@
+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.reader.R
+import com.kdanmobile.reader.ReaderViewModel
+import com.kdanmobile.reader.widget.drag.OnRecyclerItemClickListener
+import kotlinx.android.synthetic.main.view_km_thumb_layout.view.*
+
+class ThumbnailView: RelativeLayout {
+    companion object {
+        private var currentPage = 0
+    }
+    private lateinit var handler: ThumbnailHandler
+    private lateinit var adapter: ThumbnailAdapter
+
+    constructor(context: Context, viewModel: ReaderViewModel) : super(context) {
+        initView(viewModel)
+    }
+
+    constructor(context: Context, attributeSet: AttributeSet, viewModel: ReaderViewModel) : super(context, attributeSet) {
+        initView(viewModel)
+    }
+
+    constructor(context: Context, attributeSet: AttributeSet, defStyleAttr: Int, viewModel: ReaderViewModel) : super(context, attributeSet, defStyleAttr) {
+        initView(viewModel)
+    }
+
+    private fun initView(handler: ThumbnailHandler) {
+        this.handler = handler
+        LayoutInflater.from(context).inflate(R.layout.view_km_thumb_layout, this)
+        val layoutManager = LinearLayoutManager(context)
+        layoutManager.orientation = LinearLayoutManager.VERTICAL
+
+        id_km_thumb_recycler.setHasFixedSize(true)
+        id_km_thumb_recycler.layoutManager = layoutManager
+        id_km_thumb_recycler.layoutManager = LinearLayoutManager(context)
+        id_km_thumb_recycler.addOnItemTouchListener(object : OnRecyclerItemClickListener(id_km_thumb_recycler) {
+            override fun onItemClick(viewHolder: RecyclerView.ViewHolder) {
+                onScrollToPosition(viewHolder.adapterPosition, true)
+                handler.setCurrentPage(viewHolder.adapterPosition)
+            }
+
+            override fun onItemLongClick(viewHolder: RecyclerView.ViewHolder) {
+
+            }
+        })
+
+        adapter = ThumbnailAdapter(handler, "FILENAME")
+        id_km_thumb_recycler.adapter = adapter
+        onScrollToPosition(currentPage, true)
+    }
+
+    private fun onScrollToPosition(position: Int, notify: Boolean) {
+        currentPage = position
+
+        if (null != adapter && notify) {
+            adapter.setCurrentPage(position)
+        }
+
+        if (null != id_km_thumb_recycler) {
+            id_km_thumb_recycler.scrollToPosition(position)
+        }
+    }
+}