diff --git a/app/src/main/java/io/legado/app/ui/book/audio/AudioPlayActivity.kt b/app/src/main/java/io/legado/app/ui/book/audio/AudioPlayActivity.kt index 9bbf98186..e40b92bf2 100644 --- a/app/src/main/java/io/legado/app/ui/book/audio/AudioPlayActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/audio/AudioPlayActivity.kt @@ -10,8 +10,6 @@ import android.view.Menu import android.view.MenuItem import android.widget.SeekBar import androidx.activity.viewModels -import androidx.core.view.ViewCompat -import androidx.core.view.WindowInsetsCompat import androidx.lifecycle.lifecycleScope import io.legado.app.R import io.legado.app.base.VMBaseActivity @@ -39,6 +37,7 @@ import io.legado.app.ui.book.toc.TocActivityResult import io.legado.app.ui.login.SourceLoginActivity import io.legado.app.ui.widget.seekbar.SeekBarChangeListener import io.legado.app.utils.StartActivityContract +import io.legado.app.utils.applyNavigationBarPadding import io.legado.app.utils.dpToPx import io.legado.app.utils.invisible import io.legado.app.utils.observeEvent @@ -51,7 +50,6 @@ import io.legado.app.utils.visible import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.launch import kotlinx.coroutines.withContext -import splitties.views.bottomPadding import splitties.views.onLongClick import java.util.Locale @@ -187,11 +185,7 @@ class AudioPlayActivity : binding.ivTimer.setOnClickListener { timerSliderPopup.showAsDropDown(it, 0, (-100).dpToPx(), Gravity.TOP) } - ViewCompat.setOnApplyWindowInsetsListener(binding.llPlayMenu) { _, windowInsets -> - val insets = windowInsets.getInsets(WindowInsetsCompat.Type.navigationBars()) - binding.llPlayMenu.bottomPadding = insets.bottom - windowInsets - } + binding.llPlayMenu.applyNavigationBarPadding() } private fun upCover(path: String?) { diff --git a/app/src/main/java/io/legado/app/ui/book/explore/ExploreShowActivity.kt b/app/src/main/java/io/legado/app/ui/book/explore/ExploreShowActivity.kt index 735adc355..62d513944 100644 --- a/app/src/main/java/io/legado/app/ui/book/explore/ExploreShowActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/explore/ExploreShowActivity.kt @@ -49,8 +49,7 @@ class ExploreShowActivity : VMBaseActivity(toolBarTheme = Theme.Dark), @@ -157,6 +155,7 @@ class BookInfoActivity : binding.arcView.setBgColor(backgroundColor) binding.llInfo.setBackgroundColor(backgroundColor) binding.flAction.setBackgroundColor(bottomBackground) + binding.flAction.applyNavigationBarPadding() binding.tvShelf.setTextColor(getPrimaryTextColor(ColorUtils.isColorLight(bottomBackground))) binding.tvToc.text = getString(R.string.toc_s, getString(R.string.loading)) viewModel.bookData.observe(this) { showBook(it) } @@ -164,11 +163,6 @@ class BookInfoActivity : viewModel.waitDialogData.observe(this) { upWaitDialogStatus(it) } viewModel.initData(intent) initViewEvent() - ViewCompat.setOnApplyWindowInsetsListener(binding.flAction) { _, windowInsets -> - val insets = windowInsets.getInsets(WindowInsetsCompat.Type.navigationBars()) - binding.flAction.bottomPadding = insets.bottom - windowInsets - } } override fun onCompatCreateOptionsMenu(menu: Menu): Boolean { diff --git a/app/src/main/java/io/legado/app/ui/book/read/ReadMenu.kt b/app/src/main/java/io/legado/app/ui/book/read/ReadMenu.kt index 36644c37d..75395062d 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/ReadMenu.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/ReadMenu.kt @@ -15,8 +15,6 @@ import android.view.animation.Animation import android.widget.FrameLayout import android.widget.SeekBar import androidx.appcompat.widget.PopupMenu -import androidx.core.view.ViewCompat -import androidx.core.view.WindowInsetsCompat import androidx.core.view.isGone import androidx.core.view.isVisible import io.legado.app.R @@ -41,6 +39,7 @@ import io.legado.app.ui.widget.seekbar.SeekBarChangeListener import io.legado.app.utils.ColorUtils import io.legado.app.utils.ConstraintModify import io.legado.app.utils.activity +import io.legado.app.utils.applyNavigationBarPadding import io.legado.app.utils.dpToPx import io.legado.app.utils.getPrefBoolean import io.legado.app.utils.gone @@ -51,7 +50,6 @@ import io.legado.app.utils.openUrl import io.legado.app.utils.putPrefBoolean import io.legado.app.utils.startActivity import io.legado.app.utils.visible -import splitties.views.bottomPadding import splitties.views.onClick import splitties.views.onLongClick @@ -235,11 +233,7 @@ class ReadMenu @JvmOverloads constructor( /** * 确保视图不被导航栏遮挡 */ - ViewCompat.setOnApplyWindowInsetsListener(this@ReadMenu) { _, windowInsets -> - val insets = windowInsets.getInsets(WindowInsetsCompat.Type.navigationBars()) - root.bottomPadding = insets.bottom - windowInsets - } + applyNavigationBarPadding() } fun reset() { diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/PageView.kt b/app/src/main/java/io/legado/app/ui/book/read/page/PageView.kt index 05e07bebd..fdafca43d 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/page/PageView.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/PageView.kt @@ -5,8 +5,6 @@ import android.content.Context import android.view.LayoutInflater import android.widget.FrameLayout import androidx.core.content.ContextCompat -import androidx.core.view.ViewCompat -import androidx.core.view.WindowInsetsCompat import androidx.core.view.isGone import androidx.core.view.isInvisible import io.legado.app.R @@ -23,11 +21,11 @@ import io.legado.app.ui.book.read.page.entities.TextPos import io.legado.app.ui.book.read.page.provider.ChapterProvider import io.legado.app.ui.widget.BatteryView import io.legado.app.utils.activity +import io.legado.app.utils.applyStatusBarPadding import io.legado.app.utils.dpToPx import io.legado.app.utils.gone import io.legado.app.utils.setTextIfNotEqual import splitties.views.backgroundColor -import splitties.views.topPadding import java.util.Date /** @@ -62,11 +60,7 @@ class PageView(context: Context) : FrameLayout(context) { init { if (!isInEditMode) { upStyle() - ViewCompat.setOnApplyWindowInsetsListener(this) { _, windowInsets -> - val insets = windowInsets.getInsets(WindowInsetsCompat.Type.statusBars()) - binding.vwStatusBar.topPadding = insets.top - windowInsets - } + binding.vwStatusBar.applyStatusBarPadding() } } diff --git a/app/src/main/java/io/legado/app/ui/main/bookshelf/style1/books/BooksFragment.kt b/app/src/main/java/io/legado/app/ui/main/bookshelf/style1/books/BooksFragment.kt index 467a08d4e..847f6a83c 100644 --- a/app/src/main/java/io/legado/app/ui/main/bookshelf/style1/books/BooksFragment.kt +++ b/app/src/main/java/io/legado/app/ui/main/bookshelf/style1/books/BooksFragment.kt @@ -12,6 +12,7 @@ import androidx.lifecycle.repeatOnLifecycle import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView +import androidx.recyclerview.widget.RecyclerView.Adapter.StateRestorationPolicy import io.legado.app.R import io.legado.app.base.BaseFragment import io.legado.app.constant.AppLog @@ -72,7 +73,6 @@ class BooksFragment() : BaseFragment(R.layout.fragment_books), } } private var booksFlowJob: Job? = null - private var savedInstanceState: Bundle? = null var position = 0 private set var groupId = -1L @@ -83,7 +83,6 @@ class BooksFragment() : BaseFragment(R.layout.fragment_books), private var enableRefresh = true override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) { - this.savedInstanceState = savedInstanceState arguments?.let { position = it.getInt("position", 0) groupId = it.getLong("groupId", -1) @@ -113,11 +112,12 @@ class BooksFragment() : BaseFragment(R.layout.fragment_books), } else { binding.rvBookshelf.setRecycledViewPool(activityViewModel.booksGridRecycledViewPool) } + booksAdapter.stateRestorationPolicy = StateRestorationPolicy.PREVENT_WHEN_EMPTY binding.rvBookshelf.adapter = booksAdapter booksAdapter.registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() { override fun onItemRangeInserted(positionStart: Int, itemCount: Int) { val layoutManager = binding.rvBookshelf.layoutManager - if (positionStart == 0 && layoutManager is LinearLayoutManager) { + if (positionStart == 0 && itemCount == 1 && layoutManager is LinearLayoutManager) { val scrollTo = layoutManager.findFirstVisibleItemPosition() - itemCount binding.rvBookshelf.scrollToPosition(max(0, scrollTo)) } @@ -125,7 +125,7 @@ class BooksFragment() : BaseFragment(R.layout.fragment_books), override fun onItemRangeMoved(fromPosition: Int, toPosition: Int, itemCount: Int) { val layoutManager = binding.rvBookshelf.layoutManager - if (toPosition == 0 && layoutManager is LinearLayoutManager) { + if (toPosition == 0 && itemCount == 1 && layoutManager is LinearLayoutManager) { val scrollTo = layoutManager.findFirstVisibleItemPosition() - itemCount binding.rvBookshelf.scrollToPosition(max(0, scrollTo)) } @@ -191,25 +191,11 @@ class BooksFragment() : BaseFragment(R.layout.fragment_books), binding.tvEmptyMsg.isGone = list.isNotEmpty() binding.refreshLayout.isEnabled = enableRefresh && list.isNotEmpty() booksAdapter.setItems(list) - recoverPositionState() delay(100) } } } - private fun recoverPositionState() { - // 恢复书架位置状态 - if (savedInstanceState?.getBoolean("needRecoverState") == true) { - val layoutManager = binding.rvBookshelf.layoutManager - if (layoutManager is LinearLayoutManager) { - val leavePosition = savedInstanceState!!.getInt("leavePosition") - val leaveOffset = savedInstanceState!!.getInt("leaveOffset") - layoutManager.scrollToPositionWithOffset(leavePosition, leaveOffset) - } - savedInstanceState!!.putBoolean("needRecoverState", false) - } - } - private fun startLastUpdateTimeJob() { upLastUpdateTimeJob?.cancel() if (!AppConfig.showLastUpdateTime) { @@ -241,28 +227,6 @@ class BooksFragment() : BaseFragment(R.layout.fragment_books), return booksAdapter.itemCount } - override fun onSaveInstanceState(outState: Bundle) { - super.onSaveInstanceState(outState) - // 保存书架位置状态 - val layoutManager = binding.rvBookshelf.layoutManager - if (layoutManager is LinearLayoutManager) { - val itemPosition = layoutManager.findFirstVisibleItemPosition() - val currentView = layoutManager.findViewByPosition(itemPosition) - val viewOffset = currentView?.top - if (viewOffset != null) { - outState.putInt("leavePosition", itemPosition) - outState.putInt("leaveOffset", viewOffset) - outState.putBoolean("needRecoverState", true) - } else if (savedInstanceState != null) { - val leavePosition = savedInstanceState!!.getInt("leavePosition") - val leaveOffset = savedInstanceState!!.getInt("leaveOffset") - outState.putInt("leavePosition", leavePosition) - outState.putInt("leaveOffset", leaveOffset) - outState.putBoolean("needRecoverState", true) - } - } - } - override fun onDestroyView() { super.onDestroyView() /** diff --git a/app/src/main/java/io/legado/app/ui/widget/SelectActionBar.kt b/app/src/main/java/io/legado/app/ui/widget/SelectActionBar.kt index 07c1990ea..e44c662e2 100644 --- a/app/src/main/java/io/legado/app/ui/widget/SelectActionBar.kt +++ b/app/src/main/java/io/legado/app/ui/widget/SelectActionBar.kt @@ -9,8 +9,6 @@ import android.widget.FrameLayout import androidx.annotation.MenuRes import androidx.annotation.StringRes import androidx.appcompat.widget.PopupMenu -import androidx.core.view.ViewCompat -import androidx.core.view.WindowInsetsCompat import io.legado.app.R import io.legado.app.databinding.ViewSelectActionBarBinding import io.legado.app.lib.theme.TintHelper @@ -20,8 +18,8 @@ import io.legado.app.lib.theme.elevation import io.legado.app.lib.theme.getPrimaryTextColor import io.legado.app.lib.theme.getSecondaryDisabledTextColor import io.legado.app.utils.ColorUtils +import io.legado.app.utils.applyNavigationBarPadding import io.legado.app.utils.visible -import splitties.views.bottomPadding @Suppress("unused") @@ -54,12 +52,7 @@ class SelectActionBar @JvmOverloads constructor( binding.btnRevertSelection.setOnClickListener { callBack?.revertSelection() } binding.btnSelectActionMain.setOnClickListener { callBack?.onClickSelectBarMainAction() } binding.ivMenuMore.setOnClickListener { selMenu?.show() } - val initialBottomPadding = binding.root.paddingBottom - ViewCompat.setOnApplyWindowInsetsListener(this) { _, windowInsets -> - val insets = windowInsets.getInsets(WindowInsetsCompat.Type.navigationBars()) - binding.root.bottomPadding = initialBottomPadding + insets.bottom - windowInsets - } + applyNavigationBarPadding() } } diff --git a/app/src/main/java/io/legado/app/utils/ViewExtensions.kt b/app/src/main/java/io/legado/app/utils/ViewExtensions.kt index 5c2e9d7ac..17984c762 100644 --- a/app/src/main/java/io/legado/app/utils/ViewExtensions.kt +++ b/app/src/main/java/io/legado/app/utils/ViewExtensions.kt @@ -28,6 +28,8 @@ import androidx.appcompat.view.menu.MenuPopupHelper import androidx.appcompat.widget.PopupMenu import androidx.core.graphics.record import androidx.core.graphics.withTranslation +import androidx.core.view.ViewCompat +import androidx.core.view.WindowInsetsCompat import androidx.core.view.get import androidx.recyclerview.widget.RecyclerView import androidx.viewpager.widget.ViewPager @@ -36,6 +38,8 @@ import io.legado.app.lib.theme.TintHelper import io.legado.app.utils.canvasrecorder.CanvasRecorder import io.legado.app.utils.canvasrecorder.record import splitties.systemservices.inputMethodManager +import splitties.views.bottomPadding +import splitties.views.topPadding import java.lang.reflect.Field @@ -255,3 +259,21 @@ fun View.shouldHideSoftInput(event: MotionEvent): Boolean { } return false } + +fun View.applyStatusBarPadding(withInitialPadding: Boolean = false) { + val initialPadding = if (withInitialPadding) topPadding else 0 + ViewCompat.setOnApplyWindowInsetsListener(this) { _, windowInsets -> + val insets = windowInsets.getInsets(WindowInsetsCompat.Type.statusBars()) + topPadding = initialPadding + insets.top + windowInsets + } +} + +fun View.applyNavigationBarPadding(withInitialPadding: Boolean = false) { + val initialPadding = if (withInitialPadding) bottomPadding else 0 + ViewCompat.setOnApplyWindowInsetsListener(this) { _, windowInsets -> + val insets = windowInsets.getInsets(WindowInsetsCompat.Type.navigationBars()) + bottomPadding = initialPadding + insets.bottom + windowInsets + } +}