diff --git a/app/src/main/java/io/legado/app/base/BaseActivity.kt b/app/src/main/java/io/legado/app/base/BaseActivity.kt index 18327f3a7..ec1f6c011 100644 --- a/app/src/main/java/io/legado/app/base/BaseActivity.kt +++ b/app/src/main/java/io/legado/app/base/BaseActivity.kt @@ -147,7 +147,7 @@ abstract class BaseActivity( open fun upBackgroundImage() { if (imageBg) { try { - ThemeConfig.getBgImage(this, windowSize)?.let { + ThemeConfig.getBgImage(this, windowManager.windowSize)?.let { window.decorView.background = BitmapDrawable(resources, it) } } catch (e: OutOfMemoryError) { diff --git a/app/src/main/java/io/legado/app/ui/book/source/edit/BookSourceEditActivity.kt b/app/src/main/java/io/legado/app/ui/book/source/edit/BookSourceEditActivity.kt index 1759aa04a..48feb17e4 100644 --- a/app/src/main/java/io/legado/app/ui/book/source/edit/BookSourceEditActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/source/edit/BookSourceEditActivity.kt @@ -1,14 +1,10 @@ package io.legado.app.ui.book.source.edit import android.app.Activity -import android.graphics.Rect import android.os.Bundle -import android.view.Gravity import android.view.Menu import android.view.MenuItem -import android.view.ViewTreeObserver import android.widget.EditText -import android.widget.PopupWindow import androidx.activity.viewModels import androidx.recyclerview.widget.LinearLayoutManager import com.google.android.material.tabs.TabLayout @@ -33,7 +29,6 @@ import io.legado.app.ui.widget.KeyboardToolPop import io.legado.app.ui.widget.dialog.TextDialog import io.legado.app.utils.* import io.legado.app.utils.viewbindingdelegate.viewBinding -import kotlin.math.abs class BookSourceEditActivity : VMBaseActivity(false), @@ -65,10 +60,9 @@ class BookSourceEditActivity : } } - private val mSoftKeyboardTool: PopupWindow by lazy { - KeyboardToolPop(this, this, this) + private val softKeyboardTool by lazy { + KeyboardToolPop(this, this, binding.root, this) } - private var mIsSoftKeyBoardShowing = false override fun onActivityCreated(savedInstanceState: Bundle?) { initView() @@ -141,7 +135,7 @@ class BookSourceEditActivity : private fun initView() { binding.recyclerView.setEdgeEffectColor(primaryColor) - window.decorView.viewTreeObserver.addOnGlobalLayoutListener(KeyboardOnGlobalChangeListener()) + window.decorView.viewTreeObserver.addOnGlobalLayoutListener(softKeyboardTool) binding.recyclerView.layoutManager = LinearLayoutManager(this) binding.recyclerView.adapter = adapter binding.tabLayout.setBackgroundColor(backgroundColor) @@ -177,7 +171,7 @@ class BookSourceEditActivity : override fun onDestroy() { super.onDestroy() - mSoftKeyboardTool.dismiss() + softKeyboardTool.dismiss() } private fun setEditEntities(tabPosition: Int?) { @@ -477,38 +471,4 @@ class BookSourceEditActivity : showDialogFragment(TextDialog(mdText, TextDialog.Mode.MD)) } - private fun showKeyboardTopPopupWindow() { - mSoftKeyboardTool.let { - if (it.isShowing) return - if (!isFinishing) { - it.showAtLocation(binding.root, Gravity.BOTTOM, 0, 0) - } - } - } - - private fun closePopupWindow() { - mSoftKeyboardTool.dismiss() - } - - private inner class KeyboardOnGlobalChangeListener : ViewTreeObserver.OnGlobalLayoutListener { - override fun onGlobalLayout() { - val rect = Rect() - // 获取当前页面窗口的显示范围 - window.decorView.getWindowVisibleDisplayFrame(rect) - val screenHeight = this@BookSourceEditActivity.windowSize.heightPixels - val keyboardHeight = screenHeight - rect.bottom // 输入法的高度 - val preShowing = mIsSoftKeyBoardShowing - if (abs(keyboardHeight) > screenHeight / 5) { - mIsSoftKeyBoardShowing = true // 超过屏幕五分之一则表示弹出了输入法 - binding.recyclerView.setPadding(0, 0, 0, 100) - showKeyboardTopPopupWindow() - } else { - mIsSoftKeyBoardShowing = false - binding.recyclerView.setPadding(0, 0, 0, 0) - if (preShowing) { - closePopupWindow() - } - } - } - } } diff --git a/app/src/main/java/io/legado/app/ui/replace/edit/ReplaceEditActivity.kt b/app/src/main/java/io/legado/app/ui/replace/edit/ReplaceEditActivity.kt index 58eb714ed..f1f4822d0 100644 --- a/app/src/main/java/io/legado/app/ui/replace/edit/ReplaceEditActivity.kt +++ b/app/src/main/java/io/legado/app/ui/replace/edit/ReplaceEditActivity.kt @@ -2,14 +2,10 @@ package io.legado.app.ui.replace.edit import android.content.Context import android.content.Intent -import android.graphics.Rect import android.os.Bundle -import android.view.Gravity import android.view.Menu import android.view.MenuItem -import android.view.ViewTreeObserver import android.widget.EditText -import android.widget.PopupWindow import androidx.activity.viewModels import io.legado.app.R import io.legado.app.base.VMBaseActivity @@ -21,15 +17,12 @@ import io.legado.app.ui.widget.dialog.TextDialog import io.legado.app.utils.showDialogFragment import io.legado.app.utils.toastOnUi import io.legado.app.utils.viewbindingdelegate.viewBinding -import io.legado.app.utils.windowSize -import kotlin.math.abs /** * 编辑替换规则 */ class ReplaceEditActivity : VMBaseActivity(false), - ViewTreeObserver.OnGlobalLayoutListener, KeyboardToolPop.CallBack { companion object { @@ -54,13 +47,12 @@ class ReplaceEditActivity : override val binding by viewBinding(ActivityReplaceEditBinding::inflate) override val viewModel by viewModels() - private val mSoftKeyboardTool: PopupWindow by lazy { - KeyboardToolPop(this, this, this) + private val softKeyboardTool by lazy { + KeyboardToolPop(this, this, binding.root, this) } - private var mIsSoftKeyBoardShowing = false override fun onActivityCreated(savedInstanceState: Bundle?) { - window.decorView.viewTreeObserver.addOnGlobalLayoutListener(this) + window.decorView.viewTreeObserver.addOnGlobalLayoutListener(softKeyboardTool) viewModel.initData(intent) { upReplaceView(it) } @@ -91,6 +83,11 @@ class ReplaceEditActivity : return true } + override fun onDestroy() { + super.onDestroy() + softKeyboardTool.dismiss() + } + private fun upReplaceView(replaceRule: ReplaceRule) = binding.run { etName.setText(replaceRule.name) etGroup.setText(replaceRule.group) @@ -146,37 +143,4 @@ class ReplaceEditActivity : showDialogFragment(TextDialog(mdText, TextDialog.Mode.MD)) } - private fun showKeyboardTopPopupWindow() { - mSoftKeyboardTool.let { - if (it.isShowing) return - if (!isFinishing) { - it.showAtLocation(binding.llContent, Gravity.BOTTOM, 0, 0) - } - } - } - - private fun closePopupWindow() { - mSoftKeyboardTool.dismiss() - } - - override fun onGlobalLayout() { - val rect = Rect() - // 获取当前页面窗口的显示范围 - window.decorView.getWindowVisibleDisplayFrame(rect) - val screenHeight = this.windowSize.heightPixels - val keyboardHeight = screenHeight - rect.bottom // 输入法的高度 - val preShowing = mIsSoftKeyBoardShowing - if (abs(keyboardHeight) > screenHeight / 5) { - mIsSoftKeyBoardShowing = true // 超过屏幕五分之一则表示弹出了输入法 - binding.rootView.setPadding(0, 0, 0, 100) - showKeyboardTopPopupWindow() - } else { - mIsSoftKeyBoardShowing = false - binding.rootView.setPadding(0, 0, 0, 0) - if (preShowing) { - closePopupWindow() - } - } - } - } diff --git a/app/src/main/java/io/legado/app/ui/rss/source/edit/RssSourceEditActivity.kt b/app/src/main/java/io/legado/app/ui/rss/source/edit/RssSourceEditActivity.kt index 2fbfc19ff..d44095c88 100644 --- a/app/src/main/java/io/legado/app/ui/rss/source/edit/RssSourceEditActivity.kt +++ b/app/src/main/java/io/legado/app/ui/rss/source/edit/RssSourceEditActivity.kt @@ -1,14 +1,10 @@ package io.legado.app.ui.rss.source.edit import android.app.Activity -import android.graphics.Rect import android.os.Bundle -import android.view.Gravity import android.view.Menu import android.view.MenuItem -import android.view.ViewTreeObserver import android.widget.EditText -import android.widget.PopupWindow import androidx.activity.viewModels import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel import io.legado.app.R @@ -27,19 +23,16 @@ import io.legado.app.ui.widget.KeyboardToolPop import io.legado.app.ui.widget.dialog.TextDialog import io.legado.app.utils.* import io.legado.app.utils.viewbindingdelegate.viewBinding -import kotlin.math.abs class RssSourceEditActivity : VMBaseActivity(false), - ViewTreeObserver.OnGlobalLayoutListener, KeyboardToolPop.CallBack { override val binding by viewBinding(ActivityRssSourceEditBinding::inflate) override val viewModel by viewModels() - private val mSoftKeyboardTool: PopupWindow by lazy { - KeyboardToolPop(this, this, this) + private val softKeyboardTool by lazy { + KeyboardToolPop(this, this, binding.root, this) } - private var mIsSoftKeyBoardShowing = false private val adapter by lazy { RssSourceEditAdapter() } private val sourceEntities: ArrayList = ArrayList() private val qrCodeResult = registerForActivityResult(QrCodeResult()) { @@ -81,7 +74,7 @@ class RssSourceEditActivity : override fun onDestroy() { super.onDestroy() - mSoftKeyboardTool.dismiss() + softKeyboardTool.dismiss() } override fun onCompatCreateOptionsMenu(menu: Menu): Boolean { @@ -143,7 +136,7 @@ class RssSourceEditActivity : private fun initView() { binding.recyclerView.setEdgeEffectColor(primaryColor) - window.decorView.viewTreeObserver.addOnGlobalLayoutListener(this) + window.decorView.viewTreeObserver.addOnGlobalLayoutListener(softKeyboardTool) binding.recyclerView.adapter = adapter } @@ -268,37 +261,4 @@ class RssSourceEditActivity : showDialogFragment(TextDialog(mdText, TextDialog.Mode.MD)) } - private fun showKeyboardTopPopupWindow() { - mSoftKeyboardTool.let { - if (it.isShowing) return - if (!isFinishing) { - it.showAtLocation(binding.root, Gravity.BOTTOM, 0, 0) - } - } - } - - private fun closePopupWindow() { - mSoftKeyboardTool.dismiss() - } - - override fun onGlobalLayout() { - val rect = Rect() - // 获取当前页面窗口的显示范围 - window.decorView.getWindowVisibleDisplayFrame(rect) - val screenHeight = this@RssSourceEditActivity.windowSize.heightPixels - val keyboardHeight = screenHeight - rect.bottom // 输入法的高度 - val preShowing = mIsSoftKeyBoardShowing - if (abs(keyboardHeight) > screenHeight / 5) { - mIsSoftKeyBoardShowing = true // 超过屏幕五分之一则表示弹出了输入法 - binding.recyclerView.setPadding(0, 0, 0, 100) - showKeyboardTopPopupWindow() - } else { - mIsSoftKeyBoardShowing = false - binding.recyclerView.setPadding(0, 0, 0, 0) - if (preShowing) { - closePopupWindow() - } - } - } - } \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/ui/welcome/WelcomeActivity.kt b/app/src/main/java/io/legado/app/ui/welcome/WelcomeActivity.kt index 55f6d7bc3..692e2b780 100644 --- a/app/src/main/java/io/legado/app/ui/welcome/WelcomeActivity.kt +++ b/app/src/main/java/io/legado/app/ui/welcome/WelcomeActivity.kt @@ -78,7 +78,7 @@ open class WelcomeActivity : BaseActivity() { kotlin.runCatching { when (Theme.getTheme()) { Theme.Dark -> getPrefString(PreferKey.welcomeImageDark)?.let { path -> - val size = windowSize + val size = windowManager.windowSize BitmapUtils.decodeBitmap(path, size.widthPixels, size.heightPixels).let { binding.tvLegado.visible(getPrefBoolean(PreferKey.welcomeShowTextDark)) binding.ivBook.visible(getPrefBoolean(PreferKey.welcomeShowIconDark)) @@ -87,7 +87,7 @@ open class WelcomeActivity : BaseActivity() { } } else -> getPrefString(PreferKey.welcomeImage)?.let { path -> - val size = windowSize + val size = windowManager.windowSize BitmapUtils.decodeBitmap(path, size.widthPixels, size.heightPixels).let { binding.tvLegado.visible(getPrefBoolean(PreferKey.welcomeShowText)) binding.ivBook.visible(getPrefBoolean(PreferKey.welcomeShowIcon)) diff --git a/app/src/main/java/io/legado/app/ui/widget/KeyboardToolPop.kt b/app/src/main/java/io/legado/app/ui/widget/KeyboardToolPop.kt index 5d8b4510c..c5a7bd95d 100644 --- a/app/src/main/java/io/legado/app/ui/widget/KeyboardToolPop.kt +++ b/app/src/main/java/io/legado/app/ui/widget/KeyboardToolPop.kt @@ -1,8 +1,8 @@ package io.legado.app.ui.widget import android.content.Context -import android.view.LayoutInflater -import android.view.ViewGroup +import android.graphics.Rect +import android.view.* import android.widget.PopupWindow import io.legado.app.base.adapter.ItemViewHolder import io.legado.app.base.adapter.RecyclerAdapter @@ -10,11 +10,14 @@ import io.legado.app.data.appDb import io.legado.app.data.entities.KeyboardAssist import io.legado.app.databinding.ItemFilletTextBinding import io.legado.app.databinding.PopupKeyboardToolBinding +import io.legado.app.utils.windowSize import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import splitties.systemservices.layoutInflater +import splitties.systemservices.windowManager +import kotlin.math.abs /** * 键盘帮助浮窗 @@ -22,13 +25,16 @@ import splitties.systemservices.layoutInflater class KeyboardToolPop( private val context: Context, private val scope: CoroutineScope, + private val rootView: View, private val callBack: CallBack -) : PopupWindow(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT) { +) : PopupWindow(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT), + ViewTreeObserver.OnGlobalLayoutListener { private val helpChar = "❓" private val binding = PopupKeyboardToolBinding.inflate(LayoutInflater.from(context)) private val adapter = Adapter(context) + private var mIsSoftKeyBoardShowing = false init { contentView = binding.root @@ -41,6 +47,28 @@ class KeyboardToolPop( upAdapterData() } + override fun onGlobalLayout() { + val rect = Rect() + // 获取当前页面窗口的显示范围 + rootView.getWindowVisibleDisplayFrame(rect) + val screenHeight = windowManager.windowSize.heightPixels + val keyboardHeight = screenHeight - rect.bottom // 输入法的高度 + val preShowing = mIsSoftKeyBoardShowing + if (abs(keyboardHeight) > screenHeight / 5) { + mIsSoftKeyBoardShowing = true // 超过屏幕五分之一则表示弹出了输入法 + rootView.setPadding(0, 0, 0, 100) + if (!isShowing) { + showAtLocation(rootView, Gravity.BOTTOM, 0, 0) + } + } else { + mIsSoftKeyBoardShowing = false + rootView.setPadding(0, 0, 0, 0) + if (preShowing) { + dismiss() + } + } + } + private fun initRecyclerView() { binding.recyclerView.adapter = adapter adapter.addHeaderView { diff --git a/app/src/main/java/io/legado/app/utils/ActivityExtensions.kt b/app/src/main/java/io/legado/app/utils/ActivityExtensions.kt index 9a0fe2355..98201af12 100644 --- a/app/src/main/java/io/legado/app/utils/ActivityExtensions.kt +++ b/app/src/main/java/io/legado/app/utils/ActivityExtensions.kt @@ -26,18 +26,18 @@ fun AppCompatActivity.showDialogFragment(dialogFragment: DialogFragment) { dialogFragment.show(supportFragmentManager, dialogFragment::class.simpleName) } -val Activity.windowSize: DisplayMetrics +val WindowManager.windowSize: DisplayMetrics get() { val displayMetrics = DisplayMetrics() if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { - val windowMetrics: WindowMetrics = windowManager.currentWindowMetrics + val windowMetrics: WindowMetrics = currentWindowMetrics val insets = windowMetrics.windowInsets .getInsetsIgnoringVisibility(WindowInsets.Type.systemBars()) displayMetrics.widthPixels = windowMetrics.bounds.width() - insets.left - insets.right displayMetrics.heightPixels = windowMetrics.bounds.height() - insets.top - insets.bottom } else { @Suppress("DEPRECATION") - windowManager.defaultDisplay.getMetrics(displayMetrics) + defaultDisplay.getMetrics(displayMetrics) } return displayMetrics } diff --git a/app/src/main/java/io/legado/app/utils/DialogExtensions.kt b/app/src/main/java/io/legado/app/utils/DialogExtensions.kt index 0aa488322..8f2f5346a 100644 --- a/app/src/main/java/io/legado/app/utils/DialogExtensions.kt +++ b/app/src/main/java/io/legado/app/utils/DialogExtensions.kt @@ -30,7 +30,7 @@ fun AlertDialog.requestInputMethod() { } fun DialogFragment.setLayout(widthMix: Float, heightMix: Float) { - val dm = requireActivity().windowSize + val dm = requireActivity().windowManager.windowSize dialog?.window?.setLayout( (dm.widthPixels * widthMix).toInt(), (dm.heightPixels * heightMix).toInt() @@ -38,7 +38,7 @@ fun DialogFragment.setLayout(widthMix: Float, heightMix: Float) { } fun DialogFragment.setLayout(width: Int, heightMix: Float) { - val dm = requireActivity().windowSize + val dm = requireActivity().windowManager.windowSize dialog?.window?.setLayout( width, (dm.heightPixels * heightMix).toInt() @@ -46,7 +46,7 @@ fun DialogFragment.setLayout(width: Int, heightMix: Float) { } fun DialogFragment.setLayout(widthMix: Float, height: Int) { - val dm = requireActivity().windowSize + val dm = requireActivity().windowManager.windowSize dialog?.window?.setLayout( (dm.widthPixels * widthMix).toInt(), height