浏览代码

Merge branch 'inkMenu' into 'master'

實作ink undo/redo功能

See merge request kdanandroid/pdf/pdfreaderreadermodule!20
Wayne Huang 5 年之前
父节点
当前提交
1f217d2d6d

+ 47 - 5
src/main/java/com/kdanmobile/reader/ReaderActivity.kt

@@ -16,10 +16,7 @@ import android.support.v7.app.AlertDialog
 import android.util.DisplayMetrics
 import android.view.*
 import android.view.animation.AnimationUtils
-import android.widget.EditText
-import android.widget.LinearLayout
-import android.widget.TextView
-import android.widget.Toast
+import android.widget.*
 import com.kdanmobile.base.KdanBaseActivity
 import com.kdanmobile.kmpdfkit.pdfcommon.KMPDFReaderView
 import com.kdanmobile.kmpdfkit.pdfcommon.PDFInfo
@@ -36,6 +33,7 @@ import com.kdanmobile.reader.screen.reader.mediabox.signature.SignatureTabView
 import com.kdanmobile.reader.screen.reader.mediabox.stamp.StampTabView
 import com.kdanmobile.reader.screen.reader.mediabox.textbox.TextBoxTabView
 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.thumb.PdfThumbDialogFragment
@@ -214,6 +212,7 @@ abstract class ReaderActivity : KdanBaseActivity(), ReaderSettingListener, PdfTh
         applySetting()
 
         setupPdfChangedListener()
+        setupInkMenu()
     }
 
     private fun showFileCannotOpenDialog(title: String) {
@@ -379,6 +378,33 @@ abstract class ReaderActivity : KdanBaseActivity(), ReaderSettingListener, PdfTh
             false -> hideTopLeftBottomToolbars()
         }
         readerModel.onPdfChangedListener?.onPageUpdated(arrayListOf(currentPageIndex))
+
+        if (viewModel.annotationModeLiveData.value != ReaderViewModel.AnnotationMode.INK) {
+            AnimationUtil.hideViewAlpha(view_ink_menu)
+        }
+    }
+
+    private fun setupInkMenu() {
+        val btnInkUndo = findViewById<ImageButton>(R.id.btn_ink_undo)
+        val btnInkRedo = findViewById<ImageButton>(R.id.btn_ink_redo)
+        val btnInkClean = findViewById<ImageButton>(R.id.btn_ink_clean)
+        val btnInkDone = findViewById<ImageButton>(R.id.btn_ink_done)
+
+        btnInkUndo.setOnClickListener {
+            viewModel.undoInk()
+        }
+
+        btnInkRedo.setOnClickListener {
+            viewModel.redoInk()
+        }
+
+        btnInkClean.setOnClickListener {
+            viewModel.cleanInk()
+        }
+
+        btnInkDone.setOnClickListener {
+            viewModel.finishInk()
+        }
     }
 
     private fun onAnnotationEditModeUpdate(mode: ReaderViewModel.AnnotationEitMode?) {
@@ -510,6 +536,10 @@ abstract class ReaderActivity : KdanBaseActivity(), ReaderSettingListener, PdfTh
             val event = MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, -1000f, -1000f, 0)
             viewModel.getReaderView()?.onSingleTapUp(event)
         }
+        if (viewModel.annotationModeLiveData.value == ReaderViewModel.AnnotationMode.INK) {
+            viewModel.stopAnnotationMode()
+            viewModel.annotationModeLiveData.value = ReaderViewModel.AnnotationMode.NONE
+        }
         viewModel.saveModifyingAnnotation()
         viewModel.temporarySave()
         if (!filePath.isNullOrEmpty()) {
@@ -1013,7 +1043,14 @@ abstract class ReaderActivity : KdanBaseActivity(), ReaderSettingListener, PdfTh
             }
         }
         iv_readerActivity_ink.apply {
-            setOnClickListener { viewModel.onClickInkBtn() }
+            setOnClickListener {
+                if (viewModel.annotationModeLiveData.value == ReaderViewModel.AnnotationMode.INK) {
+                    AnimationUtil.hideViewAlpha(view_ink_menu)
+                } else {
+                    AnimationUtil.showViewAlpha(view_ink_menu)
+                }
+                viewModel.onClickInkBtn()
+            }
             setOnLongClickListener { btn ->
                 viewModel.onLongClickInkBtn()
                 val context = this@ReaderActivity
@@ -1035,6 +1072,11 @@ abstract class ReaderActivity : KdanBaseActivity(), ReaderSettingListener, PdfTh
                     val xOff = (-contentView.measuredWidth - space).toInt()
                     val yOff = -contentView.measuredHeight
                     window.showAsDropDown(btn, xOff, yOff)
+
+                    AnimationUtil.hideViewAlpha(view_ink_menu)
+                    window.setOnDismissListener {
+                        AnimationUtil.showViewAlpha(view_ink_menu)
+                    }
                 }
                 return@setOnLongClickListener true
             }

+ 21 - 0
src/main/java/com/kdanmobile/reader/ReaderViewModel.kt

@@ -365,6 +365,27 @@ class ReaderViewModel(private val readerModelManager: ReaderModelManager, val ur
         annotationModeLiveData.postValue(AnnotationMode.INK)
     }
 
+    fun undoInk() {
+        val controller = kmpdfFactory?.getController(KMPDFFactory.ControllerType.INK) as KMPDFInkController?
+        controller?.cancelDraw()
+    }
+
+    fun redoInk() {
+        val controller = kmpdfFactory?.getController(KMPDFFactory.ControllerType.INK) as KMPDFInkController?
+        controller?.recoverDraw()
+    }
+
+    fun cleanInk() {
+        val controller = kmpdfFactory?.getController(KMPDFFactory.ControllerType.INK) as KMPDFInkController?
+        controller?.cleanDraw()
+    }
+
+    fun finishInk() {
+        val controller = kmpdfFactory?.getController(KMPDFFactory.ControllerType.INK) as KMPDFInkController?
+        controller?.stopDrawInk()
+        stopAnnotationMode()
+    }
+
     fun stopAnnotationMode() {
         kmpdfFactory?.setAnnotationEditMode(KMPDFAnnotationBean.AnnotationType.NULL)
         annotationModeLiveData.postValue(AnnotationMode.NONE)

+ 9 - 7
src/main/java/com/kdanmobile/reader/utils/AnimationUtil.kt

@@ -349,9 +349,10 @@ class AnimationUtil private constructor() {
         }
 
         fun showViewAlpha(view: View?, duration: Long = 300) {
-            if (view != null && view.visibility != View.VISIBLE) {
-                val pvhA = PropertyValuesHolder.ofFloat("alpha", 0f, 1.0f)
-                val animAlpha = ObjectAnimator.ofPropertyValuesHolder(view, pvhA)
+            if (view != null) {
+                val pvhA = PropertyValuesHolder.ofFloat("alpha", view.alpha, 1.0f)
+                val pvhV = PropertyValuesHolder.ofInt("visibility", view.visibility, View.VISIBLE)
+                val animAlpha = ObjectAnimator.ofPropertyValuesHolder(view, pvhA, pvhV)
                 animAlpha.interpolator = AccelerateInterpolator()
                 animAlpha.addListener(object : AnimatorListenerAdapter() {
                     override fun onAnimationStart(animation: Animator) {
@@ -364,14 +365,15 @@ class AnimationUtil private constructor() {
         }
 
         fun hideViewAlpha(view: View?, duration: Long = 300) {
-            if (view != null && view.visibility == View.VISIBLE) {
-                val pvhA = PropertyValuesHolder.ofFloat("alpha", 1.0f, 0f)
-                val animAlpha = ObjectAnimator.ofPropertyValuesHolder(view, pvhA)
+            if (view != null) {
+                val pvhA = PropertyValuesHolder.ofFloat("alpha", view.alpha, 0f)
+                val pvhV = PropertyValuesHolder.ofInt("visibility", view.visibility, View.INVISIBLE)
+                val animAlpha = ObjectAnimator.ofPropertyValuesHolder(view, pvhA, pvhV)
                 animAlpha.interpolator = AccelerateInterpolator()
                 animAlpha.addListener(object : AnimatorListenerAdapter() {
                     override fun onAnimationEnd(animation: Animator) {
                         super.onAnimationEnd(animation)
-                        Handler(Looper.getMainLooper()).post { view.visibility = View.GONE }
+                        Handler(Looper.getMainLooper()).post { view.visibility = View.INVISIBLE }
                     }
                 })
                 animAlpha.setDuration(duration).start()

+ 21 - 0
src/main/res/drawable/bg_ink_menu.xml

@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+    <item>
+        <shape android:shape="rectangle" >
+            <solid android:color="#E1E1E1" />
+            <corners android:radius="4dp" />
+        </shape>
+    </item>
+
+    <item
+        android:top="1dp"
+        android:right="0dp"
+        android:bottom="1dp"
+        android:left="1dp" >
+        <shape android:shape="rectangle" >
+            <solid android:color="@color/ink_menu_background" />
+            <corners android:radius="4dp" />
+        </shape>
+    </item>
+</layer-list>
+

+ 5 - 0
src/main/res/drawable/bg_ink_menu_blue_button_normal.xml

@@ -0,0 +1,5 @@
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle" >
+    <solid android:color="@color/bright_blue" />
+    <corners android:radius="4dp"/>
+</shape>

+ 5 - 0
src/main/res/drawable/bg_ink_menu_blue_button_pressed.xml

@@ -0,0 +1,5 @@
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle" >
+    <solid android:color="@color/picton_blue" />
+    <corners android:radius="4dp"/>
+</shape>

+ 10 - 0
src/main/res/drawable/ic_delete.xml

@@ -0,0 +1,10 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+    <path
+        android:fillAlpha="0.6"
+        android:fillColor="#FF000000"
+        android:pathData="M6,19c0,1.1 0.9,2 2,2h8c1.1,0 2,-0.9 2,-2V7H6v12zM19,4h-3.5l-1,-1h-5l-1,1H5v2h14V4z"/>
+</vector>

+ 10 - 0
src/main/res/drawable/ic_done.xml

@@ -0,0 +1,10 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+    <path
+        android:fillAlpha="0.8"
+        android:fillColor="#FFFFFFFF"
+        android:pathData="M9,16.2L4.8,12l-1.4,1.4L9,19 21,7l-1.4,-1.4L9,16.2z"/>
+</vector>

+ 10 - 0
src/main/res/drawable/ic_redo.xml

@@ -0,0 +1,10 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+    <path
+        android:fillAlpha="0.6"
+        android:fillColor="#FF000000"
+        android:pathData="M18.4,10.6C16.55,8.99 14.15,8 11.5,8c-4.65,0 -8.58,3.03 -9.96,7.22L3.9,16c1.05,-3.19 4.05,-5.5 7.6,-5.5 1.95,0 3.73,0.72 5.12,1.88L13,16h9V7l-3.6,3.6z"/>
+</vector>

+ 10 - 0
src/main/res/drawable/ic_undo.xml

@@ -0,0 +1,10 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+    <path
+        android:fillAlpha="0.6"
+        android:fillColor="#FF000000"
+        android:pathData="M12.5,8c-2.65,0 -5.05,0.99 -6.9,2.6L2,7v9h9l-3.62,-3.62c1.39,-1.16 3.16,-1.88 5.12,-1.88 3.54,0 6.55,2.31 7.6,5.5l2.37,-0.78C21.08,11.03 17.15,8 12.5,8z"/>
+</vector>

+ 7 - 0
src/main/res/drawable/selector_ink_blue_button.xml

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <item android:drawable="@drawable/bg_ink_menu_blue_button_pressed" android:state_pressed="true"/>
+    <item android:drawable="@drawable/bg_ink_menu_blue_button_normal"/>
+
+</selector>

+ 7 - 0
src/main/res/drawable/selector_ink_white_button.xml

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <item android:drawable="@color/color_bolder" android:state_pressed="true"/>
+    <item android:drawable="@android:color/white"/>
+
+</selector>

+ 11 - 0
src/main/res/layout/activity_reader.xml

@@ -234,6 +234,17 @@
         android:layout_width="match_parent"
         android:layout_height="match_parent" />
 
+    <include
+        android:id="@+id/view_ink_menu"
+        layout="@layout/view_ink_menu"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="24dp"
+        android:visibility="gone"
+        app:layout_constraintTop_toTopOf="parent"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintRight_toRightOf="parent" />
+
     <TextView
         android:id="@+id/tv_readerActivity_pdfPage"
         android:layout_width="wrap_content"

+ 45 - 0
src/main/res/layout/view_ink_menu.xml

@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:background="@drawable/bg_ink_menu">
+
+	<LinearLayout
+		android:layout_width="match_parent"
+		android:layout_height="wrap_content"
+		android:layout_margin="2dp"
+		android:orientation="horizontal">
+		<ImageButton
+			android:id="@+id/btn_ink_undo"
+			android:layout_width="48dp"
+			android:layout_height="48dp"
+			android:gravity="center"
+			android:background="@drawable/selector_ink_white_button"
+			android:src="@drawable/ic_undo"/>
+
+		<ImageButton
+			android:id="@+id/btn_ink_redo"
+			android:layout_width="48dp"
+			android:layout_height="48dp"
+			android:gravity="center"
+			android:background="@drawable/selector_ink_white_button"
+			android:src="@drawable/ic_redo"/>
+
+		<ImageButton
+			android:id="@+id/btn_ink_clean"
+			android:layout_width="48dp"
+			android:layout_height="48dp"
+			android:gravity="center"
+			android:background="@drawable/selector_ink_white_button"
+			android:src="@drawable/ic_delete"/>
+
+		<ImageButton
+			android:id="@+id/btn_ink_done"
+			android:layout_width="48dp"
+			android:layout_height="48dp"
+			android:gravity="center"
+			android:background="@drawable/selector_ink_blue_button"
+			android:src="@drawable/ic_done"/>
+	</LinearLayout>
+
+</LinearLayout>

+ 2 - 0
src/main/res/values/colors.xml

@@ -73,4 +73,6 @@
 
     <color name="reader_textbox_sample_text">#f5a623</color>
     <color name="reader_textbox_sample_text_border">#cccccc</color>
+
+    <color name="ink_menu_background">#FFFFFF</color>
 </resources>