Horis 2 tahun lalu
induk
melakukan
95a837431b

+ 2 - 8
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.view.MenuItem
 import android.widget.SeekBar
 import android.widget.SeekBar
 import androidx.activity.viewModels
 import androidx.activity.viewModels
-import androidx.core.view.ViewCompat
-import androidx.core.view.WindowInsetsCompat
 import androidx.lifecycle.lifecycleScope
 import androidx.lifecycle.lifecycleScope
 import io.legado.app.R
 import io.legado.app.R
 import io.legado.app.base.VMBaseActivity
 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.login.SourceLoginActivity
 import io.legado.app.ui.widget.seekbar.SeekBarChangeListener
 import io.legado.app.ui.widget.seekbar.SeekBarChangeListener
 import io.legado.app.utils.StartActivityContract
 import io.legado.app.utils.StartActivityContract
+import io.legado.app.utils.applyNavigationBarPadding
 import io.legado.app.utils.dpToPx
 import io.legado.app.utils.dpToPx
 import io.legado.app.utils.invisible
 import io.legado.app.utils.invisible
 import io.legado.app.utils.observeEvent
 import io.legado.app.utils.observeEvent
@@ -51,7 +50,6 @@ import io.legado.app.utils.visible
 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.views.bottomPadding
 import splitties.views.onLongClick
 import splitties.views.onLongClick
 import java.util.Locale
 import java.util.Locale
 
 
@@ -187,11 +185,7 @@ class AudioPlayActivity :
         binding.ivTimer.setOnClickListener {
         binding.ivTimer.setOnClickListener {
             timerSliderPopup.showAsDropDown(it, 0, (-100).dpToPx(), Gravity.TOP)
             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?) {
     private fun upCover(path: String?) {

+ 5 - 6
app/src/main/java/io/legado/app/ui/book/explore/ExploreShowActivity.kt

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

+ 2 - 8
app/src/main/java/io/legado/app/ui/book/info/BookInfoActivity.kt

@@ -10,8 +10,6 @@ import android.widget.CheckBox
 import android.widget.LinearLayout
 import android.widget.LinearLayout
 import androidx.activity.result.contract.ActivityResultContracts
 import androidx.activity.result.contract.ActivityResultContracts
 import androidx.activity.viewModels
 import androidx.activity.viewModels
-import androidx.core.view.ViewCompat
-import androidx.core.view.WindowInsetsCompat
 import androidx.lifecycle.lifecycleScope
 import androidx.lifecycle.lifecycleScope
 import io.legado.app.R
 import io.legado.app.R
 import io.legado.app.base.VMBaseActivity
 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.ColorUtils
 import io.legado.app.utils.GSON
 import io.legado.app.utils.GSON
 import io.legado.app.utils.StartActivityContract
 import io.legado.app.utils.StartActivityContract
+import io.legado.app.utils.applyNavigationBarPadding
 import io.legado.app.utils.dpToPx
 import io.legado.app.utils.dpToPx
 import io.legado.app.utils.gone
 import io.legado.app.utils.gone
 import io.legado.app.utils.longToastOnUi
 import io.legado.app.utils.longToastOnUi
@@ -74,7 +73,6 @@ import io.legado.app.utils.visible
 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.views.bottomPadding
 
 
 class BookInfoActivity :
 class BookInfoActivity :
     VMBaseActivity<ActivityBookInfoBinding, BookInfoViewModel>(toolBarTheme = Theme.Dark),
     VMBaseActivity<ActivityBookInfoBinding, BookInfoViewModel>(toolBarTheme = Theme.Dark),
@@ -157,6 +155,7 @@ class BookInfoActivity :
         binding.arcView.setBgColor(backgroundColor)
         binding.arcView.setBgColor(backgroundColor)
         binding.llInfo.setBackgroundColor(backgroundColor)
         binding.llInfo.setBackgroundColor(backgroundColor)
         binding.flAction.setBackgroundColor(bottomBackground)
         binding.flAction.setBackgroundColor(bottomBackground)
+        binding.flAction.applyNavigationBarPadding()
         binding.tvShelf.setTextColor(getPrimaryTextColor(ColorUtils.isColorLight(bottomBackground)))
         binding.tvShelf.setTextColor(getPrimaryTextColor(ColorUtils.isColorLight(bottomBackground)))
         binding.tvToc.text = getString(R.string.toc_s, getString(R.string.loading))
         binding.tvToc.text = getString(R.string.toc_s, getString(R.string.loading))
         viewModel.bookData.observe(this) { showBook(it) }
         viewModel.bookData.observe(this) { showBook(it) }
@@ -164,11 +163,6 @@ class BookInfoActivity :
         viewModel.waitDialogData.observe(this) { upWaitDialogStatus(it) }
         viewModel.waitDialogData.observe(this) { upWaitDialogStatus(it) }
         viewModel.initData(intent)
         viewModel.initData(intent)
         initViewEvent()
         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 {
     override fun onCompatCreateOptionsMenu(menu: Menu): Boolean {

+ 2 - 8
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.FrameLayout
 import android.widget.SeekBar
 import android.widget.SeekBar
 import androidx.appcompat.widget.PopupMenu
 import androidx.appcompat.widget.PopupMenu
-import androidx.core.view.ViewCompat
-import androidx.core.view.WindowInsetsCompat
 import androidx.core.view.isGone
 import androidx.core.view.isGone
 import androidx.core.view.isVisible
 import androidx.core.view.isVisible
 import io.legado.app.R
 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.ColorUtils
 import io.legado.app.utils.ConstraintModify
 import io.legado.app.utils.ConstraintModify
 import io.legado.app.utils.activity
 import io.legado.app.utils.activity
+import io.legado.app.utils.applyNavigationBarPadding
 import io.legado.app.utils.dpToPx
 import io.legado.app.utils.dpToPx
 import io.legado.app.utils.getPrefBoolean
 import io.legado.app.utils.getPrefBoolean
 import io.legado.app.utils.gone
 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.putPrefBoolean
 import io.legado.app.utils.startActivity
 import io.legado.app.utils.startActivity
 import io.legado.app.utils.visible
 import io.legado.app.utils.visible
-import splitties.views.bottomPadding
 import splitties.views.onClick
 import splitties.views.onClick
 import splitties.views.onLongClick
 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() {
     fun reset() {

+ 2 - 8
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.view.LayoutInflater
 import android.widget.FrameLayout
 import android.widget.FrameLayout
 import androidx.core.content.ContextCompat
 import androidx.core.content.ContextCompat
-import androidx.core.view.ViewCompat
-import androidx.core.view.WindowInsetsCompat
 import androidx.core.view.isGone
 import androidx.core.view.isGone
 import androidx.core.view.isInvisible
 import androidx.core.view.isInvisible
 import io.legado.app.R
 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.book.read.page.provider.ChapterProvider
 import io.legado.app.ui.widget.BatteryView
 import io.legado.app.ui.widget.BatteryView
 import io.legado.app.utils.activity
 import io.legado.app.utils.activity
+import io.legado.app.utils.applyStatusBarPadding
 import io.legado.app.utils.dpToPx
 import io.legado.app.utils.dpToPx
 import io.legado.app.utils.gone
 import io.legado.app.utils.gone
 import io.legado.app.utils.setTextIfNotEqual
 import io.legado.app.utils.setTextIfNotEqual
 import splitties.views.backgroundColor
 import splitties.views.backgroundColor
-import splitties.views.topPadding
 import java.util.Date
 import java.util.Date
 
 
 /**
 /**
@@ -62,11 +60,7 @@ class PageView(context: Context) : FrameLayout(context) {
     init {
     init {
         if (!isInEditMode) {
         if (!isInEditMode) {
             upStyle()
             upStyle()
-            ViewCompat.setOnApplyWindowInsetsListener(this) { _, windowInsets ->
-                val insets = windowInsets.getInsets(WindowInsetsCompat.Type.statusBars())
-                binding.vwStatusBar.topPadding = insets.top
-                windowInsets
-            }
+            binding.vwStatusBar.applyStatusBarPadding()
         }
         }
     }
     }
 
 

+ 4 - 40
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.GridLayoutManager
 import androidx.recyclerview.widget.LinearLayoutManager
 import androidx.recyclerview.widget.LinearLayoutManager
 import androidx.recyclerview.widget.RecyclerView
 import androidx.recyclerview.widget.RecyclerView
+import androidx.recyclerview.widget.RecyclerView.Adapter.StateRestorationPolicy
 import io.legado.app.R
 import io.legado.app.R
 import io.legado.app.base.BaseFragment
 import io.legado.app.base.BaseFragment
 import io.legado.app.constant.AppLog
 import io.legado.app.constant.AppLog
@@ -72,7 +73,6 @@ class BooksFragment() : BaseFragment(R.layout.fragment_books),
         }
         }
     }
     }
     private var booksFlowJob: Job? = null
     private var booksFlowJob: Job? = null
-    private var savedInstanceState: Bundle? = null
     var position = 0
     var position = 0
         private set
         private set
     var groupId = -1L
     var groupId = -1L
@@ -83,7 +83,6 @@ class BooksFragment() : BaseFragment(R.layout.fragment_books),
     private var enableRefresh = true
     private var enableRefresh = true
 
 
     override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) {
     override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) {
-        this.savedInstanceState = savedInstanceState
         arguments?.let {
         arguments?.let {
             position = it.getInt("position", 0)
             position = it.getInt("position", 0)
             groupId = it.getLong("groupId", -1)
             groupId = it.getLong("groupId", -1)
@@ -113,11 +112,12 @@ class BooksFragment() : BaseFragment(R.layout.fragment_books),
         } else {
         } else {
             binding.rvBookshelf.setRecycledViewPool(activityViewModel.booksGridRecycledViewPool)
             binding.rvBookshelf.setRecycledViewPool(activityViewModel.booksGridRecycledViewPool)
         }
         }
+        booksAdapter.stateRestorationPolicy = StateRestorationPolicy.PREVENT_WHEN_EMPTY
         binding.rvBookshelf.adapter = booksAdapter
         binding.rvBookshelf.adapter = booksAdapter
         booksAdapter.registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() {
         booksAdapter.registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() {
             override fun onItemRangeInserted(positionStart: Int, itemCount: Int) {
             override fun onItemRangeInserted(positionStart: Int, itemCount: Int) {
                 val layoutManager = binding.rvBookshelf.layoutManager
                 val layoutManager = binding.rvBookshelf.layoutManager
-                if (positionStart == 0 && layoutManager is LinearLayoutManager) {
+                if (positionStart == 0 && itemCount == 1 && layoutManager is LinearLayoutManager) {
                     val scrollTo = layoutManager.findFirstVisibleItemPosition() - itemCount
                     val scrollTo = layoutManager.findFirstVisibleItemPosition() - itemCount
                     binding.rvBookshelf.scrollToPosition(max(0, scrollTo))
                     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) {
             override fun onItemRangeMoved(fromPosition: Int, toPosition: Int, itemCount: Int) {
                 val layoutManager = binding.rvBookshelf.layoutManager
                 val layoutManager = binding.rvBookshelf.layoutManager
-                if (toPosition == 0 && layoutManager is LinearLayoutManager) {
+                if (toPosition == 0 && itemCount == 1 && layoutManager is LinearLayoutManager) {
                     val scrollTo = layoutManager.findFirstVisibleItemPosition() - itemCount
                     val scrollTo = layoutManager.findFirstVisibleItemPosition() - itemCount
                     binding.rvBookshelf.scrollToPosition(max(0, scrollTo))
                     binding.rvBookshelf.scrollToPosition(max(0, scrollTo))
                 }
                 }
@@ -191,25 +191,11 @@ class BooksFragment() : BaseFragment(R.layout.fragment_books),
                 binding.tvEmptyMsg.isGone = list.isNotEmpty()
                 binding.tvEmptyMsg.isGone = list.isNotEmpty()
                 binding.refreshLayout.isEnabled = enableRefresh && list.isNotEmpty()
                 binding.refreshLayout.isEnabled = enableRefresh && list.isNotEmpty()
                 booksAdapter.setItems(list)
                 booksAdapter.setItems(list)
-                recoverPositionState()
                 delay(100)
                 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() {
     private fun startLastUpdateTimeJob() {
         upLastUpdateTimeJob?.cancel()
         upLastUpdateTimeJob?.cancel()
         if (!AppConfig.showLastUpdateTime) {
         if (!AppConfig.showLastUpdateTime) {
@@ -241,28 +227,6 @@ class BooksFragment() : BaseFragment(R.layout.fragment_books),
         return booksAdapter.itemCount
         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() {
     override fun onDestroyView() {
         super.onDestroyView()
         super.onDestroyView()
         /**
         /**

+ 2 - 9
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.MenuRes
 import androidx.annotation.StringRes
 import androidx.annotation.StringRes
 import androidx.appcompat.widget.PopupMenu
 import androidx.appcompat.widget.PopupMenu
-import androidx.core.view.ViewCompat
-import androidx.core.view.WindowInsetsCompat
 import io.legado.app.R
 import io.legado.app.R
 import io.legado.app.databinding.ViewSelectActionBarBinding
 import io.legado.app.databinding.ViewSelectActionBarBinding
 import io.legado.app.lib.theme.TintHelper
 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.getPrimaryTextColor
 import io.legado.app.lib.theme.getSecondaryDisabledTextColor
 import io.legado.app.lib.theme.getSecondaryDisabledTextColor
 import io.legado.app.utils.ColorUtils
 import io.legado.app.utils.ColorUtils
+import io.legado.app.utils.applyNavigationBarPadding
 import io.legado.app.utils.visible
 import io.legado.app.utils.visible
-import splitties.views.bottomPadding
 
 
 
 
 @Suppress("unused")
 @Suppress("unused")
@@ -54,12 +52,7 @@ class SelectActionBar @JvmOverloads constructor(
             binding.btnRevertSelection.setOnClickListener { callBack?.revertSelection() }
             binding.btnRevertSelection.setOnClickListener { callBack?.revertSelection() }
             binding.btnSelectActionMain.setOnClickListener { callBack?.onClickSelectBarMainAction() }
             binding.btnSelectActionMain.setOnClickListener { callBack?.onClickSelectBarMainAction() }
             binding.ivMenuMore.setOnClickListener { selMenu?.show() }
             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()
         }
         }
     }
     }
 
 

+ 22 - 0
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.appcompat.widget.PopupMenu
 import androidx.core.graphics.record
 import androidx.core.graphics.record
 import androidx.core.graphics.withTranslation
 import androidx.core.graphics.withTranslation
+import androidx.core.view.ViewCompat
+import androidx.core.view.WindowInsetsCompat
 import androidx.core.view.get
 import androidx.core.view.get
 import androidx.recyclerview.widget.RecyclerView
 import androidx.recyclerview.widget.RecyclerView
 import androidx.viewpager.widget.ViewPager
 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.CanvasRecorder
 import io.legado.app.utils.canvasrecorder.record
 import io.legado.app.utils.canvasrecorder.record
 import splitties.systemservices.inputMethodManager
 import splitties.systemservices.inputMethodManager
+import splitties.views.bottomPadding
+import splitties.views.topPadding
 import java.lang.reflect.Field
 import java.lang.reflect.Field
 
 
 
 
@@ -255,3 +259,21 @@ fun View.shouldHideSoftInput(event: MotionEvent): Boolean {
     }
     }
     return false
     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
+    }
+}