From fe2752c3a3476d9981bb68031207863e7c2c55a4 Mon Sep 17 00:00:00 2001 From: Tommy-Geenexus Date: Sat, 20 Jul 2024 17:14:41 +0200 Subject: [PATCH] fix: adjust layouts for Android 15 window inset changes --- .../BaseBottomSheetDialogFragment.kt | 10 +++- .../com/none/tom/exiferaser/BaseFragment.kt | 11 +++++ .../none/tom/exiferaser/ExifEraserActivity.kt | 46 +++++++++++++------ .../data/ImageProcessingRepository.kt | 6 +-- .../ui/ImageProcessingFragment.kt | 1 + .../tom/exiferaser/main/ui/HelpViewHolder.kt | 21 +++++---- .../settings/ui/SettingsFragment.kt | 1 + .../main/res/layout-sw600dp/fragment_main.xml | 4 +- app/src/main/res/layout/fragment_help.xml | 1 - .../res/layout/fragment_image_processing.xml | 3 +- app/src/main/res/layout/fragment_main.xml | 4 +- app/src/main/res/layout/fragment_settings.xml | 1 - 12 files changed, 71 insertions(+), 38 deletions(-) diff --git a/app/src/main/kotlin/com/none/tom/exiferaser/BaseBottomSheetDialogFragment.kt b/app/src/main/kotlin/com/none/tom/exiferaser/BaseBottomSheetDialogFragment.kt index 5722298a..ba6b3f79 100644 --- a/app/src/main/kotlin/com/none/tom/exiferaser/BaseBottomSheetDialogFragment.kt +++ b/app/src/main/kotlin/com/none/tom/exiferaser/BaseBottomSheetDialogFragment.kt @@ -20,7 +20,9 @@ package com.none.tom.exiferaser +import android.os.Build import android.os.Bundle +import android.util.TypedValue import android.view.LayoutInflater import android.view.View import android.view.ViewGroup @@ -29,7 +31,6 @@ import androidx.navigation.fragment.findNavController import androidx.viewbinding.ViewBinding import com.google.android.material.bottomsheet.BottomSheetBehavior import com.google.android.material.bottomsheet.BottomSheetDialogFragment -import com.google.android.material.elevation.SurfaceColors import curtains.phoneWindow abstract class BaseBottomSheetDialogFragment : BottomSheetDialogFragment() { @@ -46,9 +47,14 @@ abstract class BaseBottomSheetDialogFragment : BottomSheetDialo return binding.root } + @Suppress("DEPRECATION") override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - view.phoneWindow?.navigationBarColor = SurfaceColors.SURFACE_1.getColor(requireActivity()) + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.VANILLA_ICE_CREAM) { + val tv = TypedValue() + requireActivity().theme.resolveAttribute(R.attr.colorSurfaceContainerLow, tv, true) + view.phoneWindow?.navigationBarColor = tv.data + } with(requireDialog()) { setOnShowListener { val v = findViewById(com.google.android.material.R.id.design_bottom_sheet) diff --git a/app/src/main/kotlin/com/none/tom/exiferaser/BaseFragment.kt b/app/src/main/kotlin/com/none/tom/exiferaser/BaseFragment.kt index 4f1a9e7f..17beab7f 100644 --- a/app/src/main/kotlin/com/none/tom/exiferaser/BaseFragment.kt +++ b/app/src/main/kotlin/com/none/tom/exiferaser/BaseFragment.kt @@ -22,10 +22,13 @@ package com.none.tom.exiferaser import android.os.Bundle import android.view.View +import android.widget.FrameLayout import androidx.annotation.LayoutRes import androidx.annotation.StringRes import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.widget.Toolbar +import androidx.core.view.ViewCompat +import androidx.core.view.WindowInsetsCompat import androidx.fragment.app.Fragment import androidx.navigation.NavDirections import androidx.navigation.fragment.findNavController @@ -66,6 +69,14 @@ abstract class BaseFragment( } } + protected fun setupLayoutMarginForNavigationWindowInsets() { + ViewCompat.setOnApplyWindowInsetsListener(binding.root) { root, windowInsetsCompat -> + val insets = windowInsetsCompat.getInsets(WindowInsetsCompat.Type.navigationBars()) + (root.layoutParams as FrameLayout.LayoutParams).bottomMargin = insets.bottom + WindowInsetsCompat.CONSUMED + } + } + protected fun navigate(navDirections: NavDirections) { val navController = findNavController() val action = navController.currentDestination?.getAction(navDirections.actionId) diff --git a/app/src/main/kotlin/com/none/tom/exiferaser/ExifEraserActivity.kt b/app/src/main/kotlin/com/none/tom/exiferaser/ExifEraserActivity.kt index 023d8821..90805708 100644 --- a/app/src/main/kotlin/com/none/tom/exiferaser/ExifEraserActivity.kt +++ b/app/src/main/kotlin/com/none/tom/exiferaser/ExifEraserActivity.kt @@ -23,17 +23,21 @@ package com.none.tom.exiferaser import android.content.Intent import android.content.res.Configuration import android.net.Uri +import android.os.Build import android.os.Bundle +import android.util.TypedValue import android.view.View +import android.widget.FrameLayout import androidx.activity.enableEdgeToEdge import androidx.appcompat.app.AppCompatActivity import androidx.core.os.bundleOf import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen +import androidx.core.view.ViewCompat +import androidx.core.view.WindowInsetsCompat import androidx.navigation.fragment.NavHostFragment import androidx.window.core.layout.WindowSizeClass import androidx.window.core.layout.WindowWidthSizeClass import androidx.window.layout.WindowMetricsCalculator -import com.google.android.material.elevation.SurfaceColors import com.none.tom.exiferaser.databinding.ActivityExifEraserBinding import dagger.hilt.android.AndroidEntryPoint @@ -58,6 +62,7 @@ class ExifEraserActivity : AppCompatActivity() { } } + @Suppress("DEPRECATION") override fun onCreate(savedInstanceState: Bundle?) { installSplashScreen() enableEdgeToEdge() @@ -65,23 +70,34 @@ class ExifEraserActivity : AppCompatActivity() { val binding = ActivityExifEraserBinding.inflate(layoutInflater) setContentView(binding.root) computeWindowSizeClasses() - (supportFragmentManager.findFragmentById(R.id.nav_controller) as NavHostFragment?) - ?.navController - ?.addOnDestinationChangedListener { _, destination, _ -> - if (windowSizeClass.windowWidthSizeClass != WindowWidthSizeClass.EXPANDED) { - if (destination.id == R.id.fragment_main) { - window.navigationBarColor = SurfaceColors.SURFACE_2.getColor(this) - } else { - window.navigationBarColor = SurfaceColors.SURFACE_0.getColor(this) + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.VANILLA_ICE_CREAM) { + (supportFragmentManager.findFragmentById(R.id.nav_controller) as NavHostFragment) + .navController + .addOnDestinationChangedListener { _, destination, _ -> + if (windowSizeClass.windowWidthSizeClass != WindowWidthSizeClass.EXPANDED) { + val tv = TypedValue() + if (destination.id == R.id.fragment_main) { + theme.resolveAttribute(R.attr.colorSurfaceContainer, tv, true) + } else { + theme.resolveAttribute(R.attr.colorSurface, tv, true) + } + window.navigationBarColor = tv.data } } + } + ViewCompat.setOnApplyWindowInsetsListener(binding.root) { view, windowInsetsCompat -> + val insets = windowInsetsCompat.getInsets(WindowInsetsCompat.Type.statusBars()) + (view.layoutParams as FrameLayout.LayoutParams).topMargin = insets.top + windowInsetsCompat + } + binding.layout.addView( + object : View(this) { + override fun onConfigurationChanged(newConfig: Configuration?) { + super.onConfigurationChanged(newConfig) + computeWindowSizeClasses() + } } - binding.layout.addView(object : View(this) { - override fun onConfigurationChanged(newConfig: Configuration?) { - super.onConfigurationChanged(newConfig) - computeWindowSizeClasses() - } - }) + ) handleSupportedIntent() } diff --git a/app/src/main/kotlin/com/none/tom/exiferaser/imageProcessing/data/ImageProcessingRepository.kt b/app/src/main/kotlin/com/none/tom/exiferaser/imageProcessing/data/ImageProcessingRepository.kt index 88d01ef4..76d8e136 100644 --- a/app/src/main/kotlin/com/none/tom/exiferaser/imageProcessing/data/ImageProcessingRepository.kt +++ b/app/src/main/kotlin/com/none/tom/exiferaser/imageProcessing/data/ImageProcessingRepository.kt @@ -37,6 +37,9 @@ import com.none.tom.exiferaser.main.data.supportedImageFormats import com.none.tom.exiferaser.suspendRunCatching import dagger.hilt.android.qualifiers.ApplicationContext import io.github.tommygeenexus.exifinterfaceextended.ExifInterfaceExtended +import java.util.UUID +import javax.inject.Inject +import javax.inject.Singleton import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.buffer @@ -45,9 +48,6 @@ import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.withContext import org.apache.commons.io.FilenameUtils import timber.log.Timber -import java.util.UUID -import javax.inject.Inject -import javax.inject.Singleton @Singleton class ImageProcessingRepository @Inject constructor( diff --git a/app/src/main/kotlin/com/none/tom/exiferaser/imageProcessing/ui/ImageProcessingFragment.kt b/app/src/main/kotlin/com/none/tom/exiferaser/imageProcessing/ui/ImageProcessingFragment.kt index 6afdb0e9..7b706159 100644 --- a/app/src/main/kotlin/com/none/tom/exiferaser/imageProcessing/ui/ImageProcessingFragment.kt +++ b/app/src/main/kotlin/com/none/tom/exiferaser/imageProcessing/ui/ImageProcessingFragment.kt @@ -95,6 +95,7 @@ class ImageProcessingFragment : BaseFragment( toolbar = binding.toolbarInclude.toolbar, titleRes = R.string.summary ) + setupLayoutMarginForNavigationWindowInsets() setupResponsiveLayout() lifecycleScope.launch { viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) { diff --git a/app/src/main/kotlin/com/none/tom/exiferaser/main/ui/HelpViewHolder.kt b/app/src/main/kotlin/com/none/tom/exiferaser/main/ui/HelpViewHolder.kt index ac62edce..04db1a1a 100644 --- a/app/src/main/kotlin/com/none/tom/exiferaser/main/ui/HelpViewHolder.kt +++ b/app/src/main/kotlin/com/none/tom/exiferaser/main/ui/HelpViewHolder.kt @@ -91,14 +91,19 @@ class HelpViewHolder( private fun getBuildVersion(): String { val context = itemView.context return try { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { - context.packageManager.getPackageInfo( - context.packageName, - PackageManager.PackageInfoFlags.of(0) - ).versionName - } else { - context.packageManager.getPackageInfo(context.packageName, 0).versionName - } + checkNotNull( + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + context + .packageManager + .getPackageInfo( + context.packageName, + PackageManager.PackageInfoFlags.of(0) + ) + .versionName + } else { + context.packageManager.getPackageInfo(context.packageName, 0).versionName + } + ) } catch (e: Exception) { Timber.e(e) "" diff --git a/app/src/main/kotlin/com/none/tom/exiferaser/settings/ui/SettingsFragment.kt b/app/src/main/kotlin/com/none/tom/exiferaser/settings/ui/SettingsFragment.kt index 51c02a69..c9feae54 100644 --- a/app/src/main/kotlin/com/none/tom/exiferaser/settings/ui/SettingsFragment.kt +++ b/app/src/main/kotlin/com/none/tom/exiferaser/settings/ui/SettingsFragment.kt @@ -72,6 +72,7 @@ class SettingsFragment : toolbar = binding.toolbarInclude.toolbar, titleRes = R.string.settings ) + setupLayoutMarginForNavigationWindowInsets() binding.preferences.apply { layoutManager = LinearLayoutManager(context) adapter = SettingsAdapter(listener = this@SettingsFragment) diff --git a/app/src/main/res/layout-sw600dp/fragment_main.xml b/app/src/main/res/layout-sw600dp/fragment_main.xml index 3e26afb6..4a3c2775 100644 --- a/app/src/main/res/layout-sw600dp/fragment_main.xml +++ b/app/src/main/res/layout-sw600dp/fragment_main.xml @@ -4,7 +4,6 @@ android:id="@+id/layout" android:layout_width="match_parent" android:layout_height="match_parent" - android:fitsSystemWindows="true" android:orientation="vertical" android:transitionGroup="true"> @@ -59,8 +58,7 @@ + android:layout_height="wrap_content" /> diff --git a/app/src/main/res/layout/fragment_image_processing.xml b/app/src/main/res/layout/fragment_image_processing.xml index 92a76dc7..da3c50ac 100644 --- a/app/src/main/res/layout/fragment_image_processing.xml +++ b/app/src/main/res/layout/fragment_image_processing.xml @@ -3,8 +3,7 @@ xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/layout" android:layout_width="match_parent" - android:layout_height="match_parent" - android:fitsSystemWindows="true"> + android:layout_height="match_parent"> @@ -59,8 +58,7 @@ + android:layout_height="wrap_content" />