Ver Fonte

Merge branch 'mediaBoxLayout'

cooperku_kdanmobile há 5 anos atrás
pai
commit
aa8c7f9577

+ 1 - 1
reader/build.gradle

@@ -46,5 +46,5 @@ dependencies {
 
     testImplementation 'junit:junit:4.12'
 
-    api(name: 'kmpdfkit-1.0.8.1', ext: 'aar')
+    api(name: 'kmpdfkit-1.0.8.1 2019-01-11', ext: 'aar')
 }

BIN
reader/libs/kmpdfkit-1.0.8.1.aar


+ 40 - 29
reader/src/main/java/com/kdanmobile/reader/ReaderActivity.kt

@@ -21,6 +21,7 @@ import android.widget.EditText
 import android.widget.LinearLayout
 import android.widget.TextView
 import android.widget.Toast
+import com.kdanmobile.kmpdfkit.globaldata.KMPDFAnnotEditMode
 import com.kdanmobile.kmpdfkit.pdfcommon.KMPDFReaderView
 import com.kdanmobile.reader.Utils.applyConstraintSet
 import com.kdanmobile.reader.annotationattribute.AnnotationAttribute
@@ -99,6 +100,7 @@ abstract class ReaderActivity : AppCompatActivity() {
         viewModel.isOpenedFileLiveData.observe(this, Observer(this::onIsOpenedFileUpdate))
         viewModel.fileNameLiveData.observe(this, Observer { tv_readerActivity_title.text = it })
         viewModel.annotationModeLiveData.observe(this, Observer(this::onAnnotationModeUpdate))
+        viewModel.annotationEitModeLiveData.observe(this, Observer(this::onAnnotationEditModeUpdate))
         viewModel.isCopyModeLiveData.observe(this, Observer (this::onIsCopyModeUpdate))
         viewModel.highLightAttributeLiveData.observe(this, Observer(this::onHighlightAttributeUpdate))
         viewModel.strikeAttributeLiveData.observe(this, Observer(this::onStrikeAttributeUpdate))
@@ -239,6 +241,15 @@ abstract class ReaderActivity : AppCompatActivity() {
         }
     }
 
+    private fun onAnnotationEditModeUpdate(mode: KMPDFAnnotEditMode.Mode?) {
+        println("onAnnotationEditModeUpdate KMPDFAnnotEditMode.Mode.$mode")
+        when (mode) {
+            KMPDFAnnotEditMode.Mode.NULL -> showAllToolbars()
+            KMPDFAnnotEditMode.Mode.FREETEXT_MODIFY, KMPDFAnnotEditMode.Mode.STAMP_MODIFY, KMPDFAnnotEditMode.Mode.SIGN_MODIFY, KMPDFAnnotEditMode.Mode.SHAPE_MODIFY -> hideAllToolbars()
+            else -> {}
+        }
+    }
+
     private fun onIsOpenedFileUpdate(isOpened: Boolean?) {
         if (isOpened == null) return
         val container = viewGroup_readerActivity_container
@@ -261,12 +272,6 @@ abstract class ReaderActivity : AppCompatActivity() {
 
             override fun onTapMainDocArea() {
                 super.onTapMainDocArea()
-                if (isBelowKitkat()) {
-                    isHideToolbar = toolbar_readerActivity.visibility != View.VISIBLE
-                            || viewGroup_readerActivity_bottomToolbar.visibility != View.VISIBLE
-                            || viewGroup_readerActivity_leftToolbar.visibility != View.VISIBLE
-                            || viewGroup_readerActivity_rightToolbar.visibility != View.VISIBLE
-                }
                 when (isHideToolbar) {
                     true -> showAllToolbars()
                     false -> hideAllToolbars()
@@ -281,23 +286,26 @@ abstract class ReaderActivity : AppCompatActivity() {
             }
 
             override fun onScroll(e1: MotionEvent?, e2: MotionEvent?, distanceX: Float, distanceY: Float): Boolean {
-                if (isBelowKitkat()) {
-                    isHideToolbar = toolbar_readerActivity.visibility != View.VISIBLE
-                            || viewGroup_readerActivity_bottomToolbar.visibility != View.VISIBLE
-                            || viewGroup_readerActivity_leftToolbar.visibility != View.VISIBLE
-                            || viewGroup_readerActivity_rightToolbar.visibility != View.VISIBLE
-                }
-                if (!isHideToolbar) {
+                val isEditMode = viewModel.annotationModeLiveData.value != ReaderViewModel.AnnotationMode.None
+                val isCopyMode = viewModel.isCopyModeLiveData.value != false
+
+                if (!isEditMode && !isCopyMode && !isHideToolbar) {
                     hideAllToolbars()
-                    isHideToolbar = false
+                    isHideToolbar = true
                 }
                 return super.onScroll(e1, e2, distanceX, distanceY)
             }
         }
         viewModel.setReaderView(readerView)
+        viewModel.pdfInfoHandler.setCurrentPage(viewModel.pageIndexLiveData.value ?: 0)
         container.addView(readerView)
     }
 
+    override fun onDestroy() {
+        viewModel.saveModifyingAnnotationBeforeDestroy()
+        super.onDestroy()
+    }
+
     private fun onPageIndexChanged(pageIndex: Int?) {
         pageIndex?.let {
             viewModel.setBookmarkDisplay(pageIndex)
@@ -321,10 +329,11 @@ abstract class ReaderActivity : AppCompatActivity() {
 
     private fun showAllToolbars() {
         if (isBelowKitkat()) {
-            AnimationUtil.showViewFromTopToBottom(toolbar_readerActivity, UI_ANIMATION_DURATION)
-            AnimationUtil.showViewFromBottomToTop(viewGroup_readerActivity_bottomToolbar, UI_ANIMATION_DURATION)
-            AnimationUtil.showViewFromLeftToRight(viewGroup_readerActivity_leftToolbar, UI_ANIMATION_DURATION)
-            AnimationUtil.showViewFromRightToLeft(viewGroup_readerActivity_rightToolbar, UI_ANIMATION_DURATION)
+            val duration = ((1 - toolbar_readerActivity.alpha) * UI_ANIMATION_DURATION).toLong()
+            AnimationUtil.showViewFromTopToBottom(toolbar_readerActivity, duration)
+            AnimationUtil.showViewFromBottomToTop(viewGroup_readerActivity_bottomToolbar, duration)
+            AnimationUtil.showViewFromLeftToRight(viewGroup_readerActivity_leftToolbar, duration)
+            AnimationUtil.showViewFromRightToLeft(viewGroup_readerActivity_rightToolbar, duration)
         } else {
             constrainLayout_readerActivity_root.applyConstraintSet(originConstraintSet, UI_ANIMATION_DURATION)
         }
@@ -332,10 +341,11 @@ abstract class ReaderActivity : AppCompatActivity() {
 
     private fun hideAllToolbars() {
         if (isBelowKitkat()) {
-            AnimationUtil.hideViewFromBottomToTop(toolbar_readerActivity, UI_ANIMATION_DURATION)
-            AnimationUtil.hideViewFromTopToBottom(viewGroup_readerActivity_bottomToolbar, UI_ANIMATION_DURATION)
-            AnimationUtil.hideViewFromRightToLeft(viewGroup_readerActivity_leftToolbar, UI_ANIMATION_DURATION)
-            AnimationUtil.hideViewFromLeftToRight(viewGroup_readerActivity_rightToolbar, UI_ANIMATION_DURATION)
+            val duration = (toolbar_readerActivity.alpha * UI_ANIMATION_DURATION).toLong()
+            AnimationUtil.hideViewFromBottomToTop(toolbar_readerActivity, duration)
+            AnimationUtil.hideViewFromTopToBottom(viewGroup_readerActivity_bottomToolbar, duration)
+            AnimationUtil.hideViewFromRightToLeft(viewGroup_readerActivity_leftToolbar, duration)
+            AnimationUtil.hideViewFromLeftToRight(viewGroup_readerActivity_rightToolbar, duration)
             hideSearchViewSoftKeyboard()
         } else {
             constrainLayout_readerActivity_root.applyConstraintSet(this, R.layout.activity_reader_hide_all, UI_ANIMATION_DURATION)
@@ -344,9 +354,10 @@ abstract class ReaderActivity : AppCompatActivity() {
 
     private fun hideTopLeftBottomToolbars() {
         if (isBelowKitkat()) {
-            AnimationUtil.hideViewFromBottomToTop(toolbar_readerActivity, UI_ANIMATION_DURATION)
-            AnimationUtil.hideViewFromTopToBottom(viewGroup_readerActivity_bottomToolbar, UI_ANIMATION_DURATION)
-            AnimationUtil.hideViewFromRightToLeft(viewGroup_readerActivity_leftToolbar, UI_ANIMATION_DURATION)
+            val duration = (toolbar_readerActivity.alpha * UI_ANIMATION_DURATION).toLong()
+            AnimationUtil.hideViewFromBottomToTop(toolbar_readerActivity, duration)
+            AnimationUtil.hideViewFromTopToBottom(viewGroup_readerActivity_bottomToolbar, duration)
+            AnimationUtil.hideViewFromRightToLeft(viewGroup_readerActivity_leftToolbar, duration)
             hideSearchViewSoftKeyboard()
         } else {
             constrainLayout_readerActivity_root.applyConstraintSet(this, R.layout.activity_reader_hide_top_left_bottom, UI_ANIMATION_DURATION)
@@ -472,22 +483,22 @@ abstract class ReaderActivity : AppCompatActivity() {
             onDismissListener = Runnable { onMediaBoxDismissed() }
             onClickAddButtonListener = object : MediaBoxView.OnClickAddButtonListener {
                 override fun onClickTextBoxAddButton(textBoxTabView: TextBoxTabView) {
-                    hideAllToolbars()
+                    dismiss(false)
                     viewModel.setTextBoxAttribute(textBoxTabView.getTextBoxAttribute())
                 }
 
                 override fun onClickSignatureAddButton(signatureTabView: SignatureTabView) {
-                    hideAllToolbars()
+                    dismiss(false)
                     viewModel.setSignatureAttribute(signatureTabView.getSignatureAttribute())
                 }
 
                 override fun onClickStampAddButton(stampTabView: StampTabView) {
-                    hideAllToolbars()
+                    dismiss(false)
                     viewModel.setStampAttribute(stampTabView.getStampAttribute())
                 }
 
                 override fun onClickShapeAddButton(shapeTabView: ShapeTabView) {
-                    hideAllToolbars()
+                    dismiss(false)
                     viewModel.setShapeAttribute(shapeTabView.getShapeAttribute())
                 }
             }

+ 33 - 2
reader/src/main/java/com/kdanmobile/reader/ReaderViewModel.kt

@@ -22,7 +22,7 @@ import com.kdanmobile.kmpdfkit.pdfcommon.*
 import com.kdanmobile.reader.annotationattribute.Brush
 import com.kdanmobile.kmpdfkit.manager.controller.*
 import com.kdanmobile.kmpdfkit.manager.listener.KMPDFAddAnnotCallback
-import com.kdanmobile.kmpdfkit.pdfcommon.*
+import com.kdanmobile.kmpdfkit.manager.listener.KMPDFAnnotEditModeChangeListener
 import com.kdanmobile.reader.screen.data.ShapeAttribute
 import com.kdanmobile.reader.screen.data.SignatureAttribute
 import com.kdanmobile.reader.screen.data.StampAttribute
@@ -74,6 +74,7 @@ class ReaderViewModel(private val pdfSdkLicense: String, private val pdfSdkRsaMs
     val isOpenedFileLiveData = MutableLiveData<Boolean>().apply { value = false }
     val fileNameLiveData = MutableLiveData<String>()
     val annotationModeLiveData = MutableLiveData<AnnotationMode>().apply { value = AnnotationMode.None }
+    val annotationEitModeLiveData = MutableLiveData<KMPDFAnnotEditMode.Mode>().apply { value = KMPDFAnnotEditMode.Mode.NULL }
     var isCopyModeLiveData = MutableLiveData<Boolean>().apply { value = false }
 
     val pageIndexLiveData: LiveData<Int>
@@ -260,6 +261,7 @@ class ReaderViewModel(private val pdfSdkLicense: String, private val pdfSdkRsaMs
     }
 
     fun setReaderView(readerView: KMPDFReaderView) {
+        val isFirst = kmpdfFactory?.readerView == null
         kmpdfFactory?.readerView = readerView
         kmpdfDocumentController = kmpdfFactory?.getController(KMPDFFactory.ControllerType.DOCUMENT) as KMPDFDocumentController
         updateViewDirection()
@@ -283,6 +285,35 @@ class ReaderViewModel(private val pdfSdkLicense: String, private val pdfSdkRsaMs
                 }
             }
         }
+
+        kmpdfFactory?.kmpdfAnnotEditModeChangeListener = KMPDFAnnotEditModeChangeListener {
+            annotationEitModeLiveData.postValue(it)
+        }
+
+        if (!isFirst) {
+            restoreStateBeforeDestroy()
+        }
+    }
+
+    private fun restoreStateBeforeDestroy() {
+        if (isCopyModeLiveData.value == true) {
+            startCopyTextMode()
+        } else {
+            val annotationEditMode = when (annotationModeLiveData.value) {
+                AnnotationMode.None, null -> KMPDFAnnotationBean.AnnotationType.NULL
+                AnnotationMode.Highlight -> KMPDFAnnotationBean.AnnotationType.HIGH_LIGHT
+                AnnotationMode.Strike -> KMPDFAnnotationBean.AnnotationType.STRIKE_OUT
+                AnnotationMode.Underline -> KMPDFAnnotationBean.AnnotationType.UNDER_LINE
+                AnnotationMode.Ink -> KMPDFAnnotationBean.AnnotationType.INK
+            }
+            kmpdfFactory?.setAnnotationEditMode(annotationEditMode)
+            kmpdfFactory?.kmpdfAnnotEditMode?.pdfAnnotEditMode = KMPDFAnnotEditMode.Mode.NULL
+            annotationEitModeLiveData.postValue(KMPDFAnnotEditMode.Mode.NULL)
+        }
+    }
+
+    fun saveModifyingAnnotationBeforeDestroy() {
+        kmpdfFactory?.setAnnotationEditMode(KMPDFAnnotationBean.AnnotationType.NULL)
     }
 
     fun setPageIndex(pageIndex: Int){
@@ -422,7 +453,7 @@ class ReaderViewModel(private val pdfSdkLicense: String, private val pdfSdkRsaMs
             return kmpdfDocumentController?.cleanPreviousSearchResults(keyword) ?: false
         }
 
-        override fun cleanPreviousSearchResults(page: Int, keyword: String, rectArray: Array<RectF>): Boolean {
+        override fun setSearchResult(page: Int, keyword: String, rectArray: Array<RectF>): Boolean {
             return kmpdfDocumentController?.setSearchResult(keyword, page, rectArray) ?: false
         }
 

+ 1 - 1
reader/src/main/java/com/kdanmobile/reader/screen/handler/SearchHandler.kt

@@ -8,7 +8,7 @@ interface SearchHandler {
 
     fun cleanPreviousSearchResults(keyword: String): Boolean
 
-    fun cleanPreviousSearchResults(page: Int, keyword: String, rectArray: Array<RectF>): Boolean
+    fun setSearchResult(page: Int, keyword: String, rectArray: Array<RectF>): Boolean
 
     fun stopSearchKeyWord(): Boolean
 }

+ 7 - 7
reader/src/main/java/com/kdanmobile/reader/screen/model/SearchResultInfo.kt

@@ -3,7 +3,7 @@ package com.kdanmobile.reader.screen.model
 import android.graphics.RectF
 import com.kdanmobile.kmpdfkit.pdfcommon.TextWord
 
-class SearchResultInfo(var page: Int, var search: String, var rf: RectF, lines: Array<TextWord>) {
+class SearchResultInfo(var page: Int, var keyword: String, var rect: RectF, lines: Array<TextWord>) {
     var result: String = ""
 
     init {
@@ -13,17 +13,17 @@ class SearchResultInfo(var page: Int, var search: String, var rf: RectF, lines:
 
         val sb = StringBuilder()
         var src = result.toLowerCase()
-        val seh = search.toLowerCase()
-        var index = src.indexOf(seh)
+        val key = keyword.toLowerCase()
+        var index = src.indexOf(key)
         while (index >= 0) {
             sb.append(src.subSequence(0, index))
             sb.append("<font color=\"#ff0000\">")
             result = result.substring(index)
-            sb.append(result.substring(0, search.length))
+            sb.append(result.substring(0, keyword.length))
             sb.append("</font>")
-            result = result.substring(search.length)
-            src = src.substring(index + search.length)
-            index = src.indexOf(seh)
+            result = result.substring(keyword.length)
+            src = src.substring(index + keyword.length)
+            index = src.indexOf(key)
         }
 
         sb.append(result)

+ 0 - 17
reader/src/main/java/com/kdanmobile/reader/screen/model/SearchTaskResult.kt

@@ -1,17 +0,0 @@
-package com.kdanmobile.reader.screen.model
-
-import android.graphics.RectF
-
-class SearchTaskResult(val txt: String, val pageNumber: Int, val searchBoxes: Array<RectF>) {
-    companion object {
-        private var singleton: SearchTaskResult? = null
-
-        fun get(): SearchTaskResult? {
-            return singleton
-        }
-
-        fun set(result: SearchTaskResult) {
-            singleton = result
-        }
-    }
-}

+ 5 - 3
reader/src/main/java/com/kdanmobile/reader/screen/reader/mediabox/MediaBoxView.kt

@@ -63,7 +63,7 @@ class MediaBoxView @JvmOverloads constructor(
 
     fun show() {
         visibility = View.VISIBLE
-        setOnClickListener { dismiss() }
+        setOnClickListener { dismiss(true) }
         post {
             showMaskWithAnimation()
             showMediaBoxWithAnimation()
@@ -71,11 +71,13 @@ class MediaBoxView @JvmOverloads constructor(
         onShowListener?.run()
     }
 
-    fun dismiss() {
+    fun dismiss(fromUser: Boolean = true) {
         setOnClickListener(null)
         hideMaskWithAnimation()
         hideMediaBoxWithAnimation()
-        onDismissListener?.run()
+        if (fromUser) {
+            onDismissListener?.run()
+        }
     }
 
     private fun showMaskWithAnimation() {

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

@@ -17,7 +17,7 @@ import kotlinx.android.synthetic.main.view_bookmark.view.*
 import java.util.*
 
 class BookmarkView: RelativeLayout {
-    private lateinit var adapter: BookmarkAdapter
+    private var adapter: BookmarkAdapter? = null
     private var pdfInfoHandler: PdfInfoHandler? = null
     private var bookmarkHandler: BookmarkHandler? = null
 
@@ -43,7 +43,7 @@ class BookmarkView: RelativeLayout {
         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)
+                val bookmark = adapter?.getItem(viewHolder.adapterPosition)
                 if (null != bookmark) {
                     pdfInfoHandler?.setCurrentPage(bookmark.pageNum)
                 }
@@ -74,7 +74,7 @@ class BookmarkView: RelativeLayout {
             if (bookmarkItems.isNotEmpty()) {
                 Arrays.sort(bookmarkItems) { lhs, rhs -> if (lhs.pageNum > rhs.pageNum) 1 else -1 }
             }
-            adapter.setOutlineItems(bookmarkItems)
+            adapter?.setOutlineItems(bookmarkItems)
         } catch (e: Exception) {
             e.printStackTrace()
         }

+ 2 - 2
reader/src/main/java/com/kdanmobile/reader/screen/view/OutlineView.kt

@@ -15,7 +15,7 @@ import io.reactivex.schedulers.Schedulers
 import kotlinx.android.synthetic.main.view_outline.view.*
 
 class OutlineView: RelativeLayout {
-    private lateinit var adapter: OutlineAdapter
+    private var adapter: OutlineAdapter? = null
     private var pdfInfoHandler: PdfInfoHandler? = null
     private var disposable: Disposable? = null
 
@@ -35,7 +35,7 @@ class OutlineView: RelativeLayout {
         LayoutInflater.from(context).inflate(R.layout.view_outline, this)
 
         lv_viewPdfReaderOutline_.setOnItemClickListener { _, _, position, _ ->
-            val item = adapter.getItem(position)
+            val item = adapter?.getItem(position)
             if (null != item) {
                 pdfInfoHandler?.setCurrentPage(item.page)
             }

+ 1 - 2
reader/src/main/java/com/kdanmobile/reader/screen/view/SearchView.kt

@@ -18,7 +18,6 @@ import com.kdanmobile.reader.screen.adapter.SearchAdapter
 import com.kdanmobile.reader.screen.model.SearchResultInfo
 import com.kdanmobile.reader.screen.handler.PdfInfoHandler
 import com.kdanmobile.reader.screen.handler.SearchHandler
-import com.kdanmobile.reader.screen.model.SearchTaskResult
 import com.kdanmobile.reader.screen.model.SimpleTextWatcher
 import com.kdanmobile.reader.utils.DensityUtil
 import io.reactivex.Completable
@@ -105,7 +104,7 @@ class SearchView: RelativeLayout, View.OnClickListener {
                         30 -> {
                             val position = msg.arg1
                             val info = view.list[position]
-                            SearchTaskResult.set(SearchTaskResult(info.search, info.page, arrayOf(info.rf)))
+                            view.searchHandler?.setSearchResult(info.page, info.keyword, arrayOf(info.rect))
                             view.pdfInfoHandler?.setCurrentPage(view.list[position].page)
                         }
                     }

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

@@ -14,7 +14,7 @@ import com.kdanmobile.reader.widget.drag.OnRecyclerItemClickListener
 import kotlinx.android.synthetic.main.view_thumbnail.view.*
 
 class ThumbnailView: RelativeLayout {
-    private lateinit var adapter: ThumbnailAdapter
+    private var adapter: ThumbnailAdapter? = null
     private var currentPage = 0
     private var pdfInfoHandler: PdfInfoHandler? = null
 
@@ -55,7 +55,7 @@ class ThumbnailView: RelativeLayout {
 
         adapter = ThumbnailAdapter(pdfInfoHandler, thumbnailHandler)
         id_km_thumb_recycler.adapter = adapter
-        currentPage = pdfInfoHandler?.getCurrentPage()
+        currentPage = pdfInfoHandler.getCurrentPage()
         onScrollToPosition(currentPage, true)
     }
 
@@ -63,7 +63,7 @@ class ThumbnailView: RelativeLayout {
         currentPage = position
 
         if (notify) {
-            adapter.setCurrentPage(position)
+            adapter?.setCurrentPage(position)
         }
 
         if (null != id_km_thumb_recycler) {

+ 217 - 116
reader/src/main/java/com/kdanmobile/reader/utils/AnimationUtil.kt

@@ -72,88 +72,141 @@ class AnimationUtil private constructor() {
         }
 
         /**
-         * 隐藏buttons控件,从控件顶部往底部回收隐藏
+         * 显示buttons控件,从控件底部往控件顶部扩展显示
          *
          * @param view
          */
-        fun hideViewFromTopToBottom(view: View?, duration: Long = 300) {
-            if (showBottomToTop != null && showBottomToTop!!.isRunning())
-                return;
+        fun showViewFromBottomToTop(view: View?, duration: Long = 300) {
+            if (showBottomToTop != null && showBottomToTop!!.isRunning) {
+                if (showBottomToTop?.target == view) {
+                    showBottomToTop?.cancel()
+                    showBottomToTop = null
+                } else {
+                    return
+                }
+            }
 
-            if (view != null && view.visibility == View.VISIBLE) {
-                val pvhA = PropertyValuesHolder.ofFloat("alpha", 1.0f, 0f)
-                val pvhY = PropertyValuesHolder.ofFloat("Y", view.top.toFloat(), view.top.toFloat() + view.height)
+            if (view != null) {
+                val pvhA = PropertyValuesHolder.ofFloat("alpha", view.alpha, 1.0f)
+                val pvhY = PropertyValuesHolder.ofFloat("Y", Math.max(view.y, view.top.toFloat() + view.height), view.top.toFloat())
                 showBottomToTop = ObjectAnimator.ofPropertyValuesHolder(view, pvhA, pvhY)
-                showBottomToTop!!.interpolator = AccelerateInterpolator()
-                showBottomToTop!!.addListener(object : AnimatorListenerAdapter() {
-                    override fun onAnimationEnd(animation: Animator) {
-                        super.onAnimationEnd(animation)
-                        Handler(Looper.getMainLooper()).post { view.visibility = View.INVISIBLE }
-                    }
-                })
-                showBottomToTop!!.setDuration(duration).start()
+                showBottomToTop?.apply {
+                    interpolator = AccelerateInterpolator()
+                    addListener(object : AnimatorListenerAdapter() {
+                        override fun onAnimationStart(animation: Animator) {
+                            super.onAnimationStart(animation)
+                            view.visibility = View.VISIBLE
+                        }
+
+                        override fun onAnimationCancel(animation: Animator?) {
+                            super.onAnimationCancel(animation)
+                            animation?.removeAllListeners()
+                        }
+                    })
+                    setDuration(duration).start()
+                }
             }
         }
 
         /**
-         * 显示buttons控件,从控件底部往控件顶部扩展显示
+         * 隐藏buttons控件,从控件顶部往底部回收隐藏
          *
          * @param view
          */
-        fun showViewFromBottomToTop(view: View?, duration: Long = 300) {
-            if (showBottomToTop != null && showBottomToTop!!.isRunning())
-                return;
+        fun hideViewFromTopToBottom(view: View?, duration: Long = 300) {
+            if (showBottomToTop != null && showBottomToTop!!.isRunning) {
+                if (showBottomToTop?.target == view) {
+                    showBottomToTop?.cancel()
+                    showBottomToTop = null
+                } else {
+                    return
+                }
+            }
 
-            if (view != null && view.visibility != View.VISIBLE) {
-                val pvhA = PropertyValuesHolder.ofFloat("alpha", 0f, 1.0f)
-                val pvhY = PropertyValuesHolder.ofFloat("Y", view.top.toFloat() + view.height, view.top.toFloat())
+            if (view != null) {
+                val pvhA = PropertyValuesHolder.ofFloat("alpha", view.alpha, 0f)
+                val pvhY = PropertyValuesHolder.ofFloat("Y", Math.min(view.y, view.top.toFloat()), view.top.toFloat() + view.height)
                 showBottomToTop = ObjectAnimator.ofPropertyValuesHolder(view, pvhA, pvhY)
-                showBottomToTop!!.interpolator = AccelerateInterpolator()
-                showBottomToTop!!.addListener(object : AnimatorListenerAdapter() {
-                    override fun onAnimationStart(animation: Animator) {
-                        super.onAnimationStart(animation)
-                        view.visibility = View.VISIBLE
-                    }
-                })
-                showBottomToTop!!.setDuration(duration).start()
+                showBottomToTop = ObjectAnimator.ofPropertyValuesHolder(view, pvhA, pvhY)
+                showBottomToTop?.apply {
+                    interpolator = AccelerateInterpolator()
+                    addListener(object : AnimatorListenerAdapter() {
+                        override fun onAnimationEnd(animation: Animator) {
+                            super.onAnimationEnd(animation)
+                            view.visibility = View.INVISIBLE
+                        }
+
+                        override fun onAnimationCancel(animation: Animator?) {
+                            super.onAnimationCancel(animation)
+                            animation?.removeAllListeners()
+                        }
+                    })
+                    setDuration(duration).start()
+                }
             }
         }
 
         fun showViewFromRightToLeft(view: View?, duration: Long = 300) {
-            if (showRightToLeft != null && showRightToLeft!!.isRunning)
-                return
+            if (showRightToLeft != null && showRightToLeft!!.isRunning) {
+                if (showRightToLeft?.target == view) {
+                    showRightToLeft?.cancel()
+                    showRightToLeft = null
+                } else {
+                    return
+                }
+            }
 
-            if (view != null && view.visibility != View.VISIBLE) {
-                val pvhA = PropertyValuesHolder.ofFloat("alpha", 0f, 1.0f)
-                val pvhX = PropertyValuesHolder.ofFloat("X", view.left.toFloat() + view.width, view.left.toFloat())
+            if (view != null) {
+                val pvhA = PropertyValuesHolder.ofFloat("alpha", view.alpha, 1.0f)
+                val pvhX = PropertyValuesHolder.ofFloat("X", Math.min(view.x, view.left.toFloat() + view.width), view.left.toFloat())
                 showRightToLeft = ObjectAnimator.ofPropertyValuesHolder(view, pvhA, pvhX)
-                showRightToLeft!!.interpolator = AccelerateInterpolator()
-                showRightToLeft!!.addListener(object : AnimatorListenerAdapter() {
-                    override fun onAnimationStart(animation: Animator) {
-                        super.onAnimationStart(animation)
-                        view.visibility = View.VISIBLE
-                    }
-                })
-                showRightToLeft!!.setDuration(duration).start()
+                showRightToLeft?.apply {
+                    interpolator = AccelerateInterpolator()
+                    addListener(object : AnimatorListenerAdapter() {
+                        override fun onAnimationStart(animation: Animator) {
+                            super.onAnimationStart(animation)
+                            view.visibility = View.VISIBLE
+                        }
+
+                        override fun onAnimationCancel(animation: Animator?) {
+                            super.onAnimationCancel(animation)
+                            animation?.removeAllListeners()
+                        }
+                    })
+                    setDuration(duration).start()
+                }
             }
         }
 
         fun hideViewFromLeftToRight(view: View?, duration: Long = 300) {
-            if (showRightToLeft != null && showRightToLeft!!.isRunning)
-                return
+            if (showRightToLeft != null && showRightToLeft!!.isRunning) {
+                if (showRightToLeft?.target == view) {
+                    showRightToLeft?.cancel()
+                    showRightToLeft = null
+                } else {
+                    return
+                }
+            }
 
-            if (view != null && view.visibility == View.VISIBLE) {
-                val pvhA = PropertyValuesHolder.ofFloat("alpha", 1.0f, 0f)
-                val pvhX = PropertyValuesHolder.ofFloat("X", view.left.toFloat(), view.left.toFloat() + view.width)
+            if (view != null) {
+                val pvhA = PropertyValuesHolder.ofFloat("alpha", view.alpha, 0f)
+                val pvhX = PropertyValuesHolder.ofFloat("X", Math.max(view.x, view.left.toFloat()), view.left.toFloat() + view.width)
                 showRightToLeft = ObjectAnimator.ofPropertyValuesHolder(view, pvhA, pvhX)
-                showRightToLeft!!.interpolator = AccelerateInterpolator()
-                showRightToLeft!!.addListener(object : AnimatorListenerAdapter() {
-                    override fun onAnimationEnd(animation: Animator) {
-                        super.onAnimationEnd(animation)
-                        Handler(Looper.getMainLooper()).post { view.visibility = View.INVISIBLE }
-                    }
-                })
-                showRightToLeft!!.setDuration(duration).start()
+                showRightToLeft?.apply {
+                    interpolator = AccelerateInterpolator()
+                    addListener(object : AnimatorListenerAdapter() {
+                        override fun onAnimationEnd(animation: Animator) {
+                            super.onAnimationEnd(animation)
+                            view.visibility = View.INVISIBLE
+                        }
+
+                        override fun onAnimationCancel(animation: Animator?) {
+                            super.onAnimationCancel(animation)
+                            animation?.removeAllListeners()
+                        }
+                    })
+                    setDuration(duration).start()
+                }
             }
         }
 
@@ -163,21 +216,34 @@ class AnimationUtil private constructor() {
          * @param view
          */
         fun showViewFromTopToBottom(view: View?, duration: Long = 300) {
-            if (showTopToBottom != null && showTopToBottom!!.isRunning)
-                return
+            if (showTopToBottom != null && showTopToBottom!!.isRunning) {
+                if (showTopToBottom?.target == view) {
+                    showTopToBottom?.cancel()
+                    showTopToBottom = null
+                } else {
+                    return
+                }
+            }
 
-            if (view != null && view.visibility != View.VISIBLE) {
-                val pvhA = PropertyValuesHolder.ofFloat("alpha", 0f, 1.0f)
-                val pvhY = PropertyValuesHolder.ofFloat("Y", view.top.toFloat() - view.height, view.top.toFloat())
+            if (view != null) {
+                val pvhA = PropertyValuesHolder.ofFloat("alpha", view.alpha, 1.0f)
+                val pvhY = PropertyValuesHolder.ofFloat("Y", Math.min(view.y, view.top.toFloat() + view.height), view.top.toFloat())
                 showTopToBottom = ObjectAnimator.ofPropertyValuesHolder(view, pvhA, pvhY)
-                showTopToBottom!!.interpolator = AccelerateInterpolator()
-                showTopToBottom!!.addListener(object : AnimatorListenerAdapter() {
-                    override fun onAnimationStart(animation: Animator) {
-                        super.onAnimationStart(animation)
-                        view.visibility = View.VISIBLE
-                    }
-                })
-                showTopToBottom!!.setDuration(duration).start()
+                showTopToBottom?.apply {
+                    interpolator = AccelerateInterpolator()
+                    addListener(object : AnimatorListenerAdapter() {
+                        override fun onAnimationStart(animation: Animator) {
+                            super.onAnimationStart(animation)
+                            view.visibility = View.VISIBLE
+                        }
+
+                        override fun onAnimationCancel(animation: Animator?) {
+                            super.onAnimationCancel(animation)
+                            animation?.removeAllListeners()
+                        }
+                    })
+                    setDuration(duration).start()
+                }
             }
         }
 
@@ -187,59 +253,98 @@ class AnimationUtil private constructor() {
          * @param view
          */
         fun hideViewFromBottomToTop(view: View?, duration: Long = 300) {
-            if (showTopToBottom != null && showTopToBottom!!.isRunning)
-                return
+            if (showTopToBottom != null && showTopToBottom!!.isRunning) {
+                if (showTopToBottom?.target == view) {
+                    showTopToBottom?.cancel()
+                    showTopToBottom = null
+                } else {
+                    return
+                }
+            }
 
-            if (view != null && view.visibility == View.VISIBLE) {
-                val pvhA = PropertyValuesHolder.ofFloat("alpha", 1.0f, 0f)
-                val pvhY = PropertyValuesHolder.ofFloat("Y", view.top.toFloat(), view.top.toFloat() - view.height)
+            if (view != null) {
+                val pvhA = PropertyValuesHolder.ofFloat("alpha", view.alpha, 0f)
+                val pvhY = PropertyValuesHolder.ofFloat("Y", Math.max(view.y, view.top.toFloat()), view.top.toFloat() - view.height)
                 showTopToBottom = ObjectAnimator.ofPropertyValuesHolder(view, pvhA, pvhY)
-                showTopToBottom!!.interpolator = AccelerateInterpolator()
-                showTopToBottom!!.addListener(object : AnimatorListenerAdapter() {
-                    override fun onAnimationEnd(animation: Animator) {
-                        super.onAnimationEnd(animation)
-                        Handler(Looper.getMainLooper()).post { view.visibility = View.INVISIBLE }
-                    }
-                })
-                showTopToBottom!!.setDuration(duration).start()
+                showTopToBottom?.apply {
+                    interpolator = AccelerateInterpolator()
+                    addListener(object : AnimatorListenerAdapter() {
+                        override fun onAnimationEnd(animation: Animator) {
+                            super.onAnimationEnd(animation)
+                            view.visibility = View.INVISIBLE
+                        }
+
+                        override fun onAnimationCancel(animation: Animator?) {
+                            super.onAnimationCancel(animation)
+                            animation?.removeAllListeners()
+                        }
+                    })
+                    setDuration(duration).start()
+                }
             }
         }
 
         fun showViewFromLeftToRight(view: View?, duration: Long = 300) {
-            if (showLeftToRight != null && showLeftToRight!!.isRunning)
-                return
+            if (showLeftToRight != null && showLeftToRight!!.isRunning) {
+                if (showLeftToRight?.target == view) {
+                    showLeftToRight?.cancel()
+                    showLeftToRight = null
+                } else {
+                    return
+                }
+            }
 
-            if (view != null && view.visibility != View.VISIBLE) {
-                val pvhA = PropertyValuesHolder.ofFloat("alpha", 0f, 1.0f)
-                val pvhX = PropertyValuesHolder.ofFloat("X", view.left.toFloat() - view.width, view.left.toFloat())
+            if (view != null) {
+                val pvhA = PropertyValuesHolder.ofFloat("alpha", view.alpha, 1.0f)
+                val pvhX = PropertyValuesHolder.ofFloat("X", Math.max(view.x, view.left.toFloat() - view.width), view.left.toFloat())
                 showLeftToRight = ObjectAnimator.ofPropertyValuesHolder(view, pvhA, pvhX)
-                showLeftToRight!!.interpolator = AccelerateInterpolator()
-                showLeftToRight!!.addListener(object : AnimatorListenerAdapter() {
-                    override fun onAnimationStart(animation: Animator) {
-                        super.onAnimationStart(animation)
-                        view.visibility = View.VISIBLE
-                    }
-                })
-                showLeftToRight!!.setDuration(duration).start()
+                showLeftToRight?.apply {
+                    interpolator = AccelerateInterpolator()
+                    addListener(object : AnimatorListenerAdapter() {
+                        override fun onAnimationStart(animation: Animator) {
+                            super.onAnimationStart(animation)
+                            view.visibility = View.VISIBLE
+                        }
+
+                        override fun onAnimationCancel(animation: Animator?) {
+                            super.onAnimationCancel(animation)
+                            animation?.removeAllListeners()
+                        }
+                    })
+                    setDuration(duration).start()
+                }
             }
         }
 
         fun hideViewFromRightToLeft(view: View?, duration: Long = 300) {
-            if (showLeftToRight != null && showLeftToRight!!.isRunning)
-                return
+            if (showLeftToRight != null && showLeftToRight!!.isRunning) {
+                if (showLeftToRight?.target == view) {
+                    showLeftToRight?.cancel()
+                    showLeftToRight = null
+                } else {
+                    return
+                }
+            }
 
-            if (view != null && view.visibility == View.VISIBLE) {
-                val pvhA = PropertyValuesHolder.ofFloat("alpha", 1.0f, 0f)
-                val pvhX = PropertyValuesHolder.ofFloat("X", view.left.toFloat(), view.left.toFloat() - view.width)
+            if (view != null) {
+                val pvhA = PropertyValuesHolder.ofFloat("alpha", view.alpha, 0f)
+                val pvhX = PropertyValuesHolder.ofFloat("X", Math.min(view.x, view.left.toFloat()), view.left.toFloat() - view.width)
                 showLeftToRight = ObjectAnimator.ofPropertyValuesHolder(view, pvhA, pvhX)
-                showLeftToRight!!.interpolator = AccelerateInterpolator()
-                showLeftToRight!!.addListener(object : AnimatorListenerAdapter() {
-                    override fun onAnimationEnd(animation: Animator) {
-                        super.onAnimationEnd(animation)
-                        Handler(Looper.getMainLooper()).post { view.visibility = View.INVISIBLE }
-                    }
-                })
-                showLeftToRight!!.setDuration(duration).start()
+                showLeftToRight?.apply {
+                    interpolator = AccelerateInterpolator()
+                    addListener(object : AnimatorListenerAdapter() {
+                        override fun onAnimationEnd(animation: Animator) {
+                            super.onAnimationEnd(animation)
+                            view.visibility = View.INVISIBLE
+                        }
+
+                        override fun onAnimationCancel(animation: Animator?) {
+                            super.onAnimationCancel(animation)
+                            animation?.removeAllListeners()
+                        }
+                    })
+                    setDuration(duration).start()
+                }
             }
         }
 
@@ -277,14 +382,10 @@ class AnimationUtil private constructor() {
          * 结束该动画
          */
         fun cancelAnimations() {
-            if (showTopToBottom != null)
-                showTopToBottom!!.cancel()
-            if (showBottomToTop != null)
-                showBottomToTop!!.cancel()
-            if (showLeftToRight != null)
-                showLeftToRight!!.cancel()
-            if (showRightToLeft != null)
-                showRightToLeft!!.cancel()
+            showTopToBottom?.cancel()
+            showBottomToTop?.cancel()
+            showLeftToRight?.cancel()
+            showRightToLeft?.cancel()
             showTopToBottom = null
             showBottomToTop = null
             showRightToLeft = null

+ 6 - 5
reader/src/main/res/layout/activity_reader.xml

@@ -100,15 +100,16 @@
     </com.kdanmobile.reader.view.HorizontalView>
     <com.kdanmobile.reader.view.HorizontalView
         android:id="@+id/viewGroup_readerActivity_rightToolbar"
-        app:layout_constraintTop_toTopOf="parent"
-        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/toolbar_readerActivity"
+        app:layout_constraintBottom_toTopOf="@+id/viewGroup_readerActivity_bottomToolbar"
         app:layout_constraintRight_toRightOf="parent"
-        android:background="@drawable/bg_reader_tool_bar_right"
         android:layout_width="wrap_content"
-        android:layout_height="wrap_content">
+        android:layout_height="0dp">
         <ScrollView
             android:layout_width="wrap_content"
-            android:layout_height="wrap_content">
+            android:layout_height="wrap_content"
+            android:layout_gravity="center"
+            android:background="@drawable/bg_reader_tool_bar_right">
             <android.support.constraint.ConstraintLayout
                 android:orientation="vertical"
                 android:layout_width="wrap_content"

+ 1 - 1
reader/src/main/res/layout/activity_view_signature_create.xml

@@ -76,7 +76,7 @@
 
     <com.kdanmobile.reader.screen.view.ColorSelectView
         android:id="@+id/colorChooser_signature"
-        android:layout_width="wrap_content"
+        android:layout_width="0dp"
         android:layout_height="48dp"
         android:layout_marginLeft="16dp"
         android:layout_marginStart="16dp"

+ 17 - 22
reader/src/main/res/layout/view_color_select.xml

@@ -9,67 +9,62 @@
         android:id="@+id/colorSelect_column1"
         android:layout_width="24dp"
         android:layout_height="24dp"
-        app:color="#d0021b" />
+        app:color="#d0021b"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintRight_toLeftOf="@id/colorSelect_column2" />
 
     <com.kdanmobile.reader.screen.view.ColorOvalView
         android:id="@+id/colorSelect_column2"
         android:layout_width="24dp"
         android:layout_height="24dp"
-        android:layout_marginLeft="12dp"
-        android:layout_marginStart="12dp"
         app:color="#f5a623"
-        app:layout_constraintLeft_toRightOf="@id/colorSelect_column1" />
+        app:layout_constraintLeft_toRightOf="@id/colorSelect_column1"
+        app:layout_constraintRight_toLeftOf="@id/colorSelect_column3" />
 
     <com.kdanmobile.reader.screen.view.ColorOvalView
         android:id="@+id/colorSelect_column3"
         android:layout_width="24dp"
         android:layout_height="24dp"
-        android:layout_marginLeft="12dp"
-        android:layout_marginStart="12dp"
         app:color="#f8e71c"
-        app:layout_constraintLeft_toRightOf="@id/colorSelect_column2" />
+        app:layout_constraintLeft_toRightOf="@id/colorSelect_column2"
+        app:layout_constraintRight_toLeftOf="@id/colorSelect_column4" />
 
     <com.kdanmobile.reader.screen.view.ColorOvalView
         android:id="@+id/colorSelect_column4"
         android:layout_width="24dp"
         android:layout_height="24dp"
-        android:layout_marginLeft="12dp"
-        android:layout_marginStart="12dp"
         app:color="#8b572a"
-        app:layout_constraintLeft_toRightOf="@id/colorSelect_column3" />
+        app:layout_constraintLeft_toRightOf="@id/colorSelect_column3"
+        app:layout_constraintRight_toLeftOf="@id/colorSelect_column5" />
 
     <com.kdanmobile.reader.screen.view.ColorOvalView
         android:id="@+id/colorSelect_column5"
         android:layout_width="24dp"
         android:layout_height="24dp"
-        android:layout_marginLeft="12dp"
-        android:layout_marginStart="12dp"
         app:color="#7ed321"
-        app:layout_constraintLeft_toRightOf="@id/colorSelect_column4" />
+        app:layout_constraintLeft_toRightOf="@id/colorSelect_column4"
+        app:layout_constraintRight_toLeftOf="@id/colorSelect_column6" />
 
     <com.kdanmobile.reader.screen.view.ColorOvalView
         android:id="@+id/colorSelect_column6"
         android:layout_width="24dp"
         android:layout_height="24dp"
-        android:layout_marginLeft="12dp"
-        android:layout_marginStart="12dp"
         app:color="#417505"
-        app:layout_constraintLeft_toRightOf="@id/colorSelect_column5" />
+        app:layout_constraintLeft_toRightOf="@id/colorSelect_column5"
+        app:layout_constraintRight_toLeftOf="@id/colorSelect_column7" />
 
     <com.kdanmobile.reader.screen.view.ColorOvalView
         android:id="@+id/colorSelect_column7"
         android:layout_width="24dp"
         android:layout_height="24dp"
-        android:layout_marginLeft="12dp"
-        android:layout_marginStart="12dp"
         app:color="#4a90e2"
-        app:layout_constraintLeft_toRightOf="@id/colorSelect_column6" />
+        app:layout_constraintLeft_toRightOf="@id/colorSelect_column6"
+        app:layout_constraintRight_toLeftOf="@id/colorSelect_column8" />
 
     <com.kdanmobile.reader.screen.view.ColorOvalView
         android:id="@+id/colorSelect_column8"
         android:layout_width="24dp"
         android:layout_height="24dp"
-        android:layout_marginLeft="12dp"
-        android:layout_marginStart="12dp"
-        app:layout_constraintLeft_toRightOf="@id/colorSelect_column7" />
+        app:layout_constraintLeft_toRightOf="@id/colorSelect_column7"
+        app:layout_constraintRight_toRightOf="parent"/>
 </android.support.constraint.ConstraintLayout>

+ 1 - 1
reader/src/main/res/layout/view_viewer_edit_item_shape_border.xml

@@ -6,7 +6,7 @@
 
     <com.kdanmobile.reader.screen.view.ColorSelectView
         android:id="@+id/colorChooser_shapeBorder"
-        android:layout_width="wrap_content"
+        android:layout_width="0dp"
         android:layout_height="50dp"
         android:gravity="center"
         android:paddingTop="12dp"

+ 1 - 1
reader/src/main/res/layout/view_viewer_edit_item_shape_fill.xml

@@ -6,7 +6,7 @@
 
     <com.kdanmobile.reader.screen.view.ColorSelectView
         android:id="@+id/colorChooser_shapeFill"
-        android:layout_width="wrap_content"
+        android:layout_width="0dp"
         android:layout_height="50dp"
         android:gravity="center"
         android:paddingTop="12dp"

+ 1 - 1
reader/src/main/res/layout/view_viewer_edit_item_stamp_custom.xml

@@ -63,7 +63,7 @@
 
     <android.support.v7.widget.RecyclerView
         android:id="@+id/recyclerView_shapeCustom"
-        android:layout_width="match_parent"
+        android:layout_width="wrap_content"
         android:layout_height="0dp"
         app:layout_constraintBottom_toBottomOf="parent"
         app:layout_constraintLeft_toLeftOf="parent"

+ 1 - 1
reader/src/main/res/layout/view_viewer_edit_tab_text_box.xml

@@ -58,7 +58,7 @@
 
     <com.kdanmobile.reader.screen.view.ColorSelectView
         android:id="@+id/colorChooser_textBox"
-        android:layout_width="wrap_content"
+        android:layout_width="0dp"
         android:layout_height="48dp"
         android:gravity="center"
         android:paddingTop="12dp"