pull/1705/head
kunfei 3 years ago
parent 7f2d931238
commit 79b3f148b4
  1. 2
      app/src/main/java/io/legado/app/base/BaseActivity.kt
  2. 48
      app/src/main/java/io/legado/app/ui/book/source/edit/BookSourceEditActivity.kt
  3. 52
      app/src/main/java/io/legado/app/ui/replace/edit/ReplaceEditActivity.kt
  4. 48
      app/src/main/java/io/legado/app/ui/rss/source/edit/RssSourceEditActivity.kt
  5. 4
      app/src/main/java/io/legado/app/ui/welcome/WelcomeActivity.kt
  6. 34
      app/src/main/java/io/legado/app/ui/widget/KeyboardToolPop.kt
  7. 6
      app/src/main/java/io/legado/app/utils/ActivityExtensions.kt
  8. 6
      app/src/main/java/io/legado/app/utils/DialogExtensions.kt

@ -147,7 +147,7 @@ abstract class BaseActivity<VB : ViewBinding>(
open fun upBackgroundImage() { open fun upBackgroundImage() {
if (imageBg) { if (imageBg) {
try { try {
ThemeConfig.getBgImage(this, windowSize)?.let { ThemeConfig.getBgImage(this, windowManager.windowSize)?.let {
window.decorView.background = BitmapDrawable(resources, it) window.decorView.background = BitmapDrawable(resources, it)
} }
} catch (e: OutOfMemoryError) { } catch (e: OutOfMemoryError) {

@ -1,14 +1,10 @@
package io.legado.app.ui.book.source.edit package io.legado.app.ui.book.source.edit
import android.app.Activity import android.app.Activity
import android.graphics.Rect
import android.os.Bundle import android.os.Bundle
import android.view.Gravity
import android.view.Menu import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import android.view.ViewTreeObserver
import android.widget.EditText import android.widget.EditText
import android.widget.PopupWindow
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import com.google.android.material.tabs.TabLayout 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.ui.widget.dialog.TextDialog
import io.legado.app.utils.* import io.legado.app.utils.*
import io.legado.app.utils.viewbindingdelegate.viewBinding import io.legado.app.utils.viewbindingdelegate.viewBinding
import kotlin.math.abs
class BookSourceEditActivity : class BookSourceEditActivity :
VMBaseActivity<ActivityBookSourceEditBinding, BookSourceEditViewModel>(false), VMBaseActivity<ActivityBookSourceEditBinding, BookSourceEditViewModel>(false),
@ -65,10 +60,9 @@ class BookSourceEditActivity :
} }
} }
private val mSoftKeyboardTool: PopupWindow by lazy { private val softKeyboardTool by lazy {
KeyboardToolPop(this, this, this) KeyboardToolPop(this, this, binding.root, this)
} }
private var mIsSoftKeyBoardShowing = false
override fun onActivityCreated(savedInstanceState: Bundle?) { override fun onActivityCreated(savedInstanceState: Bundle?) {
initView() initView()
@ -141,7 +135,7 @@ class BookSourceEditActivity :
private fun initView() { private fun initView() {
binding.recyclerView.setEdgeEffectColor(primaryColor) binding.recyclerView.setEdgeEffectColor(primaryColor)
window.decorView.viewTreeObserver.addOnGlobalLayoutListener(KeyboardOnGlobalChangeListener()) window.decorView.viewTreeObserver.addOnGlobalLayoutListener(softKeyboardTool)
binding.recyclerView.layoutManager = LinearLayoutManager(this) binding.recyclerView.layoutManager = LinearLayoutManager(this)
binding.recyclerView.adapter = adapter binding.recyclerView.adapter = adapter
binding.tabLayout.setBackgroundColor(backgroundColor) binding.tabLayout.setBackgroundColor(backgroundColor)
@ -177,7 +171,7 @@ class BookSourceEditActivity :
override fun onDestroy() { override fun onDestroy() {
super.onDestroy() super.onDestroy()
mSoftKeyboardTool.dismiss() softKeyboardTool.dismiss()
} }
private fun setEditEntities(tabPosition: Int?) { private fun setEditEntities(tabPosition: Int?) {
@ -477,38 +471,4 @@ class BookSourceEditActivity :
showDialogFragment(TextDialog(mdText, TextDialog.Mode.MD)) 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()
}
}
}
}
} }

@ -2,14 +2,10 @@ package io.legado.app.ui.replace.edit
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.graphics.Rect
import android.os.Bundle import android.os.Bundle
import android.view.Gravity
import android.view.Menu import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import android.view.ViewTreeObserver
import android.widget.EditText import android.widget.EditText
import android.widget.PopupWindow
import androidx.activity.viewModels import androidx.activity.viewModels
import io.legado.app.R import io.legado.app.R
import io.legado.app.base.VMBaseActivity 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.showDialogFragment
import io.legado.app.utils.toastOnUi import io.legado.app.utils.toastOnUi
import io.legado.app.utils.viewbindingdelegate.viewBinding import io.legado.app.utils.viewbindingdelegate.viewBinding
import io.legado.app.utils.windowSize
import kotlin.math.abs
/** /**
* 编辑替换规则 * 编辑替换规则
*/ */
class ReplaceEditActivity : class ReplaceEditActivity :
VMBaseActivity<ActivityReplaceEditBinding, ReplaceEditViewModel>(false), VMBaseActivity<ActivityReplaceEditBinding, ReplaceEditViewModel>(false),
ViewTreeObserver.OnGlobalLayoutListener,
KeyboardToolPop.CallBack { KeyboardToolPop.CallBack {
companion object { companion object {
@ -54,13 +47,12 @@ class ReplaceEditActivity :
override val binding by viewBinding(ActivityReplaceEditBinding::inflate) override val binding by viewBinding(ActivityReplaceEditBinding::inflate)
override val viewModel by viewModels<ReplaceEditViewModel>() override val viewModel by viewModels<ReplaceEditViewModel>()
private val mSoftKeyboardTool: PopupWindow by lazy { private val softKeyboardTool by lazy {
KeyboardToolPop(this, this, this) KeyboardToolPop(this, this, binding.root, this)
} }
private var mIsSoftKeyBoardShowing = false
override fun onActivityCreated(savedInstanceState: Bundle?) { override fun onActivityCreated(savedInstanceState: Bundle?) {
window.decorView.viewTreeObserver.addOnGlobalLayoutListener(this) window.decorView.viewTreeObserver.addOnGlobalLayoutListener(softKeyboardTool)
viewModel.initData(intent) { viewModel.initData(intent) {
upReplaceView(it) upReplaceView(it)
} }
@ -91,6 +83,11 @@ class ReplaceEditActivity :
return true return true
} }
override fun onDestroy() {
super.onDestroy()
softKeyboardTool.dismiss()
}
private fun upReplaceView(replaceRule: ReplaceRule) = binding.run { private fun upReplaceView(replaceRule: ReplaceRule) = binding.run {
etName.setText(replaceRule.name) etName.setText(replaceRule.name)
etGroup.setText(replaceRule.group) etGroup.setText(replaceRule.group)
@ -146,37 +143,4 @@ class ReplaceEditActivity :
showDialogFragment(TextDialog(mdText, TextDialog.Mode.MD)) 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()
}
}
}
} }

@ -1,14 +1,10 @@
package io.legado.app.ui.rss.source.edit package io.legado.app.ui.rss.source.edit
import android.app.Activity import android.app.Activity
import android.graphics.Rect
import android.os.Bundle import android.os.Bundle
import android.view.Gravity
import android.view.Menu import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import android.view.ViewTreeObserver
import android.widget.EditText import android.widget.EditText
import android.widget.PopupWindow
import androidx.activity.viewModels import androidx.activity.viewModels
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel
import io.legado.app.R 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.ui.widget.dialog.TextDialog
import io.legado.app.utils.* import io.legado.app.utils.*
import io.legado.app.utils.viewbindingdelegate.viewBinding import io.legado.app.utils.viewbindingdelegate.viewBinding
import kotlin.math.abs
class RssSourceEditActivity : class RssSourceEditActivity :
VMBaseActivity<ActivityRssSourceEditBinding, RssSourceEditViewModel>(false), VMBaseActivity<ActivityRssSourceEditBinding, RssSourceEditViewModel>(false),
ViewTreeObserver.OnGlobalLayoutListener,
KeyboardToolPop.CallBack { KeyboardToolPop.CallBack {
override val binding by viewBinding(ActivityRssSourceEditBinding::inflate) override val binding by viewBinding(ActivityRssSourceEditBinding::inflate)
override val viewModel by viewModels<RssSourceEditViewModel>() override val viewModel by viewModels<RssSourceEditViewModel>()
private val mSoftKeyboardTool: PopupWindow by lazy { private val softKeyboardTool by lazy {
KeyboardToolPop(this, this, this) KeyboardToolPop(this, this, binding.root, this)
} }
private var mIsSoftKeyBoardShowing = false
private val adapter by lazy { RssSourceEditAdapter() } private val adapter by lazy { RssSourceEditAdapter() }
private val sourceEntities: ArrayList<EditEntity> = ArrayList() private val sourceEntities: ArrayList<EditEntity> = ArrayList()
private val qrCodeResult = registerForActivityResult(QrCodeResult()) { private val qrCodeResult = registerForActivityResult(QrCodeResult()) {
@ -81,7 +74,7 @@ class RssSourceEditActivity :
override fun onDestroy() { override fun onDestroy() {
super.onDestroy() super.onDestroy()
mSoftKeyboardTool.dismiss() softKeyboardTool.dismiss()
} }
override fun onCompatCreateOptionsMenu(menu: Menu): Boolean { override fun onCompatCreateOptionsMenu(menu: Menu): Boolean {
@ -143,7 +136,7 @@ class RssSourceEditActivity :
private fun initView() { private fun initView() {
binding.recyclerView.setEdgeEffectColor(primaryColor) binding.recyclerView.setEdgeEffectColor(primaryColor)
window.decorView.viewTreeObserver.addOnGlobalLayoutListener(this) window.decorView.viewTreeObserver.addOnGlobalLayoutListener(softKeyboardTool)
binding.recyclerView.adapter = adapter binding.recyclerView.adapter = adapter
} }
@ -268,37 +261,4 @@ class RssSourceEditActivity :
showDialogFragment(TextDialog(mdText, TextDialog.Mode.MD)) 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()
}
}
}
} }

@ -78,7 +78,7 @@ open class WelcomeActivity : BaseActivity<ActivityWelcomeBinding>() {
kotlin.runCatching { kotlin.runCatching {
when (Theme.getTheme()) { when (Theme.getTheme()) {
Theme.Dark -> getPrefString(PreferKey.welcomeImageDark)?.let { path -> Theme.Dark -> getPrefString(PreferKey.welcomeImageDark)?.let { path ->
val size = windowSize val size = windowManager.windowSize
BitmapUtils.decodeBitmap(path, size.widthPixels, size.heightPixels).let { BitmapUtils.decodeBitmap(path, size.widthPixels, size.heightPixels).let {
binding.tvLegado.visible(getPrefBoolean(PreferKey.welcomeShowTextDark)) binding.tvLegado.visible(getPrefBoolean(PreferKey.welcomeShowTextDark))
binding.ivBook.visible(getPrefBoolean(PreferKey.welcomeShowIconDark)) binding.ivBook.visible(getPrefBoolean(PreferKey.welcomeShowIconDark))
@ -87,7 +87,7 @@ open class WelcomeActivity : BaseActivity<ActivityWelcomeBinding>() {
} }
} }
else -> getPrefString(PreferKey.welcomeImage)?.let { path -> else -> getPrefString(PreferKey.welcomeImage)?.let { path ->
val size = windowSize val size = windowManager.windowSize
BitmapUtils.decodeBitmap(path, size.widthPixels, size.heightPixels).let { BitmapUtils.decodeBitmap(path, size.widthPixels, size.heightPixels).let {
binding.tvLegado.visible(getPrefBoolean(PreferKey.welcomeShowText)) binding.tvLegado.visible(getPrefBoolean(PreferKey.welcomeShowText))
binding.ivBook.visible(getPrefBoolean(PreferKey.welcomeShowIcon)) binding.ivBook.visible(getPrefBoolean(PreferKey.welcomeShowIcon))

@ -1,8 +1,8 @@
package io.legado.app.ui.widget package io.legado.app.ui.widget
import android.content.Context import android.content.Context
import android.view.LayoutInflater import android.graphics.Rect
import android.view.ViewGroup import android.view.*
import android.widget.PopupWindow import android.widget.PopupWindow
import io.legado.app.base.adapter.ItemViewHolder import io.legado.app.base.adapter.ItemViewHolder
import io.legado.app.base.adapter.RecyclerAdapter 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.data.entities.KeyboardAssist
import io.legado.app.databinding.ItemFilletTextBinding import io.legado.app.databinding.ItemFilletTextBinding
import io.legado.app.databinding.PopupKeyboardToolBinding import io.legado.app.databinding.PopupKeyboardToolBinding
import io.legado.app.utils.windowSize
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import splitties.systemservices.layoutInflater import splitties.systemservices.layoutInflater
import splitties.systemservices.windowManager
import kotlin.math.abs
/** /**
* 键盘帮助浮窗 * 键盘帮助浮窗
@ -22,13 +25,16 @@ import splitties.systemservices.layoutInflater
class KeyboardToolPop( class KeyboardToolPop(
private val context: Context, private val context: Context,
private val scope: CoroutineScope, private val scope: CoroutineScope,
private val rootView: View,
private val callBack: CallBack 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 helpChar = ""
private val binding = PopupKeyboardToolBinding.inflate(LayoutInflater.from(context)) private val binding = PopupKeyboardToolBinding.inflate(LayoutInflater.from(context))
private val adapter = Adapter(context) private val adapter = Adapter(context)
private var mIsSoftKeyBoardShowing = false
init { init {
contentView = binding.root contentView = binding.root
@ -41,6 +47,28 @@ class KeyboardToolPop(
upAdapterData() 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() { private fun initRecyclerView() {
binding.recyclerView.adapter = adapter binding.recyclerView.adapter = adapter
adapter.addHeaderView { adapter.addHeaderView {

@ -26,18 +26,18 @@ fun AppCompatActivity.showDialogFragment(dialogFragment: DialogFragment) {
dialogFragment.show(supportFragmentManager, dialogFragment::class.simpleName) dialogFragment.show(supportFragmentManager, dialogFragment::class.simpleName)
} }
val Activity.windowSize: DisplayMetrics val WindowManager.windowSize: DisplayMetrics
get() { get() {
val displayMetrics = DisplayMetrics() val displayMetrics = DisplayMetrics()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
val windowMetrics: WindowMetrics = windowManager.currentWindowMetrics val windowMetrics: WindowMetrics = currentWindowMetrics
val insets = windowMetrics.windowInsets val insets = windowMetrics.windowInsets
.getInsetsIgnoringVisibility(WindowInsets.Type.systemBars()) .getInsetsIgnoringVisibility(WindowInsets.Type.systemBars())
displayMetrics.widthPixels = windowMetrics.bounds.width() - insets.left - insets.right displayMetrics.widthPixels = windowMetrics.bounds.width() - insets.left - insets.right
displayMetrics.heightPixels = windowMetrics.bounds.height() - insets.top - insets.bottom displayMetrics.heightPixels = windowMetrics.bounds.height() - insets.top - insets.bottom
} else { } else {
@Suppress("DEPRECATION") @Suppress("DEPRECATION")
windowManager.defaultDisplay.getMetrics(displayMetrics) defaultDisplay.getMetrics(displayMetrics)
} }
return displayMetrics return displayMetrics
} }

@ -30,7 +30,7 @@ fun AlertDialog.requestInputMethod() {
} }
fun DialogFragment.setLayout(widthMix: Float, heightMix: Float) { fun DialogFragment.setLayout(widthMix: Float, heightMix: Float) {
val dm = requireActivity().windowSize val dm = requireActivity().windowManager.windowSize
dialog?.window?.setLayout( dialog?.window?.setLayout(
(dm.widthPixels * widthMix).toInt(), (dm.widthPixels * widthMix).toInt(),
(dm.heightPixels * heightMix).toInt() (dm.heightPixels * heightMix).toInt()
@ -38,7 +38,7 @@ fun DialogFragment.setLayout(widthMix: Float, heightMix: Float) {
} }
fun DialogFragment.setLayout(width: Int, heightMix: Float) { fun DialogFragment.setLayout(width: Int, heightMix: Float) {
val dm = requireActivity().windowSize val dm = requireActivity().windowManager.windowSize
dialog?.window?.setLayout( dialog?.window?.setLayout(
width, width,
(dm.heightPixels * heightMix).toInt() (dm.heightPixels * heightMix).toInt()
@ -46,7 +46,7 @@ fun DialogFragment.setLayout(width: Int, heightMix: Float) {
} }
fun DialogFragment.setLayout(widthMix: Float, height: Int) { fun DialogFragment.setLayout(widthMix: Float, height: Int) {
val dm = requireActivity().windowSize val dm = requireActivity().windowManager.windowSize
dialog?.window?.setLayout( dialog?.window?.setLayout(
(dm.widthPixels * widthMix).toInt(), (dm.widthPixels * widthMix).toInt(),
height height

Loading…
Cancel
Save