From 0981ba771ae328beadaec599131414147a26b55d Mon Sep 17 00:00:00 2001 From: Koitharu Date: Sat, 8 Mar 2025 09:57:23 +0200 Subject: [PATCH] Improve window insets handling --- .../alternatives/ui/AlternativesActivity.kt | 25 ++++++- .../bookmarks/ui/AllBookmarksFragment.kt | 18 ++++- .../kotatsu/browser/BrowserActivity.kt | 26 ++++++- .../browser/cloudflare/CloudFlareActivity.kt | 26 ++++++- .../koitharu/kotatsu/core/ui/BaseActivity.kt | 18 ++--- .../koitharu/kotatsu/core/ui/BaseFragment.kt | 4 ++ .../kotatsu/core/ui/BasePreferenceFragment.kt | 38 ++++++----- .../core/ui/FragmentContainerActivity.kt | 7 +- .../core/ui/sheet/BaseAdaptiveSheet.kt | 7 +- .../core/ui/util/InsetsToMarginsListener.kt | 51 -------------- .../core/ui/util/InsetsToPaddingListener.kt | 61 ----------------- .../core/ui/widgets/WindowInsetHolder.kt | 8 ++- .../kotatsu/core/util/ext/Fragment.kt | 7 ++ .../koitharu/kotatsu/core/util/ext/Insets.kt | 67 ++++++++++++++++--- .../koitharu/kotatsu/core/util/ext/View.kt | 21 ------ .../kotatsu/details/ui/DetailsActivity.kt | 28 ++++---- .../details/ui/DetailsBottomSheetCallback.kt | 3 +- .../details/ui/pager/ChaptersPagesSheet.kt | 8 +++ .../ui/pager/bookmarks/BookmarksFragment.kt | 17 ++++- .../ui/pager/chapters/ChaptersFragment.kt | 4 -- .../details/ui/pager/pages/PagesFragment.kt | 17 ++++- .../ui/scrobbling/ScrobblingInfoSheet.kt | 12 ++++ .../download/ui/list/DownloadsActivity.kt | 4 -- .../kotatsu/explore/ui/ExploreFragment.kt | 18 ++++- .../categories/FavouriteCategoriesActivity.kt | 32 ++++++++- .../edit/FavouritesCategoryEditActivity.kt | 17 +++++ .../container/FavouritesContainerFragment.kt | 3 + .../kotatsu/filter/ui/FilterHeaderFragment.kt | 4 ++ .../filter/ui/sheet/FilterSheetFragment.kt | 10 +++ .../filter/ui/tags/TagsCatalogSheet.kt | 14 ++++ .../kotatsu/image/ui/ImageActivity.kt | 19 +++--- .../kotatsu/list/ui/MangaListFragment.kt | 18 ++++- .../list/ui/config/ListConfigBottomSheet.kt | 11 +++ .../list/ui/preview/PreviewFragment.kt | 3 + .../koitharu/kotatsu/main/ui/MainActivity.kt | 26 +++---- .../kotatsu/main/ui/MainNavigationDelegate.kt | 45 ++++++++----- .../main/ui/protect/ProtectActivity.kt | 18 ++++- .../kotatsu/main/ui/welcome/WelcomeSheet.kt | 11 +++ .../kotatsu/reader/ui/ReaderActivity.kt | 16 ++--- .../colorfilter/ColorFilterConfigActivity.kt | 20 +++++- .../reader/ui/config/ReaderConfigSheet.kt | 11 +++ .../reader/ui/pager/BaseReaderFragment.kt | 4 ++ .../ui/config/ScrobblerConfigActivity.kt | 24 ++++++- .../ui/selector/ScrobblingSelectorSheet.kt | 12 ++++ .../scrobbling/kitsu/ui/KitsuAuthActivity.kt | 21 +++++- .../kotatsu/search/ui/MangaListActivity.kt | 18 +---- .../kotatsu/search/ui/multi/SearchActivity.kt | 23 ++++++- .../ui/suggestion/SearchSuggestionFragment.kt | 17 ++++- .../kotatsu/settings/SettingsActivity.kt | 4 -- .../settings/about/AppUpdateActivity.kt | 18 +++++ .../kotatsu/settings/nav/NavConfigFragment.kt | 19 ++++++ .../settings/protect/ProtectSetupActivity.kt | 18 ++++- .../reader/ReaderTapGridConfigActivity.kt | 17 ++++- .../settings/search/SettingsSearchFragment.kt | 17 ++++- .../sources/auth/SourceAuthActivity.kt | 23 +++++++ .../sources/catalog/SourcesCatalogActivity.kt | 4 -- .../sources/manage/SourcesManageFragment.kt | 23 ++++++- .../directories/MangaDirectoriesActivity.kt | 11 +-- .../TrackerCategoriesConfigSheet.kt | 11 +++ .../kotatsu/stats/ui/StatsActivity.kt | 4 -- .../kotatsu/stats/ui/sheet/MangaStatsSheet.kt | 11 +++ .../kotatsu/sync/ui/SyncAuthActivity.kt | 18 ++++- .../tracker/ui/debug/TrackerDebugActivity.kt | 22 +++++- .../kotatsu/tracker/ui/feed/FeedFragment.kt | 15 +++++ .../recent/RecentWidgetConfigActivity.kt | 17 ++++- .../widget/shelf/ShelfWidgetConfigActivity.kt | 22 +++++- .../main/res/layout/activity_alternatives.xml | 2 +- .../res/layout/activity_appwidget_shelf.xml | 2 +- app/src/main/res/layout/activity_browser.xml | 2 +- .../main/res/layout/activity_categories.xml | 2 +- app/src/main/res/layout/activity_details.xml | 2 +- app/src/main/res/layout/activity_main.xml | 2 +- .../main/res/layout/activity_manga_list.xml | 2 +- .../res/layout/activity_scrobbler_config.xml | 2 +- app/src/main/res/layout/activity_search.xml | 6 -- .../res/layout/activity_tracker_debug.xml | 2 +- app/src/main/res/layout/sheet_filter.xml | 1 + app/src/main/res/layout/sheet_list_mode.xml | 2 + .../main/res/layout/sheet_reader_config.xml | 2 + app/src/main/res/layout/sheet_scrobbling.xml | 3 +- app/src/main/res/layout/sheet_stats_manga.xml | 1 + app/src/main/res/layout/sheet_welcome.xml | 3 +- app/src/main/res/values/styles.xml | 7 ++ app/src/main/res/values/themes.xml | 1 + 84 files changed, 836 insertions(+), 374 deletions(-) delete mode 100644 app/src/main/kotlin/org/koitharu/kotatsu/core/ui/util/InsetsToMarginsListener.kt delete mode 100644 app/src/main/kotlin/org/koitharu/kotatsu/core/ui/util/InsetsToPaddingListener.kt diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/alternatives/ui/AlternativesActivity.kt b/app/src/main/kotlin/org/koitharu/kotatsu/alternatives/ui/AlternativesActivity.kt index b4279a892..87a1bc085 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/alternatives/ui/AlternativesActivity.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/alternatives/ui/AlternativesActivity.kt @@ -1,10 +1,11 @@ package org.koitharu.kotatsu.alternatives.ui import android.os.Bundle -import android.view.Gravity import android.view.View import android.widget.Toast import androidx.activity.viewModels +import androidx.core.view.WindowInsetsCompat +import androidx.core.view.updatePadding import coil3.ImageLoader import dagger.hilt.android.AndroidEntryPoint import org.koitharu.kotatsu.R @@ -15,9 +16,10 @@ import org.koitharu.kotatsu.core.ui.BaseActivity import org.koitharu.kotatsu.core.ui.BaseListAdapter import org.koitharu.kotatsu.core.ui.dialog.buildAlertDialog import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener -import org.koitharu.kotatsu.core.util.ext.consumeInsetsAsPadding +import org.koitharu.kotatsu.core.util.ext.consumeAllSystemBarsInsets import org.koitharu.kotatsu.core.util.ext.observe import org.koitharu.kotatsu.core.util.ext.observeEvent +import org.koitharu.kotatsu.core.util.ext.systemBarsInsets import org.koitharu.kotatsu.databinding.ActivityAlternativesBinding import org.koitharu.kotatsu.list.ui.adapter.ListItemType import org.koitharu.kotatsu.list.ui.adapter.TypedListSpacingDecoration @@ -50,7 +52,6 @@ class AlternativesActivity : BaseActivity(), .addDelegate(ListItemType.FOOTER_LOADING, loadingFooterAD()) .addDelegate(ListItemType.STATE_LOADING, loadingStateAD()) with(viewBinding.recyclerView) { - consumeInsetsAsPadding(Gravity.START or Gravity.END or Gravity.BOTTOM) setHasFixedSize(true) addItemDecoration(TypedListSpacingDecoration(context, addHorizontalPadding = false)) adapter = listAdapter @@ -65,6 +66,24 @@ class AlternativesActivity : BaseActivity(), } } + override fun onApplyWindowInsets( + v: View, + insets: WindowInsetsCompat + ): WindowInsetsCompat { + val barsInsets = insets.systemBarsInsets + viewBinding.recyclerView.updatePadding( + left = barsInsets.left, + right = barsInsets.right, + bottom = barsInsets.bottom, + ) + viewBinding.appbar.updatePadding( + left = barsInsets.left, + right = barsInsets.right, + top = barsInsets.top, + ) + return insets.consumeAllSystemBarsInsets() + } + override fun onItemClick(item: MangaAlternativeModel, view: View) { when (view.id) { R.id.chip_source -> router.openSearch(item.manga.source, viewModel.manga.title) diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/bookmarks/ui/AllBookmarksFragment.kt b/app/src/main/kotlin/org/koitharu/kotatsu/bookmarks/ui/AllBookmarksFragment.kt index 974a9688d..e76c760a4 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/bookmarks/ui/AllBookmarksFragment.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/bookmarks/ui/AllBookmarksFragment.kt @@ -1,7 +1,6 @@ package org.koitharu.kotatsu.bookmarks.ui import android.os.Bundle -import android.view.Gravity import android.view.LayoutInflater import android.view.Menu import android.view.MenuInflater @@ -10,6 +9,7 @@ import android.view.View import android.view.ViewGroup import android.widget.Toast import androidx.appcompat.view.ActionMode +import androidx.core.view.WindowInsetsCompat import androidx.fragment.app.viewModels import androidx.recyclerview.widget.GridLayoutManager import coil3.ImageLoader @@ -26,10 +26,11 @@ import org.koitharu.kotatsu.core.ui.list.ListSelectionController import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener import org.koitharu.kotatsu.core.ui.list.fastscroll.FastScroller import org.koitharu.kotatsu.core.ui.util.ReversibleActionObserver -import org.koitharu.kotatsu.core.util.ext.consumeInsetsAsPadding +import org.koitharu.kotatsu.core.util.ext.consumeAllSystemBarsInsets import org.koitharu.kotatsu.core.util.ext.findAppCompatDelegate import org.koitharu.kotatsu.core.util.ext.observe import org.koitharu.kotatsu.core.util.ext.observeEvent +import org.koitharu.kotatsu.core.util.ext.systemBarsInsets import org.koitharu.kotatsu.databinding.FragmentListSimpleBinding import org.koitharu.kotatsu.list.ui.GridSpanResolver import org.koitharu.kotatsu.list.ui.adapter.ListHeaderClickListener @@ -85,7 +86,6 @@ class AllBookmarksFragment : ) val spanSizeLookup = SpanSizeLookup() with(binding.recyclerView) { - consumeInsetsAsPadding(Gravity.BOTTOM or Gravity.START or Gravity.END) setHasFixedSize(true) val spanResolver = GridSpanResolver(resources) addItemDecoration(TypedListSpacingDecoration(context, false)) @@ -107,6 +107,18 @@ class AllBookmarksFragment : viewModel.onActionDone.observeEvent(viewLifecycleOwner, ReversibleActionObserver(binding.recyclerView)) } + override fun onApplyWindowInsets(v: View, insets: WindowInsetsCompat): WindowInsetsCompat { + val barsInsets = insets.systemBarsInsets + val basePadding = resources.getDimensionPixelOffset(R.dimen.list_spacing_normal) + viewBinding?.recyclerView?.setPadding( + barsInsets.left + basePadding, + barsInsets.top + basePadding, + barsInsets.right + basePadding, + barsInsets.bottom + basePadding, + ) + return insets.consumeAllSystemBarsInsets() + } + override fun onDestroyView() { super.onDestroyView() bookmarksAdapter = null diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/browser/BrowserActivity.kt b/app/src/main/kotlin/org/koitharu/kotatsu/browser/BrowserActivity.kt index 9098add50..758a8299b 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/browser/BrowserActivity.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/browser/BrowserActivity.kt @@ -1,10 +1,12 @@ package org.koitharu.kotatsu.browser import android.os.Bundle -import android.view.Gravity import android.view.Menu import android.view.MenuItem +import android.view.View +import androidx.core.view.WindowInsetsCompat import androidx.core.view.isVisible +import androidx.core.view.updatePadding import com.google.android.material.snackbar.Snackbar import dagger.hilt.android.AndroidEntryPoint import org.koitharu.kotatsu.R @@ -16,7 +18,7 @@ import org.koitharu.kotatsu.core.parser.MangaRepository import org.koitharu.kotatsu.core.parser.ParserMangaRepository import org.koitharu.kotatsu.core.ui.BaseActivity import org.koitharu.kotatsu.core.util.ext.configureForParser -import org.koitharu.kotatsu.core.util.ext.consumeInsetsAsPadding +import org.koitharu.kotatsu.core.util.ext.consumeAll import org.koitharu.kotatsu.databinding.ActivityBrowserBinding import javax.inject.Inject import com.google.android.material.R as materialR @@ -42,7 +44,6 @@ class BrowserActivity : BaseActivity(), BrowserCallback val repository = mangaRepositoryFactory.create(mangaSource) as? ParserMangaRepository val userAgent = repository?.getRequestHeaders()?.get(CommonHeaders.USER_AGENT) viewBinding.webView.configureForParser(userAgent) - viewBinding.webView.consumeInsetsAsPadding(Gravity.START or Gravity.END or Gravity.BOTTOM) viewBinding.webView.webViewClient = BrowserClient(this) viewBinding.webView.webChromeClient = ProgressChromeClient(viewBinding.progressBar) onBackPressedCallback = WebViewBackPressedCallback(viewBinding.webView) @@ -62,6 +63,25 @@ class BrowserActivity : BaseActivity(), BrowserCallback } } + override fun onApplyWindowInsets( + v: View, + insets: WindowInsetsCompat + ): WindowInsetsCompat { + val type = WindowInsetsCompat.Type.systemBars() or WindowInsetsCompat.Type.ime() + val barsInsets = insets.getInsets(type) + viewBinding.webView.updatePadding( + left = barsInsets.left, + right = barsInsets.right, + bottom = barsInsets.bottom, + ) + viewBinding.appbar.updatePadding( + left = barsInsets.left, + right = barsInsets.right, + top = barsInsets.top, + ) + return insets.consumeAll(type) + } + override fun onCreateOptionsMenu(menu: Menu): Boolean { super.onCreateOptionsMenu(menu) menuInflater.inflate(R.menu.opt_browser, menu) diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/browser/cloudflare/CloudFlareActivity.kt b/app/src/main/kotlin/org/koitharu/kotatsu/browser/cloudflare/CloudFlareActivity.kt index 23a8889e1..d3e7b3d55 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/browser/cloudflare/CloudFlareActivity.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/browser/cloudflare/CloudFlareActivity.kt @@ -3,12 +3,14 @@ package org.koitharu.kotatsu.browser.cloudflare import android.content.Context import android.content.Intent import android.os.Bundle -import android.view.Gravity import android.view.Menu import android.view.MenuItem +import android.view.View import androidx.activity.result.contract.ActivityResultContract +import androidx.core.view.WindowInsetsCompat import androidx.core.view.isInvisible import androidx.core.view.isVisible +import androidx.core.view.updatePadding import androidx.lifecycle.lifecycleScope import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.Dispatchers @@ -25,7 +27,7 @@ import org.koitharu.kotatsu.core.nav.AppRouter import org.koitharu.kotatsu.core.network.cookies.MutableCookieJar import org.koitharu.kotatsu.core.ui.BaseActivity import org.koitharu.kotatsu.core.util.ext.configureForParser -import org.koitharu.kotatsu.core.util.ext.consumeInsetsAsPadding +import org.koitharu.kotatsu.core.util.ext.consumeAll import org.koitharu.kotatsu.databinding.ActivityBrowserBinding import org.koitharu.kotatsu.parsers.network.CloudFlareHelper import javax.inject.Inject @@ -58,7 +60,6 @@ class CloudFlareActivity : BaseActivity(), CloudFlareCal } cfClient = CloudFlareClient(cookieJar, this, url) viewBinding.webView.configureForParser(intent?.getStringExtra(AppRouter.KEY_USER_AGENT)) - viewBinding.webView.consumeInsetsAsPadding(Gravity.START or Gravity.END or Gravity.BOTTOM) viewBinding.webView.webViewClient = cfClient onBackPressedCallback = WebViewBackPressedCallback(viewBinding.webView).also { onBackPressedDispatcher.addCallback(it) @@ -69,6 +70,25 @@ class CloudFlareActivity : BaseActivity(), CloudFlareCal } } + override fun onApplyWindowInsets( + v: View, + insets: WindowInsetsCompat + ): WindowInsetsCompat { + val type = WindowInsetsCompat.Type.systemBars() or WindowInsetsCompat.Type.ime() + val barsInsets = insets.getInsets(type) + viewBinding.webView.updatePadding( + left = barsInsets.left, + right = barsInsets.right, + bottom = barsInsets.bottom, + ) + viewBinding.appbar.updatePadding( + left = barsInsets.left, + right = barsInsets.right, + top = barsInsets.top, + ) + return insets.consumeAll(type) + } + override fun onDestroy() { runCatching { viewBinding.webView diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/core/ui/BaseActivity.kt b/app/src/main/kotlin/org/koitharu/kotatsu/core/ui/BaseActivity.kt index 668c3d09c..ec2598d7e 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/core/ui/BaseActivity.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/core/ui/BaseActivity.kt @@ -15,6 +15,8 @@ import androidx.appcompat.app.AppCompatDelegate import androidx.appcompat.view.ActionMode import androidx.appcompat.widget.Toolbar import androidx.core.app.ActivityCompat +import androidx.core.view.OnApplyWindowInsetsListener +import androidx.core.view.ViewCompat import androidx.fragment.app.FragmentManager import androidx.viewbinding.ViewBinding import dagger.hilt.android.EntryPointAccessors @@ -31,6 +33,7 @@ import org.koitharu.kotatsu.main.ui.protect.ScreenshotPolicyHelper abstract class BaseActivity : AppCompatActivity(), ExceptionResolver.Host, + OnApplyWindowInsetsListener, ScreenshotPolicyHelper.ContentContainer { private var isAmoledTheme = false @@ -78,16 +81,10 @@ abstract class BaseActivity : } @Deprecated("Use ViewBinding", level = DeprecationLevel.ERROR) - override fun setContentView(layoutResID: Int) { - super.setContentView(layoutResID) - setupToolbar() - } + override fun setContentView(layoutResID: Int) = throw UnsupportedOperationException() @Deprecated("Use ViewBinding", level = DeprecationLevel.ERROR) - override fun setContentView(view: View?) { - super.setContentView(view) - setupToolbar() - } + override fun setContentView(view: View?) = throw UnsupportedOperationException() override fun getContext() = this @@ -96,6 +93,7 @@ abstract class BaseActivity : protected fun setContentView(binding: B) { this.viewBinding = binding super.setContentView(binding.root) + ViewCompat.setOnApplyWindowInsetsListener(binding.root, this) val toolbar = (binding.root.findViewById(R.id.toolbar) as? Toolbar) toolbar?.let(this::setSupportActionBar) } @@ -125,10 +123,6 @@ abstract class BaseActivity : return super.onKeyDown(keyCode, event) } - private fun setupToolbar() { - (findViewById(R.id.toolbar) as? Toolbar)?.let(this::setSupportActionBar) - } - protected fun isDarkAmoledTheme(): Boolean { val uiMode = resources.configuration.uiMode val isNight = uiMode and Configuration.UI_MODE_NIGHT_MASK == Configuration.UI_MODE_NIGHT_YES diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/core/ui/BaseFragment.kt b/app/src/main/kotlin/org/koitharu/kotatsu/core/ui/BaseFragment.kt index f1f3c349f..a275062dc 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/core/ui/BaseFragment.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/core/ui/BaseFragment.kt @@ -5,6 +5,8 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import androidx.core.view.OnApplyWindowInsetsListener +import androidx.core.view.ViewCompat import androidx.fragment.app.Fragment import androidx.viewbinding.ViewBinding import dagger.hilt.android.EntryPointAccessors @@ -12,6 +14,7 @@ import org.koitharu.kotatsu.core.exceptions.resolve.ExceptionResolver import org.koitharu.kotatsu.core.ui.util.ActionModeDelegate abstract class BaseFragment : + OnApplyWindowInsetsListener, Fragment(), ExceptionResolver.Host { @@ -42,6 +45,7 @@ abstract class BaseFragment : final override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) + ViewCompat.setOnApplyWindowInsetsListener(view, this) onViewBindingCreated(requireViewBinding(), savedInstanceState) } diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/core/ui/BasePreferenceFragment.kt b/app/src/main/kotlin/org/koitharu/kotatsu/core/ui/BasePreferenceFragment.kt index cc25dbf5f..06113c780 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/core/ui/BasePreferenceFragment.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/core/ui/BasePreferenceFragment.kt @@ -2,11 +2,11 @@ package org.koitharu.kotatsu.core.ui import android.content.Context import android.os.Bundle -import android.view.Gravity import android.view.View import androidx.annotation.StringRes -import androidx.core.view.ancestors -import androidx.fragment.app.FragmentContainerView +import androidx.core.view.OnApplyWindowInsetsListener +import androidx.core.view.ViewCompat +import androidx.core.view.WindowInsetsCompat import androidx.preference.Preference import androidx.preference.PreferenceFragmentCompat import androidx.preference.PreferenceScreen @@ -18,10 +18,14 @@ import org.koitharu.kotatsu.R import org.koitharu.kotatsu.core.exceptions.resolve.ExceptionResolver import org.koitharu.kotatsu.core.prefs.AppSettings import org.koitharu.kotatsu.core.ui.util.RecyclerViewOwner -import org.koitharu.kotatsu.core.util.ext.consumeInsetsAsPadding +import org.koitharu.kotatsu.core.util.ext.consumeAllSystemBarsInsets +import org.koitharu.kotatsu.core.util.ext.container +import org.koitharu.kotatsu.core.util.ext.end import org.koitharu.kotatsu.core.util.ext.getThemeColor import org.koitharu.kotatsu.core.util.ext.getThemeDrawable import org.koitharu.kotatsu.core.util.ext.parentView +import org.koitharu.kotatsu.core.util.ext.start +import org.koitharu.kotatsu.core.util.ext.systemBarsInsets import org.koitharu.kotatsu.settings.SettingsActivity import javax.inject.Inject import com.google.android.material.R as materialR @@ -29,6 +33,7 @@ import com.google.android.material.R as materialR @AndroidEntryPoint abstract class BasePreferenceFragment(@StringRes private val titleId: Int) : PreferenceFragmentCompat(), + OnApplyWindowInsetsListener, RecyclerViewOwner, ExceptionResolver.Host { @@ -49,15 +54,23 @@ abstract class BasePreferenceFragment(@StringRes private val titleId: Int) : override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) + ViewCompat.setOnApplyWindowInsetsListener(view, this) val themedContext = (view.parentView ?: view).context view.setBackgroundColor(themedContext.getThemeColor(android.R.attr.colorBackground)) listView.clipToPadding = false - val insetsEdges = Gravity.BOTTOM or when { - !resources.getBoolean(R.bool.is_tablet) -> Gravity.FILL_HORIZONTAL - isMaster() -> Gravity.START - else -> Gravity.END - } - listView.consumeInsetsAsPadding(insetsEdges) + } + + override fun onApplyWindowInsets(v: View, insets: WindowInsetsCompat): WindowInsetsCompat { + val barsInsets = insets.systemBarsInsets + val isTablet = !resources.getBoolean(R.bool.is_tablet) + val isMaster = container?.id == R.id.container_master + listView.setPaddingRelative( + if (isTablet && !isMaster) 0 else barsInsets.start(v), + 0, + if (isTablet && isMaster) 0 else barsInsets.end(v), + barsInsets.bottom, + ) + return insets.consumeAllSystemBarsInsets() } override fun onResume() { @@ -99,9 +112,4 @@ abstract class BasePreferenceFragment(@StringRes private val titleId: Int) : } return -1 } - - private fun isMaster(): Boolean { - val container = view?.ancestors?.firstNotNullOfOrNull { it as? FragmentContainerView } ?: return false - return container.id == R.id.container_master - } } diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/core/ui/FragmentContainerActivity.kt b/app/src/main/kotlin/org/koitharu/kotatsu/core/ui/FragmentContainerActivity.kt index 8a0d7c646..ef9c96fa0 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/core/ui/FragmentContainerActivity.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/core/ui/FragmentContainerActivity.kt @@ -3,8 +3,6 @@ package org.koitharu.kotatsu.core.ui import android.os.Bundle import android.view.View import androidx.coordinatorlayout.widget.CoordinatorLayout -import androidx.core.view.OnApplyWindowInsetsListener -import androidx.core.view.ViewCompat import androidx.core.view.WindowInsetsCompat import androidx.core.view.updatePadding import androidx.fragment.app.Fragment @@ -12,6 +10,7 @@ import androidx.fragment.app.commit import com.google.android.material.appbar.AppBarLayout import dagger.hilt.android.AndroidEntryPoint import org.koitharu.kotatsu.R +import org.koitharu.kotatsu.core.util.ext.consumeSystemBarsInsets import org.koitharu.kotatsu.databinding.ActivityContainerBinding import org.koitharu.kotatsu.main.ui.owners.AppBarOwner import org.koitharu.kotatsu.main.ui.owners.SnackbarOwner @@ -19,7 +18,6 @@ import org.koitharu.kotatsu.main.ui.owners.SnackbarOwner @AndroidEntryPoint abstract class FragmentContainerActivity(private val fragmentClass: Class) : BaseActivity(), - OnApplyWindowInsetsListener, AppBarOwner, SnackbarOwner { @@ -33,7 +31,6 @@ abstract class FragmentContainerActivity(private val fragmentClass: Class : AppCompatDialogFragment(), ExceptionResolver.Host { +abstract class BaseAdaptiveSheet : AppCompatDialogFragment(), + OnApplyWindowInsetsListener, + ExceptionResolver.Host { private var waitingForDismissAllowingStateLoss = false private var isFitToContentsDisabled = false @@ -74,6 +78,7 @@ abstract class BaseAdaptiveSheet : AppCompatDialogFragment(), E final override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) + ViewCompat.setOnApplyWindowInsetsListener(view, this) val binding = requireViewBinding() if (actionModeDelegate == null) { actionModeDelegate = (activity as? BaseActivity<*>)?.actionModeDelegate diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/core/ui/util/InsetsToMarginsListener.kt b/app/src/main/kotlin/org/koitharu/kotatsu/core/ui/util/InsetsToMarginsListener.kt deleted file mode 100644 index 1977cd239..000000000 --- a/app/src/main/kotlin/org/koitharu/kotatsu/core/ui/util/InsetsToMarginsListener.kt +++ /dev/null @@ -1,51 +0,0 @@ -package org.koitharu.kotatsu.core.ui.util - -import android.view.Gravity -import android.view.View -import android.view.ViewGroup -import androidx.annotation.GravityInt -import androidx.core.graphics.Insets -import androidx.core.view.OnApplyWindowInsetsListener -import androidx.core.view.WindowInsetsCompat -import androidx.core.view.updateLayoutParams -import org.koitharu.kotatsu.core.util.ext.consumeRelative -import org.koitharu.kotatsu.core.util.ext.end -import org.koitharu.kotatsu.core.util.ext.start - -class InsetsToMarginsListener( - @GravityInt - private val sides: Int, - private val baseMargins: Insets, -) : OnApplyWindowInsetsListener { - - private val insetType = WindowInsetsCompat.Type.systemBars() - - override fun onApplyWindowInsets(v: View, insets: WindowInsetsCompat): WindowInsetsCompat { - val barsInsets = insets.getInsets(insetType) - v.updateLayoutParams { - if (sides and Gravity.START == Gravity.START) { - marginStart = barsInsets.start(v) + baseMargins.start(v) - } - if (sides and Gravity.TOP == Gravity.TOP) { - topMargin = barsInsets.top + baseMargins.top - } - if (sides and Gravity.END == Gravity.END) { - marginEnd = barsInsets.end(v) + baseMargins.end(v) - } - if (sides and Gravity.BOTTOM == Gravity.BOTTOM) { - bottomMargin = barsInsets.bottom + baseMargins.bottom - } - } - return WindowInsetsCompat.Builder(insets) - .setInsets( - insetType, - barsInsets.consumeRelative( - v, - start = sides and Gravity.START == Gravity.START, - top = sides and Gravity.TOP == Gravity.TOP, - end = sides and Gravity.END == Gravity.END, - bottom = sides and Gravity.BOTTOM == Gravity.BOTTOM, - ), - ).build() - } -} diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/core/ui/util/InsetsToPaddingListener.kt b/app/src/main/kotlin/org/koitharu/kotatsu/core/ui/util/InsetsToPaddingListener.kt deleted file mode 100644 index 6650c049c..000000000 --- a/app/src/main/kotlin/org/koitharu/kotatsu/core/ui/util/InsetsToPaddingListener.kt +++ /dev/null @@ -1,61 +0,0 @@ -package org.koitharu.kotatsu.core.ui.util - -import android.view.Gravity -import android.view.View -import androidx.annotation.GravityInt -import androidx.core.graphics.Insets -import androidx.core.view.OnApplyWindowInsetsListener -import androidx.core.view.WindowInsetsCompat -import org.koitharu.kotatsu.core.util.ext.consumeRelative -import org.koitharu.kotatsu.core.util.ext.end -import org.koitharu.kotatsu.core.util.ext.start - -class InsetsToPaddingListener( - @GravityInt - private val sides: Int, - private val basePaddings: Insets, -) : OnApplyWindowInsetsListener { - - private val insetType = WindowInsetsCompat.Type.systemBars() - - override fun onApplyWindowInsets(v: View, insets: WindowInsetsCompat): WindowInsetsCompat { - val barsInsets = insets.getInsets(insetType) - v.setPaddingRelative( - /* start = */ - if (sides and Gravity.START == Gravity.START) { - barsInsets.start(v) + basePaddings.start(v) - } else { - v.paddingStart - }, - /* top = */ - if (sides and Gravity.TOP == Gravity.TOP) { - barsInsets.top + basePaddings.top - } else { - v.paddingTop - }, - /* end = */ - if (sides and Gravity.END == Gravity.END) { - barsInsets.end(v) + basePaddings.end(v) - } else { - v.paddingEnd - }, - /* bottom = */ - if (sides and Gravity.BOTTOM == Gravity.BOTTOM) { - barsInsets.bottom + basePaddings.bottom - } else { - v.paddingBottom - }, - ) - return WindowInsetsCompat.Builder(insets) - .setInsets( - insetType, - barsInsets.consumeRelative( - v, - start = sides and Gravity.START == Gravity.START, - top = sides and Gravity.TOP == Gravity.TOP, - end = sides and Gravity.END == Gravity.END, - bottom = sides and Gravity.BOTTOM == Gravity.BOTTOM, - ), - ).build() - } -} diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/core/ui/widgets/WindowInsetHolder.kt b/app/src/main/kotlin/org/koitharu/kotatsu/core/ui/widgets/WindowInsetHolder.kt index 57870cf19..a0deadc0b 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/core/ui/widgets/WindowInsetHolder.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/core/ui/widgets/WindowInsetHolder.kt @@ -10,6 +10,8 @@ import android.widget.LinearLayout import androidx.annotation.AttrRes import androidx.coordinatorlayout.widget.CoordinatorLayout import androidx.core.view.WindowInsetsCompat +import org.koitharu.kotatsu.core.util.ext.end +import org.koitharu.kotatsu.core.util.ext.start class WindowInsetHolder @JvmOverloads constructor( context: Context, @@ -24,9 +26,9 @@ class WindowInsetHolder @JvmOverloads constructor( val barsInsets = WindowInsetsCompat.toWindowInsetsCompat(insets, this) .getInsets(WindowInsetsCompat.Type.systemBars()) val gravity = getLayoutGravity() - val newWidth = when (gravity and Gravity.HORIZONTAL_GRAVITY_MASK) { - Gravity.LEFT -> barsInsets.left - Gravity.RIGHT -> barsInsets.right + val newWidth = when (gravity and Gravity.RELATIVE_HORIZONTAL_GRAVITY_MASK) { + Gravity.START -> barsInsets.start(this) + Gravity.END -> barsInsets.end(this) else -> 0 } val newHeight = when (gravity and Gravity.VERTICAL_GRAVITY_MASK) { diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/core/util/ext/Fragment.kt b/app/src/main/kotlin/org/koitharu/kotatsu/core/util/ext/Fragment.kt index dc166a96a..483d41b5e 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/core/util/ext/Fragment.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/core/util/ext/Fragment.kt @@ -2,7 +2,9 @@ package org.koitharu.kotatsu.core.util.ext import android.os.Bundle import androidx.core.view.MenuProvider +import androidx.core.view.ancestors import androidx.fragment.app.Fragment +import androidx.fragment.app.FragmentContainerView import androidx.lifecycle.Lifecycle import androidx.lifecycle.coroutineScope @@ -29,3 +31,8 @@ tailrec fun Fragment.findParentCallback(cls: Class): T? { else -> parent.findParentCallback(cls) } } + +val Fragment.container: FragmentContainerView? + get() = view?.ancestors?.firstNotNullOfOrNull { + it as? FragmentContainerView // TODO check if direct parent + } diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/core/util/ext/Insets.kt b/app/src/main/kotlin/org/koitharu/kotatsu/core/util/ext/Insets.kt index 8c3b2a87d..58611fd60 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/core/util/ext/Insets.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/core/util/ext/Insets.kt @@ -2,6 +2,8 @@ package org.koitharu.kotatsu.core.util.ext import android.view.View import androidx.core.graphics.Insets +import androidx.core.view.WindowInsetsCompat +import androidx.core.view.WindowInsetsCompat.Type.InsetsType fun Insets.end(view: View): Int { return if (view.isRtl) left else right @@ -11,20 +13,69 @@ fun Insets.start(view: View): Int { return if (view.isRtl) right else left } -fun Insets.consume( +@Deprecated("") +val WindowInsetsCompat.systemBarsInsets: Insets + get() = getInsets(WindowInsetsCompat.Type.systemBars()) + +@Deprecated("") +fun WindowInsetsCompat.consumeSystemBarsInsets( left: Boolean = false, top: Boolean = false, right: Boolean = false, bottom: Boolean = false, -): Insets = Insets.of( - /* left = */ if (left) 0 else this.left, - /* top = */ if (top) 0 else this.top, - /* right = */ if (right) 0 else this.right, - /* bottom = */ if (bottom) 0 else this.bottom, -) +): WindowInsetsCompat { + val barsInsets = systemBarsInsets + val insets = Insets.of( + if (left) 0 else barsInsets.left, + if (top) 0 else barsInsets.top, + if (right) 0 else barsInsets.right, + if (bottom) 0 else barsInsets.bottom, + ) + return WindowInsetsCompat.Builder(this) + .setInsets(WindowInsetsCompat.Type.systemBars(), insets) + .build() +} +fun WindowInsetsCompat.consume( + v: View, + @InsetsType typeMask: Int, + start: Boolean = false, + top: Boolean = false, + end: Boolean = false, + bottom: Boolean = false, +): WindowInsetsCompat { + val insets = getInsets(typeMask) + val newInsets = Insets.of( + /* left = */ if (if (v.isRtl) end else start) 0 else insets.left, + /* top = */ if (top) 0 else insets.top, + /* right = */ if (if (v.isRtl) start else end) 0 else insets.right, + /* bottom = */ if (bottom) 0 else insets.bottom, + ) + return WindowInsetsCompat.Builder(this) + .setInsets(typeMask, newInsets) + .build() +} + +fun WindowInsetsCompat.consumeAll( + @InsetsType typeMask: Int, +): WindowInsetsCompat = WindowInsetsCompat.Builder(this) + .setInsets(typeMask, Insets.NONE) + .build() + +@Deprecated("") +fun WindowInsetsCompat.consumeSystemBarsInsets( + view: View, + start: Boolean = false, + top: Boolean = false, + end: Boolean = false, + bottom: Boolean = false, +): WindowInsetsCompat = consume(view, WindowInsetsCompat.Type.systemBars(), start, top, end, bottom) -fun Insets.consumeRelative( +@Deprecated("") +fun WindowInsetsCompat.consumeAllSystemBarsInsets() = consumeAll(WindowInsetsCompat.Type.systemBars()) + +@Deprecated("") +fun Insets.consume( view: View, start: Boolean = false, top: Boolean = false, diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/core/util/ext/View.kt b/app/src/main/kotlin/org/koitharu/kotatsu/core/util/ext/View.kt index e987e2267..da05edc0f 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/core/util/ext/View.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/core/util/ext/View.kt @@ -6,11 +6,8 @@ import android.view.View import android.view.View.MeasureSpec import android.view.ViewGroup import android.widget.Checkable -import androidx.annotation.GravityInt import androidx.appcompat.widget.ActionMenuView import androidx.appcompat.widget.Toolbar -import androidx.core.graphics.Insets -import androidx.core.view.ViewCompat import androidx.core.view.children import androidx.core.view.descendants import androidx.core.view.isVisible @@ -27,8 +24,6 @@ import com.google.android.material.slider.RangeSlider import com.google.android.material.slider.Slider import com.google.android.material.tabs.TabLayout import org.koitharu.kotatsu.core.ui.OnContextClickListenerCompat -import org.koitharu.kotatsu.core.ui.util.InsetsToMarginsListener -import org.koitharu.kotatsu.core.ui.util.InsetsToPaddingListener import kotlin.math.roundToInt fun View.hasGlobalPoint(x: Int, y: Int): Boolean { @@ -194,19 +189,3 @@ fun Chip.setProgressIcon() { chipIcon = progressDrawable progressDrawable.start() } - -private fun View.marginsSnapshot(): Insets = (layoutParams as? ViewGroup.MarginLayoutParams)?.let { lp -> - Insets.of(lp.leftMargin, lp.topMargin, lp.rightMargin, lp.bottomMargin) -} ?: Insets.NONE - -private fun View.paddingSnapshot(): Insets = Insets.of(paddingLeft, paddingTop, paddingRight, paddingBottom) - -fun View.consumeInsetsAsPadding(@GravityInt sides: Int) = ViewCompat.setOnApplyWindowInsetsListener( - this, - InsetsToPaddingListener(sides, paddingSnapshot()), -) - -fun View.consumeInsetsAsMargins(@GravityInt sides: Int) = ViewCompat.setOnApplyWindowInsetsListener( - this, - InsetsToMarginsListener(sides, marginsSnapshot()), -) diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/DetailsActivity.kt b/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/DetailsActivity.kt index 030b80357..e69c0d40a 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/DetailsActivity.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/DetailsActivity.kt @@ -2,7 +2,6 @@ package org.koitharu.kotatsu.details.ui import android.content.Context import android.os.Bundle -import android.transition.TransitionManager import android.view.Gravity import android.view.View import android.view.ViewGroup @@ -10,8 +9,6 @@ import android.view.ViewTreeObserver import android.widget.Toast import androidx.activity.viewModels import androidx.core.text.method.LinkMovementMethodCompat -import androidx.core.view.OnApplyWindowInsetsListener -import androidx.core.view.ViewCompat import androidx.core.view.WindowInsetsCompat import androidx.core.view.isGone import androidx.core.view.isVisible @@ -19,6 +16,7 @@ import androidx.core.view.updateLayoutParams import androidx.core.view.updatePadding import androidx.core.view.updatePaddingRelative import androidx.swiperefreshlayout.widget.SwipeRefreshLayout +import androidx.transition.TransitionManager import coil3.ImageLoader import coil3.request.ImageRequest import coil3.request.SuccessResult @@ -68,7 +66,7 @@ import org.koitharu.kotatsu.core.ui.util.ReversibleActionObserver import org.koitharu.kotatsu.core.ui.widgets.ChipsView import org.koitharu.kotatsu.core.util.FileSize import org.koitharu.kotatsu.core.util.LocaleUtils -import org.koitharu.kotatsu.core.util.ext.consumeRelative +import org.koitharu.kotatsu.core.util.ext.consume import org.koitharu.kotatsu.core.util.ext.copyToClipboard import org.koitharu.kotatsu.core.util.ext.crossfade import org.koitharu.kotatsu.core.util.ext.defaultPlaceholders @@ -77,6 +75,7 @@ import org.koitharu.kotatsu.core.util.ext.drawableStart import org.koitharu.kotatsu.core.util.ext.end import org.koitharu.kotatsu.core.util.ext.enqueueWith import org.koitharu.kotatsu.core.util.ext.getQuantityStringSafe +import org.koitharu.kotatsu.core.util.ext.isAnimationsEnabled import org.koitharu.kotatsu.core.util.ext.isTextTruncated import org.koitharu.kotatsu.core.util.ext.joinToStringWithLimit import org.koitharu.kotatsu.core.util.ext.mangaSourceExtra @@ -114,7 +113,7 @@ import com.google.android.material.R as materialR @AndroidEntryPoint class DetailsActivity : BaseActivity(), - View.OnClickListener, OnApplyWindowInsetsListener, + View.OnClickListener, View.OnLayoutChangeListener, ViewTreeObserver.OnDrawListener, ChipsView.OnChipClickListener, OnListItemClickListener, SwipeRefreshLayout.OnRefreshListener { @@ -162,7 +161,6 @@ class DetailsActivity : DetailsBottomSheetCallback(viewBinding.swipeRefreshLayout, checkNotNull(viewBinding.navbarDim)), ) } - ViewCompat.setOnApplyWindowInsetsListener(viewBinding.root, this) val appRouter = router viewModel.mangaDetails.filterNotNull().observe(this, ::onMangaUpdated) @@ -244,7 +242,11 @@ class DetailsActivity : R.id.button_description_more -> { val tv = viewBinding.textViewDescription - TransitionManager.beginDelayedTransition(tv.parentView) + if (tv.context.isAnimationsEnabled) { + tv.parentView?.let { + TransitionManager.beginDelayedTransition(it) + } + } if (tv.maxLines in 1 until Integer.MAX_VALUE) { tv.maxLines = Integer.MAX_VALUE } else { @@ -319,7 +321,8 @@ class DetailsActivity : } override fun onApplyWindowInsets(v: View, insets: WindowInsetsCompat): WindowInsetsCompat { - val barsInsets = insets.getInsets(WindowInsetsCompat.Type.systemBars()) + val typeMask = WindowInsetsCompat.Type.systemBars() + val barsInsets = insets.getInsets(typeMask) if (viewBinding.cardChapters != null) { // landscape viewBinding.cardChapters?.updateLayoutParams { @@ -334,12 +337,11 @@ class DetailsActivity : viewBinding.appbar.updatePaddingRelative( start = barsInsets.start(v), ) - return WindowInsetsCompat.Builder(insets) - .setInsets( - WindowInsetsCompat.Type.systemBars(), - barsInsets.consumeRelative(v, end = true, bottom = true), - ).build() + return insets.consume(v, typeMask, bottom = true, end = true) } else { + viewBinding.navbarDim?.updateLayoutParams { + height = barsInsets.bottom + } return insets } } diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/DetailsBottomSheetCallback.kt b/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/DetailsBottomSheetCallback.kt index 33576c064..b431db007 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/DetailsBottomSheetCallback.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/DetailsBottomSheetCallback.kt @@ -3,11 +3,10 @@ package org.koitharu.kotatsu.details.ui import android.view.View import androidx.swiperefreshlayout.widget.SwipeRefreshLayout import com.google.android.material.bottomsheet.BottomSheetBehavior -import org.koitharu.kotatsu.core.ui.widgets.WindowInsetHolder class DetailsBottomSheetCallback( private val swipeRefreshLayout: SwipeRefreshLayout, - private val navbarDimView: WindowInsetHolder, + private val navbarDimView: View, ) : BottomSheetBehavior.BottomSheetCallback() { override fun onStateChanged(bottomSheet: View, newState: Int) { diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/pager/ChaptersPagesSheet.kt b/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/pager/ChaptersPagesSheet.kt index e62f420f9..9a5171d4e 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/pager/ChaptersPagesSheet.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/pager/ChaptersPagesSheet.kt @@ -5,7 +5,9 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.appcompat.view.ActionMode +import androidx.core.view.WindowInsetsCompat import androidx.core.view.isVisible +import androidx.transition.TransitionManager import com.google.android.material.tabs.TabLayout import com.google.android.material.tabs.TabLayoutMediator import dagger.hilt.android.AndroidEntryPoint @@ -25,6 +27,7 @@ import org.koitharu.kotatsu.core.ui.util.RecyclerViewOwner import org.koitharu.kotatsu.core.ui.util.ReversibleActionObserver import org.koitharu.kotatsu.core.util.ext.doOnPageChanged import org.koitharu.kotatsu.core.util.ext.findCurrentPagerFragment +import org.koitharu.kotatsu.core.util.ext.isAnimationsEnabled import org.koitharu.kotatsu.core.util.ext.menuView import org.koitharu.kotatsu.core.util.ext.observe import org.koitharu.kotatsu.core.util.ext.observeEvent @@ -95,12 +98,17 @@ class ChaptersPagesSheet : BaseAdaptiveSheet(), } } + override fun onApplyWindowInsets(v: View, insets: WindowInsetsCompat): WindowInsetsCompat = insets + override fun onStateChanged(sheet: View, newState: Int) { if (newState == STATE_DRAGGING || newState == STATE_SETTLING) { return } val binding = viewBinding ?: return val isActionModeStarted = actionModeDelegate?.isActionModeStarted == true + if (sheet.context.isAnimationsEnabled) { + TransitionManager.beginDelayedTransition(binding.toolbar) + } binding.toolbar.menuView?.isVisible = newState == STATE_EXPANDED && !isActionModeStarted binding.splitButtonRead.isVisible = newState != STATE_EXPANDED && !isActionModeStarted && viewModel is DetailsViewModel diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/pager/bookmarks/BookmarksFragment.kt b/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/pager/bookmarks/BookmarksFragment.kt index fa88bf7ca..0237f1ac5 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/pager/bookmarks/BookmarksFragment.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/pager/bookmarks/BookmarksFragment.kt @@ -1,7 +1,6 @@ package org.koitharu.kotatsu.details.ui.pager.bookmarks import android.os.Bundle -import android.view.Gravity import android.view.LayoutInflater import android.view.Menu import android.view.MenuInflater @@ -9,6 +8,7 @@ import android.view.MenuItem import android.view.View import android.view.ViewGroup import androidx.appcompat.view.ActionMode +import androidx.core.view.WindowInsetsCompat import androidx.fragment.app.viewModels import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.RecyclerView @@ -29,11 +29,12 @@ import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener import org.koitharu.kotatsu.core.ui.util.PagerNestedScrollHelper import org.koitharu.kotatsu.core.ui.util.RecyclerViewOwner import org.koitharu.kotatsu.core.ui.util.ReversibleActionObserver -import org.koitharu.kotatsu.core.util.ext.consumeInsetsAsPadding +import org.koitharu.kotatsu.core.util.ext.consumeAllSystemBarsInsets import org.koitharu.kotatsu.core.util.ext.findAppCompatDelegate import org.koitharu.kotatsu.core.util.ext.findParentCallback import org.koitharu.kotatsu.core.util.ext.observe import org.koitharu.kotatsu.core.util.ext.observeEvent +import org.koitharu.kotatsu.core.util.ext.systemBarsInsets import org.koitharu.kotatsu.databinding.FragmentMangaBookmarksBinding import org.koitharu.kotatsu.details.ui.pager.ChaptersPagesViewModel import org.koitharu.kotatsu.list.ui.GridSpanResolver @@ -94,7 +95,6 @@ class BookmarksFragment : BaseFragment(), headerClickListener = null, ) viewModel.gridScale.observe(viewLifecycleOwner, ::onGridScaleChanged) // before rv initialization - binding.recyclerView.consumeInsetsAsPadding(Gravity.START or Gravity.BOTTOM or Gravity.END) with(binding.recyclerView) { addItemDecoration(TypedListSpacingDecoration(context, false)) setHasFixedSize(true) @@ -116,6 +116,17 @@ class BookmarksFragment : BaseFragment(), viewModel.onActionDone.observeEvent(viewLifecycleOwner, ReversibleActionObserver(binding.recyclerView)) } + override fun onApplyWindowInsets(v: View, insets: WindowInsetsCompat): WindowInsetsCompat { + val barsInsets = insets.systemBarsInsets + viewBinding?.recyclerView?.setPadding( + barsInsets.left, + barsInsets.top, + barsInsets.right, + barsInsets.bottom, + ) + return insets.consumeAllSystemBarsInsets() + } + override fun onDestroyView() { spanResolver = null bookmarksAdapter = null diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/pager/chapters/ChaptersFragment.kt b/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/pager/chapters/ChaptersFragment.kt index 206040c3e..56db72fd3 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/pager/chapters/ChaptersFragment.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/pager/chapters/ChaptersFragment.kt @@ -4,8 +4,6 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import androidx.core.view.OnApplyWindowInsetsListener -import androidx.core.view.ViewCompat import androidx.core.view.WindowInsetsCompat import androidx.core.view.isGone import androidx.core.view.isVisible @@ -49,7 +47,6 @@ import kotlin.math.roundToInt class ChaptersFragment : BaseFragment(), OnListItemClickListener, - OnApplyWindowInsetsListener, RecyclerViewOwner, ChipsView.OnChipClickListener { @@ -84,7 +81,6 @@ class ChaptersFragment : LinearLayoutManager(context) } } - ViewCompat.setOnApplyWindowInsetsListener(binding.root, this) with(binding.recyclerViewChapters) { addItemDecoration(TypedListSpacingDecoration(context, true)) checkNotNull(selectionController).attachToRecyclerView(this) diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/pager/pages/PagesFragment.kt b/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/pager/pages/PagesFragment.kt index dfba6cab1..ead43b6dc 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/pager/pages/PagesFragment.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/pager/pages/PagesFragment.kt @@ -1,7 +1,6 @@ package org.koitharu.kotatsu.details.ui.pager.pages import android.os.Bundle -import android.view.Gravity import android.view.LayoutInflater import android.view.Menu import android.view.MenuInflater @@ -10,6 +9,7 @@ import android.view.View import android.view.ViewGroup import androidx.appcompat.view.ActionMode import androidx.collection.ArraySet +import androidx.core.view.WindowInsetsCompat import androidx.core.view.isInvisible import androidx.core.view.isVisible import androidx.fragment.app.viewModels @@ -33,7 +33,7 @@ import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener import org.koitharu.kotatsu.core.ui.util.PagerNestedScrollHelper import org.koitharu.kotatsu.core.ui.util.RecyclerViewOwner import org.koitharu.kotatsu.core.util.RecyclerViewScrollCallback -import org.koitharu.kotatsu.core.util.ext.consumeInsetsAsPadding +import org.koitharu.kotatsu.core.util.ext.consumeAll import org.koitharu.kotatsu.core.util.ext.findAppCompatDelegate import org.koitharu.kotatsu.core.util.ext.findParentCallback import org.koitharu.kotatsu.core.util.ext.observe @@ -118,7 +118,6 @@ class PagesFragment : clickListener = this@PagesFragment, ) viewModel.gridScale.observe(viewLifecycleOwner, ::onGridScaleChanged) // before rv initialization - binding.recyclerView.consumeInsetsAsPadding(Gravity.START or Gravity.BOTTOM or Gravity.END) with(binding.recyclerView) { addItemDecoration(TypedListSpacingDecoration(context, false)) checkNotNull(selectionController).attachToRecyclerView(this) @@ -150,6 +149,18 @@ class PagesFragment : super.onDestroyView() } + override fun onApplyWindowInsets(v: View, insets: WindowInsetsCompat): WindowInsetsCompat { + val typeBask = WindowInsetsCompat.Type.systemBars() + val barsInsets = insets.getInsets(typeBask) + viewBinding?.recyclerView?.setPadding( + barsInsets.left, + barsInsets.top, + barsInsets.right, + barsInsets.bottom, + ) + return insets.consumeAll(typeBask) + } + override fun onItemClick(item: PageThumbnail, view: View) { if (selectionController?.onItemClick(item.page.id) == true) { return diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/scrobbling/ScrobblingInfoSheet.kt b/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/scrobbling/ScrobblingInfoSheet.kt index c90797e18..fa701d28d 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/scrobbling/ScrobblingInfoSheet.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/scrobbling/ScrobblingInfoSheet.kt @@ -10,6 +10,8 @@ import android.widget.RatingBar import android.widget.Toast import androidx.appcompat.widget.PopupMenu import androidx.core.text.method.LinkMovementMethodCompat +import androidx.core.view.WindowInsetsCompat +import androidx.core.view.updatePadding import androidx.fragment.app.activityViewModels import coil3.ImageLoader import com.google.android.material.snackbar.Snackbar @@ -18,6 +20,7 @@ import org.koitharu.kotatsu.R import org.koitharu.kotatsu.core.nav.AppRouter import org.koitharu.kotatsu.core.nav.router import org.koitharu.kotatsu.core.ui.sheet.BaseAdaptiveSheet +import org.koitharu.kotatsu.core.util.ext.consume import org.koitharu.kotatsu.core.util.ext.defaultPlaceholders import org.koitharu.kotatsu.core.util.ext.enqueueWith import org.koitharu.kotatsu.core.util.ext.getDisplayMessage @@ -81,6 +84,15 @@ class ScrobblingInfoSheet : menu = null } + override fun onApplyWindowInsets(v: View, insets: WindowInsetsCompat): WindowInsetsCompat { + val typeMask = WindowInsetsCompat.Type.systemBars() + viewBinding?.root?.updatePadding( + bottom = insets.getInsets(typeMask).bottom, + ) + return insets.consume(v, typeMask, bottom = true) + } + + override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) { viewModel.updateScrobbling( index = scrobblerIndex, diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/download/ui/list/DownloadsActivity.kt b/app/src/main/kotlin/org/koitharu/kotatsu/download/ui/list/DownloadsActivity.kt index 9a9cbb317..e07ecb3f5 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/download/ui/list/DownloadsActivity.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/download/ui/list/DownloadsActivity.kt @@ -8,8 +8,6 @@ import android.view.View import androidx.activity.viewModels import androidx.appcompat.view.ActionMode import androidx.core.graphics.Insets -import androidx.core.view.OnApplyWindowInsetsListener -import androidx.core.view.ViewCompat import androidx.core.view.WindowInsetsCompat import androidx.core.view.updatePadding import coil3.ImageLoader @@ -31,7 +29,6 @@ import javax.inject.Inject @AndroidEntryPoint class DownloadsActivity : BaseActivity(), DownloadItemListener, - OnApplyWindowInsetsListener, ListSelectionController.Callback { @Inject @@ -47,7 +44,6 @@ class DownloadsActivity : BaseActivity(), super.onCreate(savedInstanceState) setContentView(ActivityDownloadsBinding.inflate(layoutInflater)) supportActionBar?.setDisplayHomeAsUpEnabled(true) - ViewCompat.setOnApplyWindowInsetsListener(viewBinding.root, this) val downloadsAdapter = DownloadsAdapter(this, coil, this) val decoration = TypedListSpacingDecoration(this, false) selectionController = ListSelectionController( diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/explore/ui/ExploreFragment.kt b/app/src/main/kotlin/org/koitharu/kotatsu/explore/ui/ExploreFragment.kt index c7e8a14f6..660eae254 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/explore/ui/ExploreFragment.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/explore/ui/ExploreFragment.kt @@ -5,7 +5,6 @@ import android.content.Intent import android.net.Uri import android.os.Build import android.os.Bundle -import android.view.Gravity import android.view.LayoutInflater import android.view.Menu import android.view.MenuInflater @@ -13,6 +12,7 @@ import android.view.MenuItem import android.view.View import android.view.ViewGroup import androidx.appcompat.view.ActionMode +import androidx.core.view.WindowInsetsCompat import androidx.fragment.app.viewModels import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.LinearLayoutManager @@ -32,10 +32,11 @@ import org.koitharu.kotatsu.core.ui.util.RecyclerViewOwner import org.koitharu.kotatsu.core.ui.util.ReversibleActionObserver import org.koitharu.kotatsu.core.ui.util.SpanSizeResolver import org.koitharu.kotatsu.core.util.ext.addMenuProvider -import org.koitharu.kotatsu.core.util.ext.consumeInsetsAsPadding +import org.koitharu.kotatsu.core.util.ext.consumeAllSystemBarsInsets import org.koitharu.kotatsu.core.util.ext.findAppCompatDelegate import org.koitharu.kotatsu.core.util.ext.observe import org.koitharu.kotatsu.core.util.ext.observeEvent +import org.koitharu.kotatsu.core.util.ext.systemBarsInsets import org.koitharu.kotatsu.databinding.FragmentExploreBinding import org.koitharu.kotatsu.explore.ui.adapter.ExploreAdapter import org.koitharu.kotatsu.explore.ui.adapter.ExploreListEventListener @@ -79,7 +80,6 @@ class ExploreFragment : callback = this, ) with(binding.recyclerView) { - consumeInsetsAsPadding(Gravity.BOTTOM or Gravity.START or Gravity.END) adapter = exploreAdapter setHasFixedSize(true) SpanSizeResolver(this, resources.getDimensionPixelSize(R.dimen.explore_grid_width)).attach() @@ -97,6 +97,18 @@ class ExploreFragment : } } + override fun onApplyWindowInsets(v: View, insets: WindowInsetsCompat): WindowInsetsCompat { + val barsInsets = insets.systemBarsInsets + val basePadding = v.resources.getDimensionPixelOffset(R.dimen.list_spacing_normal) + viewBinding?.recyclerView?.setPadding( + /* left = */ barsInsets.left + basePadding, + /* top = */ basePadding, + /* right = */ barsInsets.right + basePadding, + /* bottom = */ barsInsets.bottom + basePadding, + ) + return insets.consumeAllSystemBarsInsets() + } + override fun onDestroyView() { super.onDestroyView() sourceSelectionController = null diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/favourites/ui/categories/FavouriteCategoriesActivity.kt b/app/src/main/kotlin/org/koitharu/kotatsu/favourites/ui/categories/FavouriteCategoriesActivity.kt index 6821770c8..46d620aff 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/favourites/ui/categories/FavouriteCategoriesActivity.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/favourites/ui/categories/FavouriteCategoriesActivity.kt @@ -1,10 +1,13 @@ package org.koitharu.kotatsu.favourites.ui.categories import android.os.Bundle -import android.view.Gravity import android.view.View +import android.view.ViewGroup.MarginLayoutParams import androidx.activity.viewModels import androidx.appcompat.view.ActionMode +import androidx.core.view.WindowInsetsCompat +import androidx.core.view.updateLayoutParams +import androidx.core.view.updatePadding import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.RecyclerView import coil3.ImageLoader @@ -15,9 +18,11 @@ import org.koitharu.kotatsu.core.model.FavouriteCategory import org.koitharu.kotatsu.core.nav.router import org.koitharu.kotatsu.core.ui.BaseActivity import org.koitharu.kotatsu.core.ui.list.ListSelectionController -import org.koitharu.kotatsu.core.util.ext.consumeInsetsAsPadding +import org.koitharu.kotatsu.core.util.ext.consumeAllSystemBarsInsets +import org.koitharu.kotatsu.core.util.ext.end import org.koitharu.kotatsu.core.util.ext.observe import org.koitharu.kotatsu.core.util.ext.observeEvent +import org.koitharu.kotatsu.core.util.ext.systemBarsInsets import org.koitharu.kotatsu.databinding.ActivityCategoriesBinding import org.koitharu.kotatsu.favourites.ui.categories.adapter.CategoriesAdapter import org.koitharu.kotatsu.list.ui.adapter.ListStateHolderListener @@ -53,7 +58,6 @@ class FavouriteCategoriesActivity : callback = CategoriesSelectionCallback(viewBinding.recyclerView, viewModel), ) selectionController.attachToRecyclerView(viewBinding.recyclerView) - viewBinding.recyclerView.consumeInsetsAsPadding(Gravity.START or Gravity.END or Gravity.BOTTOM) viewBinding.recyclerView.setHasFixedSize(true) viewBinding.recyclerView.adapter = adapter viewBinding.recyclerView.addItemDecoration(TypedListSpacingDecoration(this, false)) @@ -67,6 +71,28 @@ class FavouriteCategoriesActivity : viewModel.onError.observeEvent(this, SnackbarErrorObserver(viewBinding.recyclerView, null)) } + override fun onApplyWindowInsets( + v: View, + insets: WindowInsetsCompat + ): WindowInsetsCompat { + val barsInsets = insets.systemBarsInsets + viewBinding.recyclerView.updatePadding( + left = barsInsets.left, + right = barsInsets.right, + bottom = barsInsets.bottom, + ) + viewBinding.appbar.updatePadding( + left = barsInsets.left, + right = barsInsets.right, + top = barsInsets.top, + ) + viewBinding.fabAdd.updateLayoutParams { + marginEnd = topMargin + barsInsets.end(v) + bottomMargin = topMargin + barsInsets.bottom + } + return insets.consumeAllSystemBarsInsets() + } + override fun onClick(v: View) { when (v.id) { R.id.fab_add -> router.openFavoriteCategoryCreate() diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/favourites/ui/categories/edit/FavouritesCategoryEditActivity.kt b/app/src/main/kotlin/org/koitharu/kotatsu/favourites/ui/categories/edit/FavouritesCategoryEditActivity.kt index 2d87d3d92..fffe0afa8 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/favourites/ui/categories/edit/FavouritesCategoryEditActivity.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/favourites/ui/categories/edit/FavouritesCategoryEditActivity.kt @@ -8,18 +8,21 @@ import android.widget.AdapterView import android.widget.ArrayAdapter import android.widget.Filter import androidx.activity.viewModels +import androidx.core.view.WindowInsetsCompat import androidx.core.view.isVisible import dagger.hilt.android.AndroidEntryPoint import org.koitharu.kotatsu.R import org.koitharu.kotatsu.core.model.FavouriteCategory import org.koitharu.kotatsu.core.ui.BaseActivity import org.koitharu.kotatsu.core.ui.util.DefaultTextWatcher +import org.koitharu.kotatsu.core.util.ext.consumeAllSystemBarsInsets import org.koitharu.kotatsu.core.util.ext.getDisplayMessage import org.koitharu.kotatsu.core.util.ext.getSerializableCompat import org.koitharu.kotatsu.core.util.ext.observe import org.koitharu.kotatsu.core.util.ext.observeEvent import org.koitharu.kotatsu.core.util.ext.setChecked import org.koitharu.kotatsu.core.util.ext.sortedByOrdinal +import org.koitharu.kotatsu.core.util.ext.systemBarsInsets import org.koitharu.kotatsu.databinding.ActivityCategoryEditBinding import org.koitharu.kotatsu.list.domain.ListSortOrder import com.google.android.material.R as materialR @@ -56,6 +59,20 @@ class FavouritesCategoryEditActivity : } } + override fun onApplyWindowInsets( + v: View, + insets: WindowInsetsCompat + ): WindowInsetsCompat { + val barsInsets = insets.systemBarsInsets + viewBinding.root.setPadding( + barsInsets.left, + barsInsets.top, + barsInsets.right, + barsInsets.bottom, + ) + return insets.consumeAllSystemBarsInsets() + } + override fun onSaveInstanceState(outState: Bundle) { super.onSaveInstanceState(outState) outState.putSerializable(KEY_SORT_ORDER, selectedSortOrder) diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/favourites/ui/container/FavouritesContainerFragment.kt b/app/src/main/kotlin/org/koitharu/kotatsu/favourites/ui/container/FavouritesContainerFragment.kt index 8bcd606b1..10905b98f 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/favourites/ui/container/FavouritesContainerFragment.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/favourites/ui/container/FavouritesContainerFragment.kt @@ -6,6 +6,7 @@ import android.view.View import android.view.ViewGroup import android.view.ViewStub import androidx.appcompat.view.ActionMode +import androidx.core.view.WindowInsetsCompat import androidx.core.view.isGone import androidx.core.view.isVisible import androidx.fragment.app.Fragment @@ -77,6 +78,8 @@ class FavouritesContainerFragment : BaseFragment(), ChipsV .observe(viewLifecycleOwner, ::onDataChanged) } + override fun onApplyWindowInsets(v: View, insets: WindowInsetsCompat): WindowInsetsCompat = insets + override fun onChipClick(chip: Chip, data: Any?) { when (data) { is MangaTag -> filter.toggleTag(data, !chip.isChecked) diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/filter/ui/sheet/FilterSheetFragment.kt b/app/src/main/kotlin/org/koitharu/kotatsu/filter/ui/sheet/FilterSheetFragment.kt index ab69c39a7..77c8e0c6a 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/filter/ui/sheet/FilterSheetFragment.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/filter/ui/sheet/FilterSheetFragment.kt @@ -7,6 +7,7 @@ import android.view.View import android.view.ViewGroup import android.widget.AdapterView import android.widget.ArrayAdapter +import androidx.core.view.WindowInsetsCompat import androidx.core.view.isGone import androidx.core.view.updatePadding import com.google.android.material.chip.Chip @@ -18,6 +19,7 @@ import org.koitharu.kotatsu.core.nav.router import org.koitharu.kotatsu.core.ui.model.titleRes import org.koitharu.kotatsu.core.ui.sheet.BaseAdaptiveSheet import org.koitharu.kotatsu.core.ui.widgets.ChipsView +import org.koitharu.kotatsu.core.util.ext.consume import org.koitharu.kotatsu.core.util.ext.getDisplayMessage import org.koitharu.kotatsu.core.util.ext.getDisplayName import org.koitharu.kotatsu.core.util.ext.observe @@ -92,6 +94,14 @@ class FilterSheetFragment : BaseAdaptiveSheet(), } } + override fun onApplyWindowInsets(v: View, insets: WindowInsetsCompat): WindowInsetsCompat { + val typeMask = WindowInsetsCompat.Type.systemBars() + viewBinding?.scrollView?.updatePadding( + bottom = insets.getInsets(typeMask).bottom, + ) + return insets.consume(v, typeMask, bottom = true) + } + override fun onItemSelected(parent: AdapterView<*>, view: View?, position: Int, id: Long) { val filter = requireFilter() when (parent.id) { diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/filter/ui/tags/TagsCatalogSheet.kt b/app/src/main/kotlin/org/koitharu/kotatsu/filter/ui/tags/TagsCatalogSheet.kt index f209ab7ea..398b748a1 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/filter/ui/tags/TagsCatalogSheet.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/filter/ui/tags/TagsCatalogSheet.kt @@ -8,6 +8,7 @@ import android.view.View import android.view.ViewGroup import android.view.inputmethod.EditorInfo import android.widget.TextView +import androidx.core.view.WindowInsetsCompat import androidx.fragment.app.viewModels import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.lifecycle.withCreationCallback @@ -17,6 +18,7 @@ import org.koitharu.kotatsu.core.ui.sheet.AdaptiveSheetBehavior import org.koitharu.kotatsu.core.ui.sheet.AdaptiveSheetCallback import org.koitharu.kotatsu.core.ui.sheet.BaseAdaptiveSheet import org.koitharu.kotatsu.core.ui.util.DefaultTextWatcher +import org.koitharu.kotatsu.core.util.ext.consumeAll import org.koitharu.kotatsu.core.util.ext.observe import org.koitharu.kotatsu.databinding.SheetTagsBinding import org.koitharu.kotatsu.filter.ui.FilterCoordinator @@ -59,6 +61,18 @@ class TagsCatalogSheet : BaseAdaptiveSheet(), disableFitToContents() } + override fun onApplyWindowInsets(v: View, insets: WindowInsetsCompat): WindowInsetsCompat { + val typeBask = WindowInsetsCompat.Type.systemBars() + val barsInsets = insets.getInsets(typeBask) + viewBinding?.recyclerView?.setPadding( + barsInsets.left, + barsInsets.top, + barsInsets.right, + barsInsets.bottom, + ) + return insets.consumeAll(typeBask) + } + override fun onItemClick(item: TagCatalogItem, view: View) { viewModel.handleTagClick(item.tag, item.isChecked) } diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/image/ui/ImageActivity.kt b/app/src/main/kotlin/org/koitharu/kotatsu/image/ui/ImageActivity.kt index 527d76449..12ebc8d07 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/image/ui/ImageActivity.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/image/ui/ImageActivity.kt @@ -7,8 +7,6 @@ import android.view.View import android.view.ViewGroup import androidx.activity.viewModels import androidx.core.graphics.drawable.toBitmap -import androidx.core.view.OnApplyWindowInsetsListener -import androidx.core.view.ViewCompat import androidx.core.view.WindowInsetsCompat import androidx.core.view.isVisible import androidx.core.view.updateLayoutParams @@ -33,6 +31,7 @@ import org.koitharu.kotatsu.core.nav.AppRouter import org.koitharu.kotatsu.core.ui.BaseActivity import org.koitharu.kotatsu.core.ui.util.PopupMenuMediator import org.koitharu.kotatsu.core.util.ShareHelper +import org.koitharu.kotatsu.core.util.ext.consumeAll import org.koitharu.kotatsu.core.util.ext.end import org.koitharu.kotatsu.core.util.ext.enqueueWith import org.koitharu.kotatsu.core.util.ext.getDisplayIcon @@ -50,7 +49,6 @@ import com.google.android.material.R as materialR @AndroidEntryPoint class ImageActivity : BaseActivity(), ImageRequest.Listener, - OnApplyWindowInsetsListener, View.OnClickListener { @Inject @@ -63,7 +61,6 @@ class ImageActivity : BaseActivity(), override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(ActivityImageBinding.inflate(layoutInflater)) - ViewCompat.setOnApplyWindowInsetsListener(viewBinding.root, this) viewBinding.buttonBack.setOnClickListener(this) viewBinding.buttonMenu.setOnClickListener(this) val imageUrl = requireNotNull(intent.data) @@ -111,16 +108,18 @@ class ImageActivity : BaseActivity(), } override fun onApplyWindowInsets(v: View, insets: WindowInsetsCompat): WindowInsetsCompat { - val barsInsets = insets.getInsets(WindowInsetsCompat.Type.systemBars()) + val typeMask = WindowInsetsCompat.Type.systemBars() + val barsInsets = insets.getInsets(typeMask) + val baseMargin = v.resources.getDimensionPixelOffset(R.dimen.screen_padding) viewBinding.buttonMenu.updateLayoutParams { - marginEnd = barsInsets.end(v) - topMargin = barsInsets.top + marginEnd = barsInsets.end(v) + baseMargin + topMargin = barsInsets.top + baseMargin } viewBinding.buttonBack.updateLayoutParams { - marginStart = barsInsets.start(v) - topMargin = barsInsets.top + marginStart = barsInsets.start(v) + baseMargin + topMargin = barsInsets.top + baseMargin } - return insets + return insets.consumeAll(typeMask) } private fun loadImage(url: Uri?) { diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/list/ui/MangaListFragment.kt b/app/src/main/kotlin/org/koitharu/kotatsu/list/ui/MangaListFragment.kt index 37199ef6c..ab71a388a 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/list/ui/MangaListFragment.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/list/ui/MangaListFragment.kt @@ -1,7 +1,6 @@ package org.koitharu.kotatsu.list.ui import android.os.Bundle -import android.view.Gravity import android.view.LayoutInflater import android.view.Menu import android.view.MenuInflater @@ -11,6 +10,7 @@ import android.view.ViewGroup import androidx.annotation.CallSuper import androidx.appcompat.view.ActionMode import androidx.collection.ArraySet +import androidx.core.view.WindowInsetsCompat import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.RecyclerView import androidx.swiperefreshlayout.widget.SwipeRefreshLayout @@ -37,7 +37,7 @@ import org.koitharu.kotatsu.core.ui.util.ReversibleActionObserver import org.koitharu.kotatsu.core.ui.widgets.TipView import org.koitharu.kotatsu.core.util.ShareHelper import org.koitharu.kotatsu.core.util.ext.addMenuProvider -import org.koitharu.kotatsu.core.util.ext.consumeInsetsAsPadding +import org.koitharu.kotatsu.core.util.ext.consumeAll import org.koitharu.kotatsu.core.util.ext.findAppCompatDelegate import org.koitharu.kotatsu.core.util.ext.observe import org.koitharu.kotatsu.core.util.ext.observeEvent @@ -110,7 +110,6 @@ abstract class MangaListFragment : ) paginationListener = PaginationScrollListener(4, this) with(binding.recyclerView) { - consumeInsetsAsPadding(Gravity.START or Gravity.BOTTOM or Gravity.END) setHasFixedSize(true) adapter = listAdapter checkNotNull(selectionController).attachToRecyclerView(this) @@ -132,6 +131,19 @@ abstract class MangaListFragment : viewModel.onActionDone.observeEvent(viewLifecycleOwner, ReversibleActionObserver(binding.recyclerView)) } + override fun onApplyWindowInsets(v: View, insets: WindowInsetsCompat): WindowInsetsCompat { + val typeMask = WindowInsetsCompat.Type.systemBars() + val barsInsets = insets.getInsets(typeMask) + val basePadding = v.resources.getDimensionPixelOffset(R.dimen.list_spacing_normal) + viewBinding?.recyclerView?.setPadding( + left = barsInsets.left + basePadding, + top = basePadding, + right = barsInsets.right + basePadding, + bottom = barsInsets.bottom + basePadding, + ) + return insets.consumeAll(typeMask) + } + override fun onDestroyView() { listAdapter = null paginationListener = null diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/list/ui/config/ListConfigBottomSheet.kt b/app/src/main/kotlin/org/koitharu/kotatsu/list/ui/config/ListConfigBottomSheet.kt index e8a8ff20a..8876eccb4 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/list/ui/config/ListConfigBottomSheet.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/list/ui/config/ListConfigBottomSheet.kt @@ -7,7 +7,9 @@ import android.view.ViewGroup import android.widget.AdapterView import android.widget.ArrayAdapter import android.widget.CompoundButton +import androidx.core.view.WindowInsetsCompat import androidx.core.view.isVisible +import androidx.core.view.updatePadding import androidx.fragment.app.viewModels import com.google.android.material.button.MaterialButtonToggleGroup import com.google.android.material.slider.Slider @@ -15,6 +17,7 @@ import dagger.hilt.android.AndroidEntryPoint import org.koitharu.kotatsu.R import org.koitharu.kotatsu.core.prefs.ListMode import org.koitharu.kotatsu.core.ui.sheet.BaseAdaptiveSheet +import org.koitharu.kotatsu.core.util.ext.consume import org.koitharu.kotatsu.core.util.ext.setValueRounded import org.koitharu.kotatsu.core.util.progress.IntPercentLabelFormatter import org.koitharu.kotatsu.databinding.SheetListModeBinding @@ -73,6 +76,14 @@ class ListConfigBottomSheet : } } + override fun onApplyWindowInsets(v: View, insets: WindowInsetsCompat): WindowInsetsCompat { + val typeMask = WindowInsetsCompat.Type.systemBars() + viewBinding?.scrollView?.updatePadding( + bottom = insets.getInsets(typeMask).bottom, + ) + return insets.consume(v, typeMask, bottom = true) + } + override fun onButtonChecked(group: MaterialButtonToggleGroup?, checkedId: Int, isChecked: Boolean) { if (!isChecked) { return diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/list/ui/preview/PreviewFragment.kt b/app/src/main/kotlin/org/koitharu/kotatsu/list/ui/preview/PreviewFragment.kt index 56f9e5c54..8fb488e50 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/list/ui/preview/PreviewFragment.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/list/ui/preview/PreviewFragment.kt @@ -6,6 +6,7 @@ import android.view.View import android.view.ViewGroup import android.widget.TextView import androidx.core.text.method.LinkMovementMethodCompat +import androidx.core.view.WindowInsetsCompat import androidx.core.view.isVisible import androidx.fragment.app.viewModels import coil3.ImageLoader @@ -68,6 +69,8 @@ class PreviewFragment : BaseFragment(), View.OnClickList viewModel.description.observe(viewLifecycleOwner, ::onDescriptionChanged) } + override fun onApplyWindowInsets(v: View, insets: WindowInsetsCompat): WindowInsetsCompat = insets + override fun onClick(v: View) { val manga = viewModel.manga.value when (v.id) { diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/main/ui/MainActivity.kt b/app/src/main/kotlin/org/koitharu/kotatsu/main/ui/MainActivity.kt index 0d620bb41..c958dbf71 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/main/ui/MainActivity.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/main/ui/MainActivity.kt @@ -15,9 +15,7 @@ import androidx.appcompat.view.ActionMode import androidx.core.app.ActivityCompat import androidx.core.content.ContextCompat import androidx.core.net.toUri -import androidx.core.view.OnApplyWindowInsetsListener import androidx.core.view.SoftwareKeyboardControllerCompat -import androidx.core.view.ViewCompat import androidx.core.view.WindowInsetsCompat import androidx.core.view.children import androidx.core.view.inputmethod.EditorInfoCompat @@ -25,7 +23,6 @@ import androidx.core.view.isInvisible import androidx.core.view.isVisible import androidx.core.view.updateLayoutParams import androidx.core.view.updatePadding -import androidx.core.view.updatePaddingRelative import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentTransaction import androidx.fragment.app.commit @@ -53,7 +50,7 @@ import org.koitharu.kotatsu.core.ui.util.FadingAppbarMediator import org.koitharu.kotatsu.core.ui.util.MenuInvalidator import org.koitharu.kotatsu.core.ui.util.OptionsMenuBadgeHelper import org.koitharu.kotatsu.core.ui.widgets.SlidingBottomNavigationView -import org.koitharu.kotatsu.core.util.ext.consumeRelative +import org.koitharu.kotatsu.core.util.ext.consume import org.koitharu.kotatsu.core.util.ext.end import org.koitharu.kotatsu.core.util.ext.observe import org.koitharu.kotatsu.core.util.ext.observeEvent @@ -84,7 +81,6 @@ class MainActivity : BaseActivity(), AppBarOwner, BottomNav View.OnClickListener, View.OnFocusChangeListener, SearchSuggestionListener, - OnApplyWindowInsetsListener, MainNavigationDelegate.OnFragmentChangedListener, View.OnLayoutChangeListener { @@ -107,7 +103,6 @@ class MainActivity : BaseActivity(), AppBarOwner, BottomNav override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(ActivityMainBinding.inflate(layoutInflater)) - ViewCompat.setOnApplyWindowInsetsListener(viewBinding.root, this) with(viewBinding.searchView) { onFocusChangeListener = this@MainActivity @@ -216,7 +211,8 @@ class MainActivity : BaseActivity(), AppBarOwner, BottomNav } override fun onApplyWindowInsets(v: View, insets: WindowInsetsCompat): WindowInsetsCompat { - val barsInsets = insets.getInsets(WindowInsetsCompat.Type.systemBars()) + val typeMask = WindowInsetsCompat.Type.systemBars() + val barsInsets = insets.getInsets(typeMask) viewBinding.toolbarCard.updateLayoutParams { marginEnd = barsInsets.end(v) marginStart = if (viewBinding.navRail != null) { @@ -230,16 +226,12 @@ class MainActivity : BaseActivity(), AppBarOwner, BottomNav right = barsInsets.right, bottom = barsInsets.bottom, ) - return viewBinding.navRail?.let { navRail -> - navRail.updateLayoutParams { - marginStart = barsInsets.start(v) - topMargin = barsInsets.top - bottomMargin = barsInsets.bottom - } - WindowInsetsCompat.Builder(insets) - .setInsets(WindowInsetsCompat.Type.systemBars(), barsInsets.consumeRelative(v, start = true)) - .build() - } ?: insets + viewBinding.navRail?.updateLayoutParams { + marginStart = barsInsets.start(v) + topMargin = barsInsets.top + bottomMargin = barsInsets.bottom + } + return insets.consume(v, typeMask, start = viewBinding.navRail != null) } override fun onLayoutChange( diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/main/ui/MainNavigationDelegate.kt b/app/src/main/kotlin/org/koitharu/kotatsu/main/ui/MainNavigationDelegate.kt index 111157a44..593526f76 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/main/ui/MainNavigationDelegate.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/main/ui/MainNavigationDelegate.kt @@ -58,13 +58,16 @@ class MainNavigationDelegate( } override fun onNavigationItemSelected(item: MenuItem): Boolean { - return onNavigationItemSelected(item.itemId) + return if (onNavigationItemSelected(item.itemId)) { + item.isChecked = true + true + } else { + false + } } override fun onNavigationItemReselected(item: MenuItem) { - val fragment = fragmentManager.findFragmentByTag(TAG_PRIMARY) - val recyclerView = (fragment as? RecyclerViewOwner)?.recyclerView ?: return - recyclerView.smoothScrollToTop() + onNavigationItemReselected() } override fun handleOnBackPressed() { @@ -137,19 +140,22 @@ class MainNavigationDelegate( } private fun onNavigationItemSelected(@IdRes itemId: Int): Boolean { - return setPrimaryFragment( - when (itemId) { - R.id.nav_history -> HistoryListFragment::class.java - R.id.nav_favorites -> FavouritesContainerFragment::class.java - R.id.nav_explore -> ExploreFragment::class.java - R.id.nav_feed -> FeedFragment::class.java - R.id.nav_local -> LocalListFragment::class.java - R.id.nav_suggestions -> SuggestionsFragment::class.java - R.id.nav_bookmarks -> AllBookmarksFragment::class.java - R.id.nav_updated -> UpdatesFragment::class.java - else -> return false - }, - ) + val newFragment = when (itemId) { + R.id.nav_history -> HistoryListFragment::class.java + R.id.nav_favorites -> FavouritesContainerFragment::class.java + R.id.nav_explore -> ExploreFragment::class.java + R.id.nav_feed -> FeedFragment::class.java + R.id.nav_local -> LocalListFragment::class.java + R.id.nav_suggestions -> SuggestionsFragment::class.java + R.id.nav_bookmarks -> AllBookmarksFragment::class.java + R.id.nav_updated -> UpdatesFragment::class.java + else -> return false + } + if (!setPrimaryFragment(newFragment)) { + // probably already selected + onNavigationItemReselected() + } + return true } private fun getItemId(fragment: Fragment) = when (fragment) { @@ -178,6 +184,11 @@ class MainNavigationDelegate( return true } + private fun onNavigationItemReselected() { + val recyclerView = (primaryFragment as? RecyclerViewOwner)?.recyclerView ?: return + recyclerView.smoothScrollToTop() + } + private fun onFragmentChanged(fragment: Fragment, fromUser: Boolean) { isEnabled = getItemId(fragment) != firstItem()?.itemId listeners.forEach { it.onFragmentChanged(fragment, fromUser) } diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/main/ui/protect/ProtectActivity.kt b/app/src/main/kotlin/org/koitharu/kotatsu/main/ui/protect/ProtectActivity.kt index c05462db3..ea04b96a1 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/main/ui/protect/ProtectActivity.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/main/ui/protect/ProtectActivity.kt @@ -4,7 +4,6 @@ import android.content.Context import android.content.Intent import android.os.Bundle import android.text.Editable -import android.view.Gravity import android.view.KeyEvent import android.view.View import android.view.WindowManager @@ -16,16 +15,18 @@ import androidx.biometric.BiometricManager.Authenticators.BIOMETRIC_WEAK import androidx.biometric.BiometricManager.BIOMETRIC_SUCCESS import androidx.biometric.BiometricPrompt import androidx.biometric.BiometricPrompt.AuthenticationCallback +import androidx.core.view.WindowInsetsCompat import com.google.android.material.textfield.TextInputLayout import dagger.hilt.android.AndroidEntryPoint import org.koitharu.kotatsu.R import org.koitharu.kotatsu.core.ui.BaseActivity import org.koitharu.kotatsu.core.ui.util.DefaultTextWatcher -import org.koitharu.kotatsu.core.util.ext.consumeInsetsAsPadding +import org.koitharu.kotatsu.core.util.ext.consumeAllSystemBarsInsets import org.koitharu.kotatsu.core.util.ext.getDisplayMessage import org.koitharu.kotatsu.core.util.ext.getParcelableExtraCompat import org.koitharu.kotatsu.core.util.ext.observe import org.koitharu.kotatsu.core.util.ext.observeEvent +import org.koitharu.kotatsu.core.util.ext.systemBarsInsets import org.koitharu.kotatsu.databinding.ActivityProtectBinding import com.google.android.material.R as materialR @@ -43,7 +44,6 @@ class ProtectActivity : super.onCreate(savedInstanceState) window.addFlags(WindowManager.LayoutParams.FLAG_SECURE) setContentView(ActivityProtectBinding.inflate(layoutInflater)) - viewBinding.root.consumeInsetsAsPadding(Gravity.FILL) viewBinding.editPassword.setOnEditorActionListener(this) viewBinding.editPassword.addTextChangedListener(this) viewBinding.buttonNext.setOnClickListener(this) @@ -64,6 +64,18 @@ class ProtectActivity : } } + override fun onApplyWindowInsets(v: View, insets: WindowInsetsCompat): WindowInsetsCompat { + val barsInsets = insets.systemBarsInsets + val basePadding = resources.getDimensionPixelOffset(R.dimen.screen_padding) + viewBinding.root.setPadding( + barsInsets.left + basePadding, + barsInsets.top + basePadding, + barsInsets.right + basePadding, + barsInsets.bottom + basePadding, + ) + return insets.consumeAllSystemBarsInsets() + } + override fun onStart() { super.onStart() canUseBiometric = useFingerprint() diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/main/ui/welcome/WelcomeSheet.kt b/app/src/main/kotlin/org/koitharu/kotatsu/main/ui/welcome/WelcomeSheet.kt index 48d0cc61f..fefed0f7e 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/main/ui/welcome/WelcomeSheet.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/main/ui/welcome/WelcomeSheet.kt @@ -8,7 +8,9 @@ import android.view.View import android.view.ViewGroup import androidx.activity.result.ActivityResultCallback import androidx.activity.result.contract.ActivityResultContracts +import androidx.core.view.WindowInsetsCompat import androidx.core.view.isGone +import androidx.core.view.updatePadding import androidx.fragment.app.viewModels import com.google.android.material.chip.Chip import com.google.android.material.snackbar.Snackbar @@ -18,6 +20,7 @@ import org.koitharu.kotatsu.core.model.titleResId import org.koitharu.kotatsu.core.nav.router import org.koitharu.kotatsu.core.ui.sheet.BaseAdaptiveSheet import org.koitharu.kotatsu.core.ui.widgets.ChipsView +import org.koitharu.kotatsu.core.util.ext.consume import org.koitharu.kotatsu.core.util.ext.getDisplayName import org.koitharu.kotatsu.core.util.ext.observe import org.koitharu.kotatsu.core.util.ext.tryLaunch @@ -53,6 +56,14 @@ class WelcomeSheet : BaseAdaptiveSheet(), ChipsView.OnChipC viewModel.types.observe(viewLifecycleOwner, ::onTypesChanged) } + override fun onApplyWindowInsets(v: View, insets: WindowInsetsCompat): WindowInsetsCompat { + val typeMask = WindowInsetsCompat.Type.systemBars() + viewBinding?.scrollView?.updatePadding( + bottom = insets.getInsets(typeMask).bottom, + ) + return insets.consume(v, typeMask, bottom = true) + } + override fun onChipClick(chip: Chip, data: Any?) { when (data) { is ContentType -> viewModel.setTypeChecked(data, !chip.isChecked) diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/ReaderActivity.kt b/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/ReaderActivity.kt index e81eb0823..8aa79ce09 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/ReaderActivity.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/ReaderActivity.kt @@ -2,10 +2,6 @@ package org.koitharu.kotatsu.reader.ui import android.content.Intent import android.os.Bundle -import android.transition.Fade -import android.transition.Slide -import android.transition.TransitionManager -import android.transition.TransitionSet import android.view.Gravity import android.view.KeyEvent import android.view.MotionEvent @@ -14,8 +10,6 @@ import android.view.ViewGroup import android.view.WindowManager import androidx.activity.viewModels import androidx.core.graphics.Insets -import androidx.core.view.OnApplyWindowInsetsListener -import androidx.core.view.ViewCompat import androidx.core.view.WindowInsetsCompat import androidx.core.view.isGone import androidx.core.view.isVisible @@ -23,6 +17,10 @@ import androidx.core.view.updateLayoutParams import androidx.core.view.updatePadding import androidx.lifecycle.Lifecycle import androidx.lifecycle.lifecycleScope +import androidx.transition.Fade +import androidx.transition.Slide +import androidx.transition.TransitionManager +import androidx.transition.TransitionSet import com.google.android.material.snackbar.Snackbar import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.Dispatchers @@ -63,7 +61,6 @@ class ReaderActivity : TapGridDispatcher.OnGridTouchListener, ReaderConfigSheet.Callback, ReaderControlDelegate.OnInteractionListener, - OnApplyWindowInsetsListener, ReaderNavigationCallback, IdlingDetector.Callback, ZoomControl.ZoomControlListener { @@ -116,7 +113,6 @@ class ReaderActivity : viewBinding.zoomControl.listener = this viewBinding.actionsView.listener = this idlingDetector.bindToLifecycle(this) - ViewCompat.setOnApplyWindowInsetsListener(viewBinding.root, this) screenOrientationHelper.applySettings() viewModel.onError.observeEvent( @@ -297,7 +293,9 @@ class ReaderActivity : .setOrdering(TransitionSet.ORDERING_TOGETHER) .addTransition(Slide(Gravity.TOP).addTarget(viewBinding.appbarTop)) .addTransition(Fade().addTarget(viewBinding.infoBar)) - .addTransition(Slide(Gravity.BOTTOM).addTarget(viewBinding.toolbarDocked)) + viewBinding.toolbarDocked?.let { + transition.addTransition(Slide(Gravity.BOTTOM).addTarget(it)) + } TransitionManager.beginDelayedTransition(viewBinding.root, transition) } val isFullscreen = settings.isReaderFullscreenEnabled diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/colorfilter/ColorFilterConfigActivity.kt b/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/colorfilter/ColorFilterConfigActivity.kt index f811aebb2..a3f5e2b72 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/colorfilter/ColorFilterConfigActivity.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/colorfilter/ColorFilterConfigActivity.kt @@ -3,10 +3,10 @@ package org.koitharu.kotatsu.reader.ui.colorfilter import android.content.res.Resources import android.graphics.Bitmap import android.os.Bundle -import android.view.Gravity import android.view.View import android.widget.CompoundButton import androidx.activity.viewModels +import androidx.core.view.WindowInsetsCompat import coil3.ImageLoader import coil3.request.ImageRequest import coil3.request.bitmapConfig @@ -19,7 +19,7 @@ import com.google.android.material.slider.Slider import dagger.hilt.android.AndroidEntryPoint import org.koitharu.kotatsu.R import org.koitharu.kotatsu.core.ui.BaseActivity -import org.koitharu.kotatsu.core.util.ext.consumeInsetsAsPadding +import org.koitharu.kotatsu.core.util.ext.consumeAllSystemBarsInsets import org.koitharu.kotatsu.core.util.ext.decodeRegion import org.koitharu.kotatsu.core.util.ext.enqueueWith import org.koitharu.kotatsu.core.util.ext.indicator @@ -28,6 +28,7 @@ import org.koitharu.kotatsu.core.util.ext.observe import org.koitharu.kotatsu.core.util.ext.observeEvent import org.koitharu.kotatsu.core.util.ext.setChecked import org.koitharu.kotatsu.core.util.ext.setValueRounded +import org.koitharu.kotatsu.core.util.ext.systemBarsInsets import org.koitharu.kotatsu.databinding.ActivityColorFilterBinding import org.koitharu.kotatsu.parsers.model.MangaPage import org.koitharu.kotatsu.parsers.util.format @@ -54,7 +55,6 @@ class ColorFilterConfigActivity : setDisplayHomeAsUpEnabled(true) setHomeAsUpIndicator(materialR.drawable.abc_ic_clear_material) } - viewBinding.root.consumeInsetsAsPadding(Gravity.FILL) viewBinding.sliderBrightness.addOnChangeListener(this) viewBinding.sliderContrast.addOnChangeListener(this) val formatter = PercentLabelFormatter(resources) @@ -75,6 +75,20 @@ class ColorFilterConfigActivity : loadPreview(viewModel.preview) } + override fun onApplyWindowInsets( + v: View, + insets: WindowInsetsCompat + ): WindowInsetsCompat { + val barsInsets = insets.systemBarsInsets + viewBinding.root.setPadding( + barsInsets.left, + barsInsets.top, + barsInsets.right, + barsInsets.bottom, + ) + return insets.consumeAllSystemBarsInsets() + } + override fun onValueChange(slider: Slider, value: Float, fromUser: Boolean) { if (fromUser) { when (slider.id) { diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/config/ReaderConfigSheet.kt b/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/config/ReaderConfigSheet.kt index e7bf450d0..3669539e5 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/config/ReaderConfigSheet.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/config/ReaderConfigSheet.kt @@ -5,8 +5,10 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.CompoundButton +import androidx.core.view.WindowInsetsCompat import androidx.core.view.isGone import androidx.core.view.isVisible +import androidx.core.view.updatePadding import androidx.fragment.app.activityViewModels import androidx.lifecycle.lifecycleScope import com.google.android.material.button.MaterialButtonToggleGroup @@ -25,6 +27,7 @@ import org.koitharu.kotatsu.core.prefs.AppSettings import org.koitharu.kotatsu.core.prefs.ReaderMode import org.koitharu.kotatsu.core.prefs.observeAsStateFlow import org.koitharu.kotatsu.core.ui.sheet.BaseAdaptiveSheet +import org.koitharu.kotatsu.core.util.ext.consume import org.koitharu.kotatsu.core.util.ext.findParentCallback import org.koitharu.kotatsu.core.util.ext.observe import org.koitharu.kotatsu.core.util.ext.viewLifecycleScope @@ -123,6 +126,14 @@ class ReaderConfigSheet : } } + override fun onApplyWindowInsets(v: View, insets: WindowInsetsCompat): WindowInsetsCompat { + val typeMask = WindowInsetsCompat.Type.systemBars() + viewBinding?.scrollView?.updatePadding( + bottom = insets.getInsets(typeMask).bottom, + ) + return insets.consume(v, typeMask, bottom = true) + } + override fun onClick(v: View) { when (v.id) { R.id.button_settings -> { diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/pager/BaseReaderFragment.kt b/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/pager/BaseReaderFragment.kt index 2288b7710..57fe76149 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/pager/BaseReaderFragment.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/pager/BaseReaderFragment.kt @@ -1,6 +1,8 @@ package org.koitharu.kotatsu.reader.ui.pager import android.os.Bundle +import android.view.View +import androidx.core.view.WindowInsetsCompat import androidx.fragment.app.activityViewModels import androidx.viewbinding.ViewBinding import org.koitharu.kotatsu.core.prefs.ReaderAnimation @@ -31,6 +33,8 @@ abstract class BaseReaderFragment : BaseFragment(), ZoomCont } } + override fun onApplyWindowInsets(v: View, insets: WindowInsetsCompat): WindowInsetsCompat = insets + override fun onPause() { super.onPause() viewModel.saveCurrentState(getCurrentState()) diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/scrobbling/common/ui/config/ScrobblerConfigActivity.kt b/app/src/main/kotlin/org/koitharu/kotatsu/scrobbling/common/ui/config/ScrobblerConfigActivity.kt index 2586a9bd4..d3606aeba 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/scrobbling/common/ui/config/ScrobblerConfigActivity.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/scrobbling/common/ui/config/ScrobblerConfigActivity.kt @@ -2,9 +2,10 @@ package org.koitharu.kotatsu.scrobbling.common.ui.config import android.content.Intent import android.os.Bundle -import android.view.Gravity import android.view.View import androidx.activity.viewModels +import androidx.core.view.WindowInsetsCompat +import androidx.core.view.updatePadding import coil3.ImageLoader import coil3.request.error import coil3.request.fallback @@ -16,13 +17,14 @@ import org.koitharu.kotatsu.core.exceptions.resolve.SnackbarErrorObserver import org.koitharu.kotatsu.core.nav.router import org.koitharu.kotatsu.core.ui.BaseActivity import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener -import org.koitharu.kotatsu.core.util.ext.consumeInsetsAsPadding +import org.koitharu.kotatsu.core.util.ext.consumeAllSystemBarsInsets import org.koitharu.kotatsu.core.util.ext.disposeImageRequest import org.koitharu.kotatsu.core.util.ext.enqueueWith import org.koitharu.kotatsu.core.util.ext.newImageRequest import org.koitharu.kotatsu.core.util.ext.observe import org.koitharu.kotatsu.core.util.ext.observeEvent import org.koitharu.kotatsu.core.util.ext.showOrHide +import org.koitharu.kotatsu.core.util.ext.systemBarsInsets import org.koitharu.kotatsu.databinding.ActivityScrobblerConfigBinding import org.koitharu.kotatsu.list.ui.adapter.TypedListSpacingDecoration import org.koitharu.kotatsu.scrobbling.common.domain.model.ScrobblerUser @@ -48,7 +50,6 @@ class ScrobblerConfigActivity : BaseActivity(), val listAdapter = ScrobblingMangaAdapter(this, coil, this) with(viewBinding.recyclerView) { - consumeInsetsAsPadding(Gravity.START or Gravity.END or Gravity.BOTTOM) adapter = listAdapter setHasFixedSize(true) val decoration = TypedListSpacingDecoration(context, false) @@ -73,6 +74,23 @@ class ScrobblerConfigActivity : BaseActivity(), processIntent(intent) } + override fun onApplyWindowInsets(v: View, insets: WindowInsetsCompat): WindowInsetsCompat { + val barsInsets = insets.systemBarsInsets + val basePadding = v.resources.getDimensionPixelOffset(R.dimen.list_spacing_normal) + viewBinding.appbar.updatePadding( + top = barsInsets.top, + left = barsInsets.left, + right = barsInsets.right, + ) + viewBinding.recyclerView.setPadding( + barsInsets.left + basePadding, + barsInsets.top + basePadding, + barsInsets.right + basePadding, + barsInsets.bottom + basePadding, + ) + return insets.consumeAllSystemBarsInsets() + } + override fun onItemClick(item: ScrobblingInfo, view: View) { router.openDetails(item.mangaId) } diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/scrobbling/common/ui/selector/ScrobblingSelectorSheet.kt b/app/src/main/kotlin/org/koitharu/kotatsu/scrobbling/common/ui/selector/ScrobblingSelectorSheet.kt index c4b319de2..7118e9504 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/scrobbling/common/ui/selector/ScrobblingSelectorSheet.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/scrobbling/common/ui/selector/ScrobblingSelectorSheet.kt @@ -7,6 +7,8 @@ import android.view.View import android.view.ViewGroup import android.widget.Toast import androidx.appcompat.widget.SearchView +import androidx.core.view.WindowInsetsCompat +import androidx.core.view.updatePadding import androidx.fragment.app.viewModels import androidx.recyclerview.widget.AsyncListDiffer import androidx.recyclerview.widget.RecyclerView.NO_ID @@ -22,6 +24,7 @@ import org.koitharu.kotatsu.core.ui.list.PaginationScrollListener import org.koitharu.kotatsu.core.ui.sheet.BaseAdaptiveSheet import org.koitharu.kotatsu.core.ui.util.CollapseActionViewCallback import org.koitharu.kotatsu.core.util.RecyclerViewScrollCallback +import org.koitharu.kotatsu.core.util.ext.consume import org.koitharu.kotatsu.core.util.ext.firstVisibleItemPosition import org.koitharu.kotatsu.core.util.ext.getDisplayMessage import org.koitharu.kotatsu.core.util.ext.observe @@ -114,6 +117,15 @@ class ScrobblingSelectorSheet : paginationScrollListener = null } + override fun onApplyWindowInsets(v: View, insets: WindowInsetsCompat): WindowInsetsCompat { + val typeMask = WindowInsetsCompat.Type.systemBars() + val basePadding = v.resources.getDimensionPixelOffset(R.dimen.list_spacing_normal) + viewBinding?.recyclerView?.updatePadding( + bottom = basePadding + insets.getInsets(typeMask).bottom, + ) + return insets.consume(v, typeMask, bottom = true) + } + override fun onCurrentListChanged(previousList: MutableList, currentList: MutableList) { if (previousList.singleOrNull() is LoadingFooter) { val rv = viewBinding?.recyclerView ?: return diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/scrobbling/kitsu/ui/KitsuAuthActivity.kt b/app/src/main/kotlin/org/koitharu/kotatsu/scrobbling/kitsu/ui/KitsuAuthActivity.kt index d50b47e50..4acc0bdcf 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/scrobbling/kitsu/ui/KitsuAuthActivity.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/scrobbling/kitsu/ui/KitsuAuthActivity.kt @@ -4,13 +4,14 @@ import android.annotation.SuppressLint import android.content.Intent import android.os.Bundle import android.text.Editable -import android.view.Gravity import android.view.View import androidx.core.net.toUri +import androidx.core.view.WindowInsetsCompat import org.koitharu.kotatsu.R import org.koitharu.kotatsu.core.ui.BaseActivity import org.koitharu.kotatsu.core.ui.util.DefaultTextWatcher -import org.koitharu.kotatsu.core.util.ext.consumeInsetsAsPadding +import org.koitharu.kotatsu.core.util.ext.consumeAllSystemBarsInsets +import org.koitharu.kotatsu.core.util.ext.systemBarsInsets import org.koitharu.kotatsu.databinding.ActivityKitsuAuthBinding import org.koitharu.kotatsu.parsers.util.urlEncoded @@ -21,13 +22,27 @@ class KitsuAuthActivity : BaseActivity(), View.OnClick override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(ActivityKitsuAuthBinding.inflate(layoutInflater)) - viewBinding.root.consumeInsetsAsPadding(Gravity.FILL) viewBinding.buttonCancel.setOnClickListener(this) viewBinding.buttonDone.setOnClickListener(this) viewBinding.editEmail.addTextChangedListener(this) viewBinding.editPassword.addTextChangedListener(this) } + override fun onApplyWindowInsets( + v: View, + insets: WindowInsetsCompat + ): WindowInsetsCompat { + val barsInsets = insets.systemBarsInsets + val basePadding = resources.getDimensionPixelOffset(R.dimen.screen_padding) + viewBinding.root.setPadding( + barsInsets.left + basePadding, + barsInsets.top + basePadding, + barsInsets.right + basePadding, + barsInsets.bottom + basePadding, + ) + return insets.consumeAllSystemBarsInsets() + } + override fun onClick(v: View) { when (v.id) { R.id.button_cancel -> finish() diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/search/ui/MangaListActivity.kt b/app/src/main/kotlin/org/koitharu/kotatsu/search/ui/MangaListActivity.kt index 2204ed113..3e720f917 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/search/ui/MangaListActivity.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/search/ui/MangaListActivity.kt @@ -5,8 +5,6 @@ import android.view.View import android.view.ViewGroup import androidx.core.graphics.drawable.toDrawable import androidx.core.os.bundleOf -import androidx.core.view.OnApplyWindowInsetsListener -import androidx.core.view.ViewCompat import androidx.core.view.WindowInsetsCompat import androidx.core.view.updateLayoutParams import androidx.core.view.updatePaddingRelative @@ -32,7 +30,7 @@ import org.koitharu.kotatsu.core.nav.router import org.koitharu.kotatsu.core.ui.BaseActivity import org.koitharu.kotatsu.core.ui.model.titleRes import org.koitharu.kotatsu.core.util.ViewBadge -import org.koitharu.kotatsu.core.util.ext.consumeRelative +import org.koitharu.kotatsu.core.util.ext.consumeSystemBarsInsets import org.koitharu.kotatsu.core.util.ext.end import org.koitharu.kotatsu.core.util.ext.getParcelableExtraCompat import org.koitharu.kotatsu.core.util.ext.getSerializableExtraCompat @@ -60,7 +58,6 @@ class MangaListActivity : BaseActivity(), AppBarOwner, View.OnClickListener, FilterCoordinator.Owner, - OnApplyWindowInsetsListener, AppBarLayout.OnOffsetChangedListener { override val appBar: AppBarLayout @@ -82,8 +79,6 @@ class MangaListActivity : supportActionBar?.setDisplayHomeAsUpEnabled(true) if (viewBinding.containerFilterHeader != null) { viewBinding.appbar.addOnOffsetChangedListener(this) - } else { - ViewCompat.setOnApplyWindowInsetsListener(viewBinding.root, this) } viewBinding.buttonOrder?.setOnClickListener(this) title = source.getTitle(this) @@ -113,17 +108,10 @@ class MangaListActivity : } viewBinding.appbar.updatePaddingRelative( top = barsInsets.top, + end = if (viewBinding.cardSide == null) barsInsets.end(v) else 0, start = barsInsets.start(v), ) - return WindowInsetsCompat.Builder(insets) - .setInsets( - WindowInsetsCompat.Type.systemBars(), - barsInsets.consumeRelative( - v, - top = true, - end = true, - ), - ).build() + return insets.consumeSystemBarsInsets(v, top = true, end = true) } override fun onClick(v: View) { diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/search/ui/multi/SearchActivity.kt b/app/src/main/kotlin/org/koitharu/kotatsu/search/ui/multi/SearchActivity.kt index 65fc666b2..de404b168 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/search/ui/multi/SearchActivity.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/search/ui/multi/SearchActivity.kt @@ -1,13 +1,14 @@ package org.koitharu.kotatsu.search.ui.multi import android.os.Bundle -import android.view.Gravity import android.view.Menu import android.view.MenuInflater import android.view.MenuItem import android.view.View import androidx.activity.viewModels import androidx.appcompat.view.ActionMode +import androidx.core.view.WindowInsetsCompat +import androidx.core.view.updatePadding import coil3.ImageLoader import dagger.hilt.android.AndroidEntryPoint import org.koitharu.kotatsu.R @@ -19,10 +20,11 @@ import org.koitharu.kotatsu.core.ui.list.ListSelectionController import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener import org.koitharu.kotatsu.core.ui.widgets.TipView import org.koitharu.kotatsu.core.util.ShareHelper -import org.koitharu.kotatsu.core.util.ext.consumeInsetsAsPadding +import org.koitharu.kotatsu.core.util.ext.consumeAllSystemBarsInsets import org.koitharu.kotatsu.core.util.ext.invalidateNestedItemDecorations import org.koitharu.kotatsu.core.util.ext.observe import org.koitharu.kotatsu.core.util.ext.observeEvent +import org.koitharu.kotatsu.core.util.ext.systemBarsInsets import org.koitharu.kotatsu.databinding.ActivitySearchBinding import org.koitharu.kotatsu.list.domain.ListFilterOption import org.koitharu.kotatsu.list.ui.MangaSelectionDecoration @@ -91,7 +93,6 @@ class SearchActivity : selectionDecoration = selectionDecoration, ) viewBinding.recyclerView.adapter = adapter - viewBinding.recyclerView.consumeInsetsAsPadding(Gravity.START or Gravity.END or Gravity.BOTTOM) viewBinding.recyclerView.setHasFixedSize(true) viewBinding.recyclerView.addItemDecoration(TypedListSpacingDecoration(this, true)) @@ -106,6 +107,22 @@ class SearchActivity : viewModel.onError.observeEvent(this, SnackbarErrorObserver(viewBinding.recyclerView, null)) } + override fun onApplyWindowInsets(v: View, insets: WindowInsetsCompat): WindowInsetsCompat { + val barsInsets = insets.systemBarsInsets + viewBinding.appbar.updatePadding( + top = barsInsets.top, + left = barsInsets.left, + right = barsInsets.right, + ) + viewBinding.recyclerView.setPadding( + barsInsets.left, + barsInsets.top, + barsInsets.right, + barsInsets.bottom, + ) + return insets.consumeAllSystemBarsInsets() + } + override fun onItemClick(item: Manga, view: View) { if (!selectionController.onItemClick(item.id)) { router.openDetails(item) diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/search/ui/suggestion/SearchSuggestionFragment.kt b/app/src/main/kotlin/org/koitharu/kotatsu/search/ui/suggestion/SearchSuggestionFragment.kt index cd9accc5f..08bc21bdf 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/search/ui/suggestion/SearchSuggestionFragment.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/search/ui/suggestion/SearchSuggestionFragment.kt @@ -1,9 +1,10 @@ package org.koitharu.kotatsu.search.ui.suggestion import android.os.Bundle -import android.view.Gravity import android.view.LayoutInflater +import android.view.View import android.view.ViewGroup +import androidx.core.view.WindowInsetsCompat import androidx.fragment.app.activityViewModels import androidx.recyclerview.widget.ItemTouchHelper import coil3.ImageLoader @@ -11,7 +12,7 @@ import dagger.hilt.android.AndroidEntryPoint import org.koitharu.kotatsu.core.os.VoiceInputContract import org.koitharu.kotatsu.core.ui.BaseFragment import org.koitharu.kotatsu.core.util.ext.addMenuProvider -import org.koitharu.kotatsu.core.util.ext.consumeInsetsAsPadding +import org.koitharu.kotatsu.core.util.ext.consumeAllSystemBarsInsets import org.koitharu.kotatsu.core.util.ext.observe import org.koitharu.kotatsu.databinding.FragmentSearchSuggestionBinding import org.koitharu.kotatsu.search.ui.suggestion.adapter.SearchSuggestionAdapter @@ -47,12 +48,22 @@ class SearchSuggestionFragment : addMenuProvider(SearchSuggestionMenuProvider(binding.root.context, voiceInputLauncher, viewModel)) binding.root.adapter = adapter binding.root.setHasFixedSize(true) - binding.root.consumeInsetsAsPadding(Gravity.BOTTOM or Gravity.START or Gravity.END) viewModel.suggestion.observe(viewLifecycleOwner, adapter) ItemTouchHelper(SearchSuggestionItemCallback(this)) .attachToRecyclerView(binding.root) } + override fun onApplyWindowInsets(v: View, insets: WindowInsetsCompat): WindowInsetsCompat { + val barsInsets = insets.getInsets(WindowInsetsCompat.Type.ime() or WindowInsetsCompat.Type.systemBars()) + v.setPadding( + barsInsets.left, + 0, + barsInsets.right, + barsInsets.bottom, + ) + return insets.consumeAllSystemBarsInsets() + } + override fun onRemoveQuery(query: String) { viewModel.deleteQuery(query) } diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/settings/SettingsActivity.kt b/app/src/main/kotlin/org/koitharu/kotatsu/settings/SettingsActivity.kt index 62a9225d1..f8409a3bd 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/settings/SettingsActivity.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/settings/SettingsActivity.kt @@ -5,8 +5,6 @@ import android.os.Bundle import android.view.View import android.view.ViewGroup import androidx.activity.viewModels -import androidx.core.view.OnApplyWindowInsetsListener -import androidx.core.view.ViewCompat import androidx.core.view.WindowInsetsCompat import androidx.core.view.isVisible import androidx.core.view.updateLayoutParams @@ -45,7 +43,6 @@ import org.koitharu.kotatsu.settings.userdata.UserDataSettingsFragment @AndroidEntryPoint class SettingsActivity : BaseActivity(), - OnApplyWindowInsetsListener, PreferenceFragmentCompat.OnPreferenceStartFragmentCallback, AppBarOwner { @@ -60,7 +57,6 @@ class SettingsActivity : override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(ActivitySettingsBinding.inflate(layoutInflater)) - ViewCompat.setOnApplyWindowInsetsListener(viewBinding.root, this) supportActionBar?.setDisplayHomeAsUpEnabled(true) val fm = supportFragmentManager val currentFragment = fm.findFragmentById(R.id.container) diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/settings/about/AppUpdateActivity.kt b/app/src/main/kotlin/org/koitharu/kotatsu/settings/about/AppUpdateActivity.kt index d220d4bc6..ecd0d1d78 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/settings/about/AppUpdateActivity.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/settings/about/AppUpdateActivity.kt @@ -15,6 +15,7 @@ import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.viewModels import androidx.core.content.ContextCompat import androidx.core.text.buildSpannedString +import androidx.core.view.WindowInsetsCompat import com.google.android.material.snackbar.Snackbar import dagger.hilt.android.AndroidEntryPoint import io.noties.markwon.Markwon @@ -26,12 +27,14 @@ import org.koitharu.kotatsu.core.github.AppVersion import org.koitharu.kotatsu.core.nav.router import org.koitharu.kotatsu.core.ui.BaseActivity import org.koitharu.kotatsu.core.util.FileSize +import org.koitharu.kotatsu.core.util.ext.consumeAllSystemBarsInsets import org.koitharu.kotatsu.core.util.ext.getDisplayMessage import org.koitharu.kotatsu.core.util.ext.observe import org.koitharu.kotatsu.core.util.ext.observeEvent import org.koitharu.kotatsu.core.util.ext.printStackTraceDebug import org.koitharu.kotatsu.core.util.ext.setTextAndVisible import org.koitharu.kotatsu.core.util.ext.showOrHide +import org.koitharu.kotatsu.core.util.ext.systemBarsInsets import org.koitharu.kotatsu.core.util.ext.textAndVisible import org.koitharu.kotatsu.databinding.ActivityAppUpdateBinding @@ -83,6 +86,21 @@ class AppUpdateActivity : BaseActivity(), View.OnClick super.onDestroy() } + override fun onApplyWindowInsets( + v: View, + insets: WindowInsetsCompat + ): WindowInsetsCompat { + val barsInsets = insets.systemBarsInsets + val basePadding = resources.getDimensionPixelOffset(R.dimen.screen_padding) + viewBinding.root.setPadding( + barsInsets.left + basePadding, + barsInsets.top + basePadding, + barsInsets.right + basePadding, + barsInsets.bottom + basePadding, + ) + return insets.consumeAllSystemBarsInsets() + } + override fun onClick(v: View) { when (v.id) { R.id.button_cancel -> finishAfterTransition() diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/settings/nav/NavConfigFragment.kt b/app/src/main/kotlin/org/koitharu/kotatsu/settings/nav/NavConfigFragment.kt index 2baf0756d..369376ed0 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/settings/nav/NavConfigFragment.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/settings/nav/NavConfigFragment.kt @@ -5,6 +5,7 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import androidx.core.view.WindowInsetsCompat import androidx.fragment.app.viewModels import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.RecyclerView @@ -17,7 +18,12 @@ import org.koitharu.kotatsu.core.ui.dialog.buildAlertDialog import org.koitharu.kotatsu.core.ui.dialog.setRecyclerViewList import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener import org.koitharu.kotatsu.core.ui.util.RecyclerViewOwner +import org.koitharu.kotatsu.core.util.ext.consumeAllSystemBarsInsets +import org.koitharu.kotatsu.core.util.ext.container +import org.koitharu.kotatsu.core.util.ext.end import org.koitharu.kotatsu.core.util.ext.observe +import org.koitharu.kotatsu.core.util.ext.start +import org.koitharu.kotatsu.core.util.ext.systemBarsInsets import org.koitharu.kotatsu.databinding.FragmentSettingsSourcesBinding import org.koitharu.kotatsu.list.ui.adapter.ListItemType import org.koitharu.kotatsu.list.ui.model.ListModel @@ -60,6 +66,19 @@ class NavConfigFragment : BaseFragment(), Recycl viewModel.content.observe(viewLifecycleOwner, navConfigAdapter) } + override fun onApplyWindowInsets(v: View, insets: WindowInsetsCompat): WindowInsetsCompat { + val barsInsets = insets.systemBarsInsets + val isTablet = !resources.getBoolean(R.bool.is_tablet) + val isMaster = container?.id == R.id.container_master + v.setPaddingRelative( + if (isTablet && !isMaster) 0 else barsInsets.start(v), + 0, + if (isTablet && isMaster) 0 else barsInsets.end(v), + barsInsets.bottom, + ) + return insets.consumeAllSystemBarsInsets() + } + override fun onResume() { super.onResume() activity?.setTitle(R.string.main_screen_sections) diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/settings/protect/ProtectSetupActivity.kt b/app/src/main/kotlin/org/koitharu/kotatsu/settings/protect/ProtectSetupActivity.kt index a2e0d5d82..e7ca825e0 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/settings/protect/ProtectSetupActivity.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/settings/protect/ProtectSetupActivity.kt @@ -4,7 +4,6 @@ import android.content.pm.PackageManager import android.os.Build import android.os.Bundle import android.text.Editable -import android.view.Gravity import android.view.KeyEvent import android.view.View import android.view.WindowManager @@ -12,15 +11,17 @@ import android.view.inputmethod.EditorInfo import android.widget.CompoundButton import android.widget.TextView import androidx.activity.viewModels +import androidx.core.view.WindowInsetsCompat import androidx.core.view.isGone import androidx.core.view.isVisible import dagger.hilt.android.AndroidEntryPoint import org.koitharu.kotatsu.R import org.koitharu.kotatsu.core.ui.BaseActivity import org.koitharu.kotatsu.core.ui.util.DefaultTextWatcher -import org.koitharu.kotatsu.core.util.ext.consumeInsetsAsPadding +import org.koitharu.kotatsu.core.util.ext.consumeAllSystemBarsInsets import org.koitharu.kotatsu.core.util.ext.observe import org.koitharu.kotatsu.core.util.ext.observeEvent +import org.koitharu.kotatsu.core.util.ext.systemBarsInsets import org.koitharu.kotatsu.databinding.ActivitySetupProtectBinding private const val MIN_PASSWORD_LENGTH = 4 @@ -39,7 +40,6 @@ class ProtectSetupActivity : super.onCreate(savedInstanceState) window.addFlags(WindowManager.LayoutParams.FLAG_SECURE) setContentView(ActivitySetupProtectBinding.inflate(layoutInflater)) - viewBinding.root.consumeInsetsAsPadding(Gravity.FILL) viewBinding.editPassword.addTextChangedListener(this) viewBinding.editPassword.setOnEditorActionListener(this) viewBinding.buttonNext.setOnClickListener(this) @@ -60,6 +60,18 @@ class ProtectSetupActivity : } } + override fun onApplyWindowInsets(v: View, insets: WindowInsetsCompat): WindowInsetsCompat { + val barsInsets = insets.systemBarsInsets + val basePadding = resources.getDimensionPixelOffset(R.dimen.screen_padding) + viewBinding.root.setPadding( + barsInsets.left + basePadding, + barsInsets.top + basePadding, + barsInsets.right + basePadding, + barsInsets.bottom + basePadding, + ) + return insets.consumeAllSystemBarsInsets() + } + override fun onClick(v: View) { when (v.id) { R.id.button_cancel -> finish() diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/settings/reader/ReaderTapGridConfigActivity.kt b/app/src/main/kotlin/org/koitharu/kotatsu/settings/reader/ReaderTapGridConfigActivity.kt index fe907c48a..aaea17e62 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/settings/reader/ReaderTapGridConfigActivity.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/settings/reader/ReaderTapGridConfigActivity.kt @@ -4,7 +4,6 @@ import android.content.DialogInterface import android.graphics.drawable.Drawable import android.graphics.drawable.LayerDrawable import android.os.Bundle -import android.view.Gravity import android.view.Menu import android.view.MenuItem import android.view.View @@ -14,14 +13,16 @@ import androidx.core.graphics.ColorUtils import androidx.core.graphics.drawable.toDrawable import androidx.core.text.bold import androidx.core.text.buildSpannedString +import androidx.core.view.WindowInsetsCompat import com.google.android.material.dialog.MaterialAlertDialogBuilder import dagger.hilt.android.AndroidEntryPoint import org.koitharu.kotatsu.R import org.koitharu.kotatsu.core.ui.BaseActivity -import org.koitharu.kotatsu.core.util.ext.consumeInsetsAsPadding +import org.koitharu.kotatsu.core.util.ext.consumeAllSystemBarsInsets import org.koitharu.kotatsu.core.util.ext.findKeyByValue import org.koitharu.kotatsu.core.util.ext.getThemeDrawable import org.koitharu.kotatsu.core.util.ext.observe +import org.koitharu.kotatsu.core.util.ext.systemBarsInsets import org.koitharu.kotatsu.databinding.ActivityReaderTapActionsBinding import org.koitharu.kotatsu.reader.domain.TapGridArea import org.koitharu.kotatsu.reader.ui.tapgrid.TapAction @@ -39,7 +40,6 @@ class ReaderTapGridConfigActivity : BaseActivity(), override fun onViewBindingCreated(binding: FragmentSearchSuggestionBinding, savedInstanceState: Bundle?) { super.onViewBindingCreated(binding, savedInstanceState) - binding.root.consumeInsetsAsPadding(Gravity.FILL_HORIZONTAL or Gravity.BOTTOM) val adapter = BaseListAdapter() .addDelegate(ListItemType.NAV_ITEM, settingsItemAD(this)) adapter.addListListener(this) @@ -39,6 +38,18 @@ class SettingsSearchFragment : BaseFragment(), viewModel.content.observe(viewLifecycleOwner, adapter) } + override fun onApplyWindowInsets(v: View, insets: WindowInsetsCompat): WindowInsetsCompat { + val type = WindowInsetsCompat.Type.ime() or WindowInsetsCompat.Type.systemBars() + val barsInsets = insets.getInsets(type) + v.setPadding( + barsInsets.left, + 0, + barsInsets.right, + barsInsets.bottom, + ) + return insets.consumeAll(type) + } + override fun onItemClick(item: SettingsItem, view: View) = viewModel.navigateToPreference(item) override fun onCurrentListChanged( diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/settings/sources/auth/SourceAuthActivity.kt b/app/src/main/kotlin/org/koitharu/kotatsu/settings/sources/auth/SourceAuthActivity.kt index 6917786f8..3ac2782f6 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/settings/sources/auth/SourceAuthActivity.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/settings/sources/auth/SourceAuthActivity.kt @@ -5,9 +5,12 @@ import android.content.Context import android.content.Intent import android.os.Bundle import android.view.MenuItem +import android.view.View import android.widget.Toast import androidx.activity.result.contract.ActivityResultContract +import androidx.core.view.WindowInsetsCompat import androidx.core.view.isVisible +import androidx.core.view.updatePadding import dagger.hilt.android.AndroidEntryPoint import org.koitharu.kotatsu.R import org.koitharu.kotatsu.browser.BrowserCallback @@ -21,6 +24,7 @@ import org.koitharu.kotatsu.core.parser.MangaRepository import org.koitharu.kotatsu.core.parser.ParserMangaRepository import org.koitharu.kotatsu.core.ui.BaseActivity import org.koitharu.kotatsu.core.util.ext.configureForParser +import org.koitharu.kotatsu.core.util.ext.consumeAll import org.koitharu.kotatsu.databinding.ActivityBrowserBinding import org.koitharu.kotatsu.parsers.MangaParserAuthProvider import org.koitharu.kotatsu.parsers.model.MangaParserSource @@ -84,6 +88,25 @@ class SourceAuthActivity : BaseActivity(), BrowserCallba viewBinding.webView.destroy() } + override fun onApplyWindowInsets( + v: View, + insets: WindowInsetsCompat + ): WindowInsetsCompat { + val type = WindowInsetsCompat.Type.systemBars() or WindowInsetsCompat.Type.ime() + val barsInsets = insets.getInsets(type) + viewBinding.webView.updatePadding( + left = barsInsets.left, + right = barsInsets.right, + bottom = barsInsets.bottom, + ) + viewBinding.appbar.updatePadding( + left = barsInsets.left, + right = barsInsets.right, + top = barsInsets.top, + ) + return insets.consumeAll(type) + } + override fun onOptionsItemSelected(item: MenuItem): Boolean = when (item.itemId) { android.R.id.home -> { viewBinding.webView.stopLoading() diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/settings/sources/catalog/SourcesCatalogActivity.kt b/app/src/main/kotlin/org/koitharu/kotatsu/settings/sources/catalog/SourcesCatalogActivity.kt index 5caec0235..e1437187a 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/settings/sources/catalog/SourcesCatalogActivity.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/settings/sources/catalog/SourcesCatalogActivity.kt @@ -8,8 +8,6 @@ import androidx.activity.viewModels import androidx.appcompat.widget.PopupMenu import androidx.appcompat.widget.SearchView import androidx.core.graphics.Insets -import androidx.core.view.OnApplyWindowInsetsListener -import androidx.core.view.ViewCompat import androidx.core.view.WindowInsetsCompat import androidx.core.view.updatePadding import coil3.ImageLoader @@ -40,7 +38,6 @@ import javax.inject.Inject @AndroidEntryPoint class SourcesCatalogActivity : BaseActivity(), OnListItemClickListener, - OnApplyWindowInsetsListener, AppBarOwner, MenuItem.OnActionExpandListener, ChipsView.OnChipClickListener { @@ -57,7 +54,6 @@ class SourcesCatalogActivity : BaseActivity(), super.onCreate(savedInstanceState) setContentView(ActivitySourcesCatalogBinding.inflate(layoutInflater)) supportActionBar?.setDisplayHomeAsUpEnabled(true) - ViewCompat.setOnApplyWindowInsetsListener(viewBinding.root, this) val sourcesAdapter = SourcesCatalogAdapter(this, coil, this) with(viewBinding.recyclerView) { setHasFixedSize(true) diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/settings/sources/manage/SourcesManageFragment.kt b/app/src/main/kotlin/org/koitharu/kotatsu/settings/sources/manage/SourcesManageFragment.kt index 569eefac3..54cb47dd7 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/settings/sources/manage/SourcesManageFragment.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/settings/sources/manage/SourcesManageFragment.kt @@ -1,14 +1,15 @@ package org.koitharu.kotatsu.settings.sources.manage import android.os.Bundle -import android.view.Gravity import android.view.LayoutInflater import android.view.Menu import android.view.MenuInflater import android.view.MenuItem +import android.view.View import android.view.ViewGroup import androidx.appcompat.widget.SearchView import androidx.core.view.MenuProvider +import androidx.core.view.WindowInsetsCompat import androidx.fragment.app.viewModels import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.RecyclerView @@ -23,10 +24,14 @@ import org.koitharu.kotatsu.core.ui.BaseFragment import org.koitharu.kotatsu.core.ui.util.RecyclerViewOwner import org.koitharu.kotatsu.core.ui.util.ReversibleActionObserver import org.koitharu.kotatsu.core.util.ext.addMenuProvider -import org.koitharu.kotatsu.core.util.ext.consumeInsetsAsPadding +import org.koitharu.kotatsu.core.util.ext.consumeAllSystemBarsInsets +import org.koitharu.kotatsu.core.util.ext.container +import org.koitharu.kotatsu.core.util.ext.end import org.koitharu.kotatsu.core.util.ext.getItem import org.koitharu.kotatsu.core.util.ext.observe import org.koitharu.kotatsu.core.util.ext.observeEvent +import org.koitharu.kotatsu.core.util.ext.start +import org.koitharu.kotatsu.core.util.ext.systemBarsInsets import org.koitharu.kotatsu.core.util.ext.viewLifecycleScope import org.koitharu.kotatsu.databinding.FragmentSettingsSourcesBinding import org.koitharu.kotatsu.main.ui.owners.AppBarOwner @@ -72,7 +77,6 @@ class SourcesManageFragment : sourcesAdapter = SourceConfigAdapter(this, coil, viewLifecycleOwner) with(binding.recyclerView) { setHasFixedSize(true) - consumeInsetsAsPadding(Gravity.START or Gravity.END or Gravity.BOTTOM) adapter = sourcesAdapter reorderHelper = ItemTouchHelper(SourcesReorderCallback()).also { it.attachToRecyclerView(this) @@ -86,6 +90,19 @@ class SourcesManageFragment : addMenuProvider(SourcesMenuProvider()) } + override fun onApplyWindowInsets(v: View, insets: WindowInsetsCompat): WindowInsetsCompat { + val barsInsets = insets.systemBarsInsets + val isTablet = !resources.getBoolean(R.bool.is_tablet) + val isMaster = container?.id == R.id.container_master + v.setPaddingRelative( + if (isTablet && !isMaster) 0 else barsInsets.start(v), + 0, + if (isTablet && isMaster) 0 else barsInsets.end(v), + barsInsets.bottom, + ) + return insets.consumeAllSystemBarsInsets() + } + override fun onResume() { super.onResume() activity?.setTitle(R.string.manage_sources) diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/settings/storage/directories/MangaDirectoriesActivity.kt b/app/src/main/kotlin/org/koitharu/kotatsu/settings/storage/directories/MangaDirectoriesActivity.kt index 23e634c60..f77f54da5 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/settings/storage/directories/MangaDirectoriesActivity.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/settings/storage/directories/MangaDirectoriesActivity.kt @@ -8,9 +8,6 @@ import android.view.View import android.view.ViewGroup import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.viewModels -import androidx.core.graphics.Insets -import androidx.core.view.OnApplyWindowInsetsListener -import androidx.core.view.ViewCompat import androidx.core.view.WindowInsetsCompat import androidx.core.view.isVisible import androidx.core.view.updateLayoutParams @@ -23,6 +20,7 @@ import org.koitharu.kotatsu.core.exceptions.resolve.SnackbarErrorObserver import org.koitharu.kotatsu.core.os.OpenDocumentTreeHelper import org.koitharu.kotatsu.core.ui.BaseActivity import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener +import org.koitharu.kotatsu.core.util.ext.consumeAllSystemBarsInsets import org.koitharu.kotatsu.core.util.ext.observe import org.koitharu.kotatsu.core.util.ext.observeEvent import org.koitharu.kotatsu.core.util.ext.tryLaunch @@ -33,7 +31,7 @@ import org.koitharu.kotatsu.settings.storage.RequestStorageManagerPermissionCont @AndroidEntryPoint class MangaDirectoriesActivity : BaseActivity(), - OnListItemClickListener, View.OnClickListener, OnApplyWindowInsetsListener { + OnListItemClickListener, View.OnClickListener { private val viewModel: MangaDirectoriesViewModel by viewModels() private val pickFileTreeLauncher = OpenDocumentTreeHelper( @@ -64,7 +62,6 @@ class MangaDirectoriesActivity : BaseActivity() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(ActivityMangaDirectoriesBinding.inflate(layoutInflater)) - ViewCompat.setOnApplyWindowInsetsListener(viewBinding.root, this) supportActionBar?.setDisplayHomeAsUpEnabled(true) val adapter = AsyncListDifferDelegationAdapter(DirectoryDiffCallback(), directoryConfigAD(this)) viewBinding.recyclerView.adapter = adapter @@ -105,8 +102,6 @@ class MangaDirectoriesActivity : BaseActivity() viewBinding.recyclerView.updatePadding( bottom = barsInsets.bottom, ) - return WindowInsetsCompat.Builder(insets) - .setInsets(WindowInsetsCompat.Type.systemBars(), Insets.NONE) - .build() + return insets.consumeAllSystemBarsInsets() } } diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/settings/tracker/categories/TrackerCategoriesConfigSheet.kt b/app/src/main/kotlin/org/koitharu/kotatsu/settings/tracker/categories/TrackerCategoriesConfigSheet.kt index d32a578cb..00bdedcc5 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/settings/tracker/categories/TrackerCategoriesConfigSheet.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/settings/tracker/categories/TrackerCategoriesConfigSheet.kt @@ -4,12 +4,15 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import androidx.core.view.WindowInsetsCompat +import androidx.core.view.updatePadding import androidx.fragment.app.viewModels import dagger.hilt.android.AndroidEntryPoint import org.koitharu.kotatsu.R import org.koitharu.kotatsu.core.model.FavouriteCategory import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener import org.koitharu.kotatsu.core.ui.sheet.BaseAdaptiveSheet +import org.koitharu.kotatsu.core.util.ext.consume import org.koitharu.kotatsu.core.util.ext.observe import org.koitharu.kotatsu.databinding.SheetBaseBinding @@ -33,6 +36,14 @@ class TrackerCategoriesConfigSheet : viewModel.content.observe(viewLifecycleOwner, adapter) } + override fun onApplyWindowInsets(v: View, insets: WindowInsetsCompat): WindowInsetsCompat { + val typeMask = WindowInsetsCompat.Type.systemBars() + viewBinding?.recyclerView?.updatePadding( + bottom = insets.getInsets(typeMask).bottom, + ) + return insets.consume(v, typeMask, bottom = true) + } + override fun onItemClick(item: FavouriteCategory, view: View) { viewModel.toggleItem(item) } diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/stats/ui/StatsActivity.kt b/app/src/main/kotlin/org/koitharu/kotatsu/stats/ui/StatsActivity.kt index 1d792a901..964bb3333 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/stats/ui/StatsActivity.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/stats/ui/StatsActivity.kt @@ -10,8 +10,6 @@ import android.widget.CompoundButton import androidx.activity.viewModels import androidx.appcompat.widget.PopupMenu import androidx.core.graphics.Insets -import androidx.core.view.OnApplyWindowInsetsListener -import androidx.core.view.ViewCompat import androidx.core.view.WindowInsetsCompat import androidx.core.view.isGone import androidx.core.view.isVisible @@ -50,7 +48,6 @@ import javax.inject.Inject @AndroidEntryPoint class StatsActivity : BaseActivity(), - OnApplyWindowInsetsListener, OnListItemClickListener, PieChartView.OnSegmentClickListener, AsyncListDiffer.ListListener, @@ -67,7 +64,6 @@ class StatsActivity : BaseActivity(), super.onCreate(savedInstanceState) setContentView(ActivityStatsBinding.inflate(layoutInflater)) supportActionBar?.setDisplayHomeAsUpEnabled(true) - ViewCompat.setOnApplyWindowInsetsListener(viewBinding.root, this) val adapter = BaseListAdapter() .addDelegate(ListItemType.FEED, statsAD(this)) .addListListener(this) diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/stats/ui/sheet/MangaStatsSheet.kt b/app/src/main/kotlin/org/koitharu/kotatsu/stats/ui/sheet/MangaStatsSheet.kt index 8c001b9c4..a101ce6c0 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/stats/ui/sheet/MangaStatsSheet.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/stats/ui/sheet/MangaStatsSheet.kt @@ -5,12 +5,15 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.collection.IntList +import androidx.core.view.WindowInsetsCompat +import androidx.core.view.updatePadding import androidx.fragment.app.viewModels import dagger.hilt.android.AndroidEntryPoint import org.koitharu.kotatsu.R import org.koitharu.kotatsu.core.nav.router import org.koitharu.kotatsu.core.ui.sheet.BaseAdaptiveSheet import org.koitharu.kotatsu.core.util.KotatsuColors +import org.koitharu.kotatsu.core.util.ext.consume import org.koitharu.kotatsu.core.util.ext.observe import org.koitharu.kotatsu.core.util.ext.textAndVisible import org.koitharu.kotatsu.databinding.SheetStatsMangaBinding @@ -40,6 +43,14 @@ class MangaStatsSheet : BaseAdaptiveSheet(), View.OnClic binding.buttonOpen.setOnClickListener(this) } + override fun onApplyWindowInsets(v: View, insets: WindowInsetsCompat): WindowInsetsCompat { + val typeMask = WindowInsetsCompat.Type.systemBars() + viewBinding?.scrollView?.updatePadding( + bottom = insets.getInsets(typeMask).bottom, + ) + return insets.consume(v, typeMask, bottom = true) + } + override fun onClick(v: View) { router.openDetails(viewModel.manga) } diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/sync/ui/SyncAuthActivity.kt b/app/src/main/kotlin/org/koitharu/kotatsu/sync/ui/SyncAuthActivity.kt index 94288ed29..886fc6445 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/sync/ui/SyncAuthActivity.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/sync/ui/SyncAuthActivity.kt @@ -6,12 +6,12 @@ import android.accounts.AccountManager import android.os.Bundle import android.text.Editable import android.text.TextWatcher -import android.view.Gravity import android.view.View import android.widget.Button import android.widget.Toast import androidx.activity.OnBackPressedCallback import androidx.activity.viewModels +import androidx.core.view.WindowInsetsCompat import androidx.core.view.isVisible import androidx.fragment.app.FragmentResultListener import androidx.transition.Fade @@ -21,11 +21,12 @@ import dagger.hilt.android.AndroidEntryPoint import org.koitharu.kotatsu.R import org.koitharu.kotatsu.core.ui.BaseActivity import org.koitharu.kotatsu.core.ui.util.DefaultTextWatcher -import org.koitharu.kotatsu.core.util.ext.consumeInsetsAsPadding +import org.koitharu.kotatsu.core.util.ext.consumeAllSystemBarsInsets import org.koitharu.kotatsu.core.util.ext.getDisplayMessage import org.koitharu.kotatsu.core.util.ext.getParcelableExtraCompat import org.koitharu.kotatsu.core.util.ext.observe import org.koitharu.kotatsu.core.util.ext.observeEvent +import org.koitharu.kotatsu.core.util.ext.systemBarsInsets import org.koitharu.kotatsu.databinding.ActivitySyncAuthBinding import org.koitharu.kotatsu.sync.data.SyncSettings import org.koitharu.kotatsu.sync.domain.SyncAuthResult @@ -42,7 +43,6 @@ class SyncAuthActivity : BaseActivity(), View.OnClickLi override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(ActivitySyncAuthBinding.inflate(layoutInflater)) - viewBinding.root.consumeInsetsAsPadding(Gravity.FILL) accountAuthenticatorResponse = intent.getParcelableExtraCompat(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE) accountAuthenticatorResponse?.onRequestContinued() @@ -68,6 +68,18 @@ class SyncAuthActivity : BaseActivity(), View.OnClickLi pageBackCallback.update() } + override fun onApplyWindowInsets(v: View, insets: WindowInsetsCompat): WindowInsetsCompat { + val barsInsets = insets.systemBarsInsets + val basePadding = resources.getDimensionPixelOffset(R.dimen.screen_padding) + viewBinding.root.setPadding( + barsInsets.left + basePadding, + barsInsets.top + basePadding, + barsInsets.right + basePadding, + barsInsets.bottom + basePadding, + ) + return insets.consumeAllSystemBarsInsets() + } + override fun onClick(v: View) { when (v.id) { R.id.button_cancel -> { diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/tracker/ui/debug/TrackerDebugActivity.kt b/app/src/main/kotlin/org/koitharu/kotatsu/tracker/ui/debug/TrackerDebugActivity.kt index 7e3dc271a..8cb875558 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/tracker/ui/debug/TrackerDebugActivity.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/tracker/ui/debug/TrackerDebugActivity.kt @@ -1,17 +1,19 @@ package org.koitharu.kotatsu.tracker.ui.debug import android.os.Bundle -import android.view.Gravity import android.view.View import androidx.activity.viewModels +import androidx.core.view.WindowInsetsCompat +import androidx.core.view.updatePadding import coil3.ImageLoader import dagger.hilt.android.AndroidEntryPoint import org.koitharu.kotatsu.core.nav.router import org.koitharu.kotatsu.core.ui.BaseActivity import org.koitharu.kotatsu.core.ui.BaseListAdapter import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener -import org.koitharu.kotatsu.core.util.ext.consumeInsetsAsPadding +import org.koitharu.kotatsu.core.util.ext.consumeAllSystemBarsInsets import org.koitharu.kotatsu.core.util.ext.observe +import org.koitharu.kotatsu.core.util.ext.systemBarsInsets import org.koitharu.kotatsu.databinding.ActivityTrackerDebugBinding import org.koitharu.kotatsu.list.ui.adapter.ListItemType import org.koitharu.kotatsu.list.ui.adapter.TypedListSpacingDecoration @@ -32,7 +34,6 @@ class TrackerDebugActivity : BaseActivity(), OnList val tracksAdapter = BaseListAdapter() .addDelegate(ListItemType.FEED, trackDebugAD(this, coil, this)) with(viewBinding.recyclerView) { - consumeInsetsAsPadding(Gravity.START or Gravity.END or Gravity.BOTTOM) setHasFixedSize(true) adapter = tracksAdapter addItemDecoration(TypedListSpacingDecoration(context, false)) @@ -40,6 +41,21 @@ class TrackerDebugActivity : BaseActivity(), OnList viewModel.content.observe(this, tracksAdapter) } + override fun onApplyWindowInsets(v: View, insets: WindowInsetsCompat): WindowInsetsCompat { + val barsInsets = insets.systemBarsInsets + viewBinding.recyclerView.updatePadding( + left = barsInsets.left, + right = barsInsets.right, + bottom = barsInsets.bottom, + ) + viewBinding.appbar.updatePadding( + left = barsInsets.left, + right = barsInsets.right, + top = barsInsets.top, + ) + return insets.consumeAllSystemBarsInsets() + } + override fun onItemClick(item: TrackDebugItem, view: View) { router.openDetails(item.manga) } diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/tracker/ui/feed/FeedFragment.kt b/app/src/main/kotlin/org/koitharu/kotatsu/tracker/ui/feed/FeedFragment.kt index dd11ad2fd..bf87abea1 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/tracker/ui/feed/FeedFragment.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/tracker/ui/feed/FeedFragment.kt @@ -4,6 +4,7 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import androidx.core.view.WindowInsetsCompat import androidx.fragment.app.viewModels import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView @@ -22,6 +23,7 @@ import org.koitharu.kotatsu.core.ui.util.RecyclerViewOwner import org.koitharu.kotatsu.core.ui.util.ReversibleActionObserver import org.koitharu.kotatsu.core.ui.widgets.TipView import org.koitharu.kotatsu.core.util.ext.addMenuProvider +import org.koitharu.kotatsu.core.util.ext.consumeAll import org.koitharu.kotatsu.core.util.ext.observe import org.koitharu.kotatsu.core.util.ext.observeEvent import org.koitharu.kotatsu.databinding.FragmentListBinding @@ -83,6 +85,19 @@ class FeedFragment : viewModel.isRunning.observe(viewLifecycleOwner, this::onIsTrackerRunningChanged) } + override fun onApplyWindowInsets(v: View, insets: WindowInsetsCompat): WindowInsetsCompat { + val typeMask = WindowInsetsCompat.Type.systemBars() + val barsInsets = insets.getInsets(typeMask) + val basePadding = v.resources.getDimensionPixelOffset(R.dimen.list_spacing_normal) + viewBinding?.recyclerView?.setPadding( + left = barsInsets.left + basePadding, + top = basePadding, + right = barsInsets.right + basePadding, + bottom = barsInsets.bottom + basePadding, + ) + return insets.consumeAll(typeMask) + } + override fun onRefresh() { viewModel.update() } diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/widget/recent/RecentWidgetConfigActivity.kt b/app/src/main/kotlin/org/koitharu/kotatsu/widget/recent/RecentWidgetConfigActivity.kt index 511a8ed22..32d9394a1 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/widget/recent/RecentWidgetConfigActivity.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/widget/recent/RecentWidgetConfigActivity.kt @@ -3,13 +3,14 @@ package org.koitharu.kotatsu.widget.recent import android.appwidget.AppWidgetManager import android.content.Intent import android.os.Bundle -import android.view.Gravity import android.view.View +import androidx.core.view.WindowInsetsCompat import dagger.hilt.android.AndroidEntryPoint import org.koitharu.kotatsu.R import org.koitharu.kotatsu.core.prefs.AppWidgetConfig import org.koitharu.kotatsu.core.ui.BaseActivity -import org.koitharu.kotatsu.core.util.ext.consumeInsetsAsPadding +import org.koitharu.kotatsu.core.util.ext.consumeAllSystemBarsInsets +import org.koitharu.kotatsu.core.util.ext.systemBarsInsets import org.koitharu.kotatsu.databinding.ActivityAppwidgetRecentBinding import com.google.android.material.R as materialR @@ -28,7 +29,6 @@ class RecentWidgetConfigActivity : setHomeAsUpIndicator(materialR.drawable.abc_ic_clear_material) } viewBinding.buttonDone.setOnClickListener(this) - viewBinding.root.consumeInsetsAsPadding(Gravity.START or Gravity.END or Gravity.BOTTOM or Gravity.TOP) val appWidgetId = intent?.getIntExtra( AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID, @@ -41,6 +41,17 @@ class RecentWidgetConfigActivity : viewBinding.switchBackground.isChecked = config.hasBackground } + override fun onApplyWindowInsets(v: View, insets: WindowInsetsCompat): WindowInsetsCompat { + val barsInsets = insets.systemBarsInsets + viewBinding.root.setPadding( + barsInsets.left, + barsInsets.top, + barsInsets.right, + barsInsets.bottom, + ) + return insets.consumeAllSystemBarsInsets() + } + override fun onClick(v: View) { when (v.id) { R.id.button_done -> { diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/widget/shelf/ShelfWidgetConfigActivity.kt b/app/src/main/kotlin/org/koitharu/kotatsu/widget/shelf/ShelfWidgetConfigActivity.kt index d08e8f514..afa3aec44 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/widget/shelf/ShelfWidgetConfigActivity.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/widget/shelf/ShelfWidgetConfigActivity.kt @@ -3,18 +3,20 @@ package org.koitharu.kotatsu.widget.shelf import android.appwidget.AppWidgetManager import android.content.Intent import android.os.Bundle -import android.view.Gravity import android.view.View import androidx.activity.viewModels +import androidx.core.view.WindowInsetsCompat +import androidx.core.view.updatePadding import dagger.hilt.android.AndroidEntryPoint import org.koitharu.kotatsu.R import org.koitharu.kotatsu.core.exceptions.resolve.SnackbarErrorObserver import org.koitharu.kotatsu.core.prefs.AppWidgetConfig import org.koitharu.kotatsu.core.ui.BaseActivity import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener -import org.koitharu.kotatsu.core.util.ext.consumeInsetsAsPadding +import org.koitharu.kotatsu.core.util.ext.consumeAllSystemBarsInsets import org.koitharu.kotatsu.core.util.ext.observe import org.koitharu.kotatsu.core.util.ext.observeEvent +import org.koitharu.kotatsu.core.util.ext.systemBarsInsets import org.koitharu.kotatsu.databinding.ActivityAppwidgetShelfBinding import org.koitharu.kotatsu.widget.shelf.adapter.CategorySelectAdapter import org.koitharu.kotatsu.widget.shelf.model.CategoryItem @@ -40,7 +42,6 @@ class ShelfWidgetConfigActivity : } adapter = CategorySelectAdapter(this) viewBinding.recyclerView.adapter = adapter - viewBinding.recyclerView.consumeInsetsAsPadding(Gravity.START or Gravity.END or Gravity.BOTTOM) viewBinding.buttonDone.setOnClickListener(this) val appWidgetId = intent?.getIntExtra( AppWidgetManager.EXTRA_APPWIDGET_ID, @@ -58,6 +59,21 @@ class ShelfWidgetConfigActivity : viewModel.onError.observeEvent(this, SnackbarErrorObserver(viewBinding.recyclerView, null)) } + override fun onApplyWindowInsets(v: View, insets: WindowInsetsCompat): WindowInsetsCompat { + val barsInsets = insets.systemBarsInsets + viewBinding.recyclerView.updatePadding( + left = barsInsets.left, + right = barsInsets.right, + bottom = barsInsets.bottom, + ) + viewBinding.appbar.updatePadding( + left = barsInsets.left, + right = barsInsets.right, + top = barsInsets.top, + ) + return insets.consumeAllSystemBarsInsets() + } + override fun onClick(v: View) { when (v.id) { R.id.button_done -> { diff --git a/app/src/main/res/layout/activity_alternatives.xml b/app/src/main/res/layout/activity_alternatives.xml index a9a1b8e4b..2bd0f3e68 100644 --- a/app/src/main/res/layout/activity_alternatives.xml +++ b/app/src/main/res/layout/activity_alternatives.xml @@ -10,7 +10,7 @@ android:id="@+id/appbar" android:layout_width="match_parent" android:layout_height="wrap_content" - android:fitsSystemWindows="true"> + android:fitsSystemWindows="false"> + android:fitsSystemWindows="false"> diff --git a/app/src/main/res/layout/activity_categories.xml b/app/src/main/res/layout/activity_categories.xml index d157625e4..d124ddb81 100644 --- a/app/src/main/res/layout/activity_categories.xml +++ b/app/src/main/res/layout/activity_categories.xml @@ -10,7 +10,7 @@ android:id="@+id/appbar" android:layout_width="match_parent" android:layout_height="wrap_content" - android:fitsSystemWindows="true"> + android:fitsSystemWindows="false"> - + android:fitsSystemWindows="false"> + android:fitsSystemWindows="false"> - - + android:fitsSystemWindows="false"> diff --git a/app/src/main/res/layout/sheet_list_mode.xml b/app/src/main/res/layout/sheet_list_mode.xml index 6097b730a..f8e905c2a 100644 --- a/app/src/main/res/layout/sheet_list_mode.xml +++ b/app/src/main/res/layout/sheet_list_mode.xml @@ -15,8 +15,10 @@ app:title="@string/list_options" /> diff --git a/app/src/main/res/layout/sheet_reader_config.xml b/app/src/main/res/layout/sheet_reader_config.xml index fa1bb6547..22ea253fb 100644 --- a/app/src/main/res/layout/sheet_reader_config.xml +++ b/app/src/main/res/layout/sheet_reader_config.xml @@ -14,8 +14,10 @@ app:title="@string/options" /> + android:layout_height="wrap_content" + android:clipToPadding="false"> @style/Animation.Kotatsu.BottomSheetDialog + @style/Widget.Kotatsu.BottomSheet.Modal + + +