Просмотр исходного кода

Merge pull request #902

* 点击区域设置压缩问题
5151561 6 месяцев назад
Родитель
Сommit
347995a676

+ 62 - 0
app/src/main/java/io/legado/app/base/BaseOverlayDialogFragment.kt

@@ -0,0 +1,62 @@
+package io.legado.app.base
+
+import android.app.Dialog
+import android.content.DialogInterface
+import android.os.Bundle
+import android.view.View
+import androidx.annotation.LayoutRes
+import androidx.fragment.app.DialogFragment
+import androidx.fragment.app.FragmentManager
+import androidx.lifecycle.lifecycleScope
+import io.legado.app.constant.AppLog
+import io.legado.app.help.coroutine.Coroutine
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
+import kotlin.coroutines.CoroutineContext
+
+abstract class BaseOverlayDialogFragment(
+    @LayoutRes layoutID: Int
+) : DialogFragment(layoutID) {
+
+    private var onDismissListener: DialogInterface.OnDismissListener? = null
+
+    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
+        return Dialog(requireContext(), theme)
+    }
+
+    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+        super.onViewCreated(view, savedInstanceState)
+        onFragmentCreated(view, savedInstanceState)
+        observeLiveBus()
+    }
+
+    abstract fun onFragmentCreated(view: View, savedInstanceState: Bundle?)
+
+    open fun observeLiveBus() {
+    }
+
+    fun setOnDismissListener(onDismissListener: DialogInterface.OnDismissListener?) {
+        this.onDismissListener = onDismissListener
+    }
+
+    override fun onDismiss(dialog: DialogInterface) {
+        super.onDismiss(dialog)
+        onDismissListener?.onDismiss(dialog)
+    }
+
+    override fun show(manager: FragmentManager, tag: String?) {
+        if (isAdded) return
+        kotlin.runCatching {
+            manager.beginTransaction().remove(this).commitAllowingStateLoss()
+            super.show(manager, tag)
+        }.onFailure {
+            AppLog.put("显示对话框失败 tag:$tag", it)
+        }
+    }
+
+    fun <T> execute(
+        scope: CoroutineScope = lifecycleScope,
+        context: CoroutineContext = Dispatchers.IO,
+        block: suspend CoroutineScope.() -> T
+    ) = Coroutine.async(scope, context) { block() }
+}

+ 2 - 3
app/src/main/java/io/legado/app/ui/book/manga/config/MangaClickActionConfigDialog.kt

@@ -6,7 +6,7 @@ import android.view.View
 import android.view.ViewGroup
 import android.widget.TextView
 import io.legado.app.R
-import io.legado.app.base.BaseDialogFragment
+import io.legado.app.base.BaseOverlayDialogFragment
 import io.legado.app.constant.PreferKey
 import io.legado.app.databinding.DialogClickActionConfigBinding
 import io.legado.app.help.config.AppConfig
@@ -15,7 +15,7 @@ import io.legado.app.utils.getCompatColor
 import io.legado.app.utils.putPrefInt
 import io.legado.app.utils.viewbindingdelegate.viewBinding
 
-class MangaClickActionConfigDialog : BaseDialogFragment(R.layout.dialog_click_action_config) {
+class MangaClickActionConfigDialog : BaseOverlayDialogFragment(R.layout.dialog_click_action_config) {
     private val binding by viewBinding(DialogClickActionConfigBinding::bind)
 
     private val actions by lazy {
@@ -142,4 +142,3 @@ class MangaClickActionConfigDialog : BaseDialogFragment(R.layout.dialog_click_ac
         AppConfig.detectMangaClickArea()
     }
 }
-

+ 3 - 3
app/src/main/java/io/legado/app/ui/book/read/config/ClickActionConfigDialog.kt

@@ -6,7 +6,7 @@ import android.view.View
 import android.view.ViewGroup
 import android.widget.TextView
 import io.legado.app.R
-import io.legado.app.base.BaseDialogFragment
+import io.legado.app.base.BaseOverlayDialogFragment
 import io.legado.app.constant.PreferKey
 import io.legado.app.databinding.DialogClickActionConfigBinding
 import io.legado.app.help.config.AppConfig
@@ -19,7 +19,7 @@ import io.legado.app.utils.viewbindingdelegate.viewBinding
 /**
  * 点击区域设置
  */
-class ClickActionConfigDialog : BaseDialogFragment(R.layout.dialog_click_action_config) {
+class ClickActionConfigDialog : BaseOverlayDialogFragment(R.layout.dialog_click_action_config) {
     private val binding by viewBinding(DialogClickActionConfigBinding::bind)
     private val actions by lazy {
         linkedMapOf(
@@ -147,4 +147,4 @@ class ClickActionConfigDialog : BaseDialogFragment(R.layout.dialog_click_action_
         AppConfig.detectClickArea()
     }
 
-}
+}

+ 94 - 0
app/src/test/java/io/legado/app/ui/book/read/config/ClickActionConfigDialogTest.kt

@@ -0,0 +1,94 @@
+package io.legado.app.ui.book.read.config
+
+import android.app.Application
+import android.os.Bundle
+import android.view.View
+import android.view.View.MeasureSpec
+import android.view.ViewGroup
+import android.widget.FrameLayout
+import androidx.appcompat.app.AppCompatActivity
+import io.legado.app.base.BaseOverlayDialogFragment
+import io.legado.app.R
+import org.junit.Assert.assertEquals
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.robolectric.Robolectric
+import org.robolectric.RobolectricTestRunner
+import org.robolectric.Shadows.shadowOf
+import org.robolectric.annotation.Config
+import splitties.init.injectAsAppCtx
+
+@RunWith(RobolectricTestRunner::class)
+@Config(
+    sdk = [34],
+    application = ClickActionConfigDialogTest.TestApplication::class
+)
+class ClickActionConfigDialogTest {
+
+    @Test
+    fun clickActionConfigDialog_shouldFillWindowHeight() {
+        val activity = Robolectric.buildActivity(TestActivity::class.java)
+            .setup()
+            .get()
+        val dialog = TestFullscreenDialog()
+
+        dialog.show(activity.supportFragmentManager, "click-config")
+        shadowOf(activity.mainLooper).idle()
+
+        val windowHeight = 1920
+        val windowWidth = 1080
+        val decorView = dialog.requireDialog().window!!.decorView
+        layoutView(decorView, windowWidth, windowHeight)
+
+        assertEquals(
+            "ClickActionConfigDialog root view should cover the full window height",
+            windowHeight,
+            dialog.requireView().height
+        )
+    }
+
+    private fun layoutView(view: View, width: Int, height: Int) {
+        view.measure(
+            MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
+            MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)
+        )
+        view.layout(0, 0, width, height)
+    }
+
+    class TestApplication : Application() {
+        override fun onCreate() {
+            injectAsAppCtx()
+            super.onCreate()
+        }
+    }
+
+    class TestFullscreenDialog : BaseOverlayDialogFragment(R.layout.dialog_click_action_config) {
+        override fun onStart() {
+            super.onStart()
+            dialog?.window?.run {
+                setBackgroundDrawableResource(R.color.transparent)
+                setLayout(
+                    ViewGroup.LayoutParams.MATCH_PARENT,
+                    ViewGroup.LayoutParams.MATCH_PARENT
+                )
+            }
+        }
+
+        override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) = Unit
+    }
+
+    class TestActivity : AppCompatActivity() {
+        override fun onCreate(savedInstanceState: Bundle?) {
+            setTheme(R.style.Theme_Base_WH)
+            super.onCreate(savedInstanceState)
+            setContentView(
+                FrameLayout(this).apply {
+                    layoutParams = ViewGroup.LayoutParams(
+                        ViewGroup.LayoutParams.MATCH_PARENT,
+                        ViewGroup.LayoutParams.MATCH_PARENT
+                    )
+                }
+            )
+        }
+    }
+}