This commit is contained in:
Horis
2024-09-01 10:45:43 +08:00
parent 30ec23390a
commit dde4af4517
8 changed files with 41 additions and 87 deletions

View File

@@ -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?) {

View File

@@ -49,8 +49,7 @@ class ExploreShowActivity : VMBaseActivity<ActivityExploreShowBinding, ExploreSh
loadMoreView.startLoad()
loadMoreView.setOnClickListener {
if (!loadMoreView.isLoading) {
loadMoreView.hasMore()
scrollToBottom()
scrollToBottom(true)
}
}
binding.recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
@@ -63,9 +62,9 @@ class ExploreShowActivity : VMBaseActivity<ActivityExploreShowBinding, ExploreSh
})
}
private fun scrollToBottom() {
if (loadMoreView.hasMore && !loadMoreView.isLoading) {
loadMoreView.startLoad()
private fun scrollToBottom(forceLoad: Boolean = false) {
if ((loadMoreView.hasMore && !loadMoreView.isLoading) || forceLoad) {
loadMoreView.hasMore()
viewModel.explore()
}
}
@@ -74,7 +73,7 @@ class ExploreShowActivity : VMBaseActivity<ActivityExploreShowBinding, ExploreSh
loadMoreView.stopLoad()
if (books.isEmpty() && adapter.isEmpty()) {
loadMoreView.noMore(getString(R.string.empty))
} else if (adapter.itemCount == books.size) {
} else if (adapter.getActualItemCount() == books.size) {
loadMoreView.noMore()
} else {
adapter.setItems(books)

View File

@@ -10,8 +10,6 @@ import android.widget.CheckBox
import android.widget.LinearLayout
import androidx.activity.result.contract.ActivityResultContracts
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
@@ -60,6 +58,7 @@ import io.legado.app.ui.widget.dialog.WaitDialog
import io.legado.app.utils.ColorUtils
import io.legado.app.utils.GSON
import io.legado.app.utils.StartActivityContract
import io.legado.app.utils.applyNavigationBarPadding
import io.legado.app.utils.dpToPx
import io.legado.app.utils.gone
import io.legado.app.utils.longToastOnUi
@@ -74,7 +73,6 @@ import io.legado.app.utils.visible
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import splitties.views.bottomPadding
class BookInfoActivity :
VMBaseActivity<ActivityBookInfoBinding, BookInfoViewModel>(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 {

View File

@@ -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() {

View File

@@ -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()
}
}

View File

@@ -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()
/**

View File

@@ -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()
}
}

View File

@@ -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
}
}