mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-11-26 08:24:16 +01:00
Fix window insets handling when in landscape mode
To avoid code duplication, insets handling has been moved to a separate interface.
This commit is contained in:
parent
ab6c5f4c50
commit
163f4f2014
@ -18,7 +18,9 @@ import androidx.appcompat.app.AppCompatDelegate
|
|||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.core.content.res.use
|
import androidx.core.content.res.use
|
||||||
import androidx.core.graphics.drawable.toBitmap
|
import androidx.core.graphics.drawable.toBitmap
|
||||||
import androidx.core.view.*
|
import androidx.core.view.WindowCompat
|
||||||
|
import androidx.core.view.isInvisible
|
||||||
|
import androidx.core.view.isVisible
|
||||||
import androidx.documentfile.provider.DocumentFile
|
import androidx.documentfile.provider.DocumentFile
|
||||||
import androidx.preference.PreferenceManager
|
import androidx.preference.PreferenceManager
|
||||||
import androidx.recyclerview.widget.GridLayoutManager
|
import androidx.recyclerview.widget.GridLayoutManager
|
||||||
@ -35,6 +37,7 @@ import emu.skyline.loader.LoaderResult
|
|||||||
import emu.skyline.loader.RomFormat
|
import emu.skyline.loader.RomFormat
|
||||||
import emu.skyline.provider.DocumentsProvider
|
import emu.skyline.provider.DocumentsProvider
|
||||||
import emu.skyline.utils.PreferenceSettings
|
import emu.skyline.utils.PreferenceSettings
|
||||||
|
import emu.skyline.utils.WindowInsetsHelper
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import kotlin.math.ceil
|
import kotlin.math.ceil
|
||||||
|
|
||||||
@ -100,12 +103,7 @@ class MainActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
setContentView(binding.root)
|
setContentView(binding.root)
|
||||||
WindowCompat.setDecorFitsSystemWindows(window, false)
|
WindowCompat.setDecorFitsSystemWindows(window, false)
|
||||||
// Apply inset padding to the app list recycler view to avoid navigation bar overlap
|
WindowInsetsHelper.applyToActivity(binding.root, binding.appList)
|
||||||
ViewCompat.setOnApplyWindowInsetsListener(binding.appList) { view, windowInsets ->
|
|
||||||
val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars())
|
|
||||||
view.updatePadding(bottom = insets.bottom)
|
|
||||||
WindowInsetsCompat.CONSUMED
|
|
||||||
}
|
|
||||||
|
|
||||||
PreferenceManager.setDefaultValues(this, R.xml.preferences, false)
|
PreferenceManager.setDefaultValues(this, R.xml.preferences, false)
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@ import androidx.preference.PreferenceCategory
|
|||||||
import androidx.preference.PreferenceFragmentCompat
|
import androidx.preference.PreferenceFragmentCompat
|
||||||
import emu.skyline.databinding.SettingsActivityBinding
|
import emu.skyline.databinding.SettingsActivityBinding
|
||||||
import emu.skyline.preference.IntegerListPreference
|
import emu.skyline.preference.IntegerListPreference
|
||||||
|
import emu.skyline.utils.WindowInsetsHelper
|
||||||
|
|
||||||
class SettingsActivity : AppCompatActivity() {
|
class SettingsActivity : AppCompatActivity() {
|
||||||
val binding by lazy { SettingsActivityBinding.inflate(layoutInflater) }
|
val binding by lazy { SettingsActivityBinding.inflate(layoutInflater) }
|
||||||
@ -33,6 +34,7 @@ class SettingsActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
setContentView(binding.root)
|
setContentView(binding.root)
|
||||||
WindowCompat.setDecorFitsSystemWindows(window, false)
|
WindowCompat.setDecorFitsSystemWindows(window, false)
|
||||||
|
WindowInsetsHelper.applyToActivity(binding.root)
|
||||||
|
|
||||||
setSupportActionBar(binding.titlebar.toolbar)
|
setSupportActionBar(binding.titlebar.toolbar)
|
||||||
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
||||||
@ -81,15 +83,9 @@ class SettingsActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onViewCreated(view : View, savedInstanceState : Bundle?) {
|
override fun onViewCreated(view : View, savedInstanceState : Bundle?) {
|
||||||
val recyclerView = view.findViewById<View>(R.id.recycler_view)
|
|
||||||
// Apply inset padding to the settings recycler view to avoid navigation bar overlap
|
|
||||||
ViewCompat.setOnApplyWindowInsetsListener(recyclerView) { v, windowInsets ->
|
|
||||||
val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars())
|
|
||||||
v.updatePadding(bottom = insets.bottom)
|
|
||||||
WindowInsetsCompat.CONSUMED
|
|
||||||
}
|
|
||||||
|
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
val recyclerView = view.findViewById<View>(R.id.recycler_view)
|
||||||
|
WindowInsetsHelper.setPadding(recyclerView, bottom = true)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -12,7 +12,8 @@ import android.view.KeyEvent
|
|||||||
import android.view.ViewTreeObserver
|
import android.view.ViewTreeObserver
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||||
import androidx.core.view.*
|
import androidx.core.view.WindowCompat
|
||||||
|
import androidx.core.view.marginTop
|
||||||
import androidx.recyclerview.widget.DividerItemDecoration
|
import androidx.recyclerview.widget.DividerItemDecoration
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
@ -29,6 +30,7 @@ import emu.skyline.input.dialog.RumbleDialog
|
|||||||
import emu.skyline.input.dialog.StickDialog
|
import emu.skyline.input.dialog.StickDialog
|
||||||
import emu.skyline.input.onscreen.OnScreenEditActivity
|
import emu.skyline.input.onscreen.OnScreenEditActivity
|
||||||
import emu.skyline.utils.PreferenceSettings
|
import emu.skyline.utils.PreferenceSettings
|
||||||
|
import emu.skyline.utils.WindowInsetsHelper
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -173,12 +175,7 @@ class ControllerActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
setContentView(binding.root)
|
setContentView(binding.root)
|
||||||
WindowCompat.setDecorFitsSystemWindows(window, false)
|
WindowCompat.setDecorFitsSystemWindows(window, false)
|
||||||
// Apply inset padding to the controller list recycler view to avoid navigation bar overlap
|
WindowInsetsHelper.applyToActivity(binding.root, binding.controllerList)
|
||||||
ViewCompat.setOnApplyWindowInsetsListener(binding.controllerList) { view, windowInsets ->
|
|
||||||
val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars())
|
|
||||||
view.updatePadding(bottom = insets.bottom)
|
|
||||||
WindowInsetsCompat.CONSUMED
|
|
||||||
}
|
|
||||||
|
|
||||||
setSupportActionBar(binding.titlebar.toolbar)
|
setSupportActionBar(binding.titlebar.toolbar)
|
||||||
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
||||||
|
@ -12,10 +12,7 @@ import android.view.ViewTreeObserver
|
|||||||
import androidx.activity.result.contract.ActivityResultContracts
|
import androidx.activity.result.contract.ActivityResultContracts
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||||
import androidx.core.view.ViewCompat
|
|
||||||
import androidx.core.view.WindowCompat
|
import androidx.core.view.WindowCompat
|
||||||
import androidx.core.view.WindowInsetsCompat
|
|
||||||
import androidx.core.view.updatePadding
|
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import androidx.viewbinding.ViewBinding
|
import androidx.viewbinding.ViewBinding
|
||||||
import com.google.android.material.snackbar.Snackbar
|
import com.google.android.material.snackbar.Snackbar
|
||||||
@ -29,6 +26,7 @@ import emu.skyline.databinding.GpuDriverActivityBinding
|
|||||||
import emu.skyline.utils.GpuDriverHelper
|
import emu.skyline.utils.GpuDriverHelper
|
||||||
import emu.skyline.utils.GpuDriverInstallResult
|
import emu.skyline.utils.GpuDriverInstallResult
|
||||||
import emu.skyline.utils.PreferenceSettings
|
import emu.skyline.utils.PreferenceSettings
|
||||||
|
import emu.skyline.utils.WindowInsetsHelper
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
@ -127,12 +125,8 @@ class GpuDriverActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
setContentView(binding.root)
|
setContentView(binding.root)
|
||||||
WindowCompat.setDecorFitsSystemWindows(window, false)
|
WindowCompat.setDecorFitsSystemWindows(window, false)
|
||||||
// Apply inset padding to the driver list recycler view to avoid navigation bar overlap
|
WindowInsetsHelper.applyToActivity(binding.root, binding.driverList)
|
||||||
ViewCompat.setOnApplyWindowInsetsListener(binding.driverList) { view, windowInsets ->
|
WindowInsetsHelper.addMargin(binding.addDriverButton, bottom = true)
|
||||||
val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars())
|
|
||||||
view.updatePadding(bottom = insets.bottom)
|
|
||||||
WindowInsetsCompat.CONSUMED
|
|
||||||
}
|
|
||||||
|
|
||||||
setSupportActionBar(binding.titlebar.toolbar)
|
setSupportActionBar(binding.titlebar.toolbar)
|
||||||
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
||||||
|
85
app/src/main/java/emu/skyline/utils/WindowInsetsHelper.kt
Normal file
85
app/src/main/java/emu/skyline/utils/WindowInsetsHelper.kt
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-License-Identifier: MPL-2.0
|
||||||
|
* Copyright © 2022 Skyline Team and Contributors (https://github.com/skyline-emu/)
|
||||||
|
*/
|
||||||
|
|
||||||
|
package emu.skyline.utils
|
||||||
|
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.core.view.ViewCompat
|
||||||
|
import androidx.core.view.WindowInsetsCompat
|
||||||
|
import androidx.core.view.updateLayoutParams
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An interface to easily add window insets handling to any layout
|
||||||
|
*/
|
||||||
|
interface WindowInsetsHelper {
|
||||||
|
companion object {
|
||||||
|
/**
|
||||||
|
* Convenience method to setup insets for most Activities with a single call
|
||||||
|
* @param rootView The root view of the layout
|
||||||
|
* @param listView The list view of the layout
|
||||||
|
*/
|
||||||
|
fun applyToActivity(rootView : View, listView : View? = null) {
|
||||||
|
// Apply margin to the root view to avoid overlapping system bar in landscape mode
|
||||||
|
// Don't consume insets in the root view so that child views can apply them
|
||||||
|
setMargin(rootView, consume = false, left = true, right = true)
|
||||||
|
|
||||||
|
// Apply padding to the list view to avoid navigation bar overlap at the bottom
|
||||||
|
listView?.let { addPadding(it, bottom = true) }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setMargin(view : View, consume : Boolean = true, left : Boolean = false, top : Boolean = false, right : Boolean = false, bottom : Boolean = false) {
|
||||||
|
ViewCompat.setOnApplyWindowInsetsListener(view) { v, windowInsets ->
|
||||||
|
val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars())
|
||||||
|
v.updateLayoutParams<ViewGroup.MarginLayoutParams> {
|
||||||
|
if (left) leftMargin = insets.left
|
||||||
|
if (top) topMargin = insets.top
|
||||||
|
if (right) rightMargin = insets.right
|
||||||
|
if (bottom) bottomMargin = insets.bottom
|
||||||
|
}
|
||||||
|
if (consume) WindowInsetsCompat.CONSUMED else windowInsets
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun addMargin(view : View, consume : Boolean = true, left : Boolean = false, top : Boolean = false, right : Boolean = false, bottom : Boolean = false) {
|
||||||
|
ViewCompat.setOnApplyWindowInsetsListener(view) { v, windowInsets ->
|
||||||
|
val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars())
|
||||||
|
v.updateLayoutParams<ViewGroup.MarginLayoutParams> {
|
||||||
|
if (left) leftMargin += insets.left
|
||||||
|
if (top) topMargin += insets.top
|
||||||
|
if (right) rightMargin += insets.right
|
||||||
|
if (bottom) bottomMargin += insets.bottom
|
||||||
|
}
|
||||||
|
if (consume) WindowInsetsCompat.CONSUMED else windowInsets
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setPadding(view : View, consume : Boolean = true, left : Boolean = false, top : Boolean = false, right : Boolean = false, bottom : Boolean = false) {
|
||||||
|
ViewCompat.setOnApplyWindowInsetsListener(view) { v, windowInsets ->
|
||||||
|
val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars())
|
||||||
|
v.setPadding(
|
||||||
|
if (left) insets.left else v.paddingLeft,
|
||||||
|
if (top) insets.top else v.paddingTop,
|
||||||
|
if (right) insets.right else v.paddingRight,
|
||||||
|
if (bottom) insets.bottom else v.paddingBottom
|
||||||
|
)
|
||||||
|
if (consume) WindowInsetsCompat.CONSUMED else windowInsets
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun addPadding(view : View, consume : Boolean = true, left : Boolean = false, top : Boolean = false, right : Boolean = false, bottom : Boolean = false) {
|
||||||
|
ViewCompat.setOnApplyWindowInsetsListener(view) { v, windowInsets ->
|
||||||
|
val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars())
|
||||||
|
v.setPadding(
|
||||||
|
if (left) insets.left + v.paddingLeft else v.paddingLeft,
|
||||||
|
if (top) insets.top + v.paddingTop else v.paddingTop,
|
||||||
|
if (right) insets.right + v.paddingRight else v.paddingRight,
|
||||||
|
if (bottom) insets.bottom + v.paddingBottom else v.paddingBottom
|
||||||
|
)
|
||||||
|
if (consume) WindowInsetsCompat.CONSUMED else windowInsets
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user