Android: Use enableEdgeToEdge

Dolphin has been using edge-to-edge rendering for a little while now,
but it has required a bit of manual work. Now that edge-to-edge is
becoming something expected of apps in Android 15, there's a nicer API
we can use.

Tested on Android 8, 11 and 13, with no changes in behavior noted.
This commit is contained in:
JosJuice 2024-09-28 18:20:31 +02:00
parent 2cb124bd3a
commit d0e6573ac7
7 changed files with 12 additions and 90 deletions

View File

@ -6,11 +6,10 @@ import android.content.Context
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.view.View import android.view.View
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat import androidx.core.view.ViewCompat
import androidx.core.view.WindowCompat
import androidx.core.view.WindowInsetsCompat import androidx.core.view.WindowInsetsCompat
import com.google.android.material.color.MaterialColors
import org.dolphinemu.dolphinemu.R import org.dolphinemu.dolphinemu.R
import org.dolphinemu.dolphinemu.databinding.ActivityConvertBinding import org.dolphinemu.dolphinemu.databinding.ActivityConvertBinding
import org.dolphinemu.dolphinemu.fragments.ConvertFragment import org.dolphinemu.dolphinemu.fragments.ConvertFragment
@ -23,14 +22,13 @@ class ConvertActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
ThemeHelper.setTheme(this) ThemeHelper.setTheme(this)
enableEdgeToEdge()
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
binding = ActivityConvertBinding.inflate(layoutInflater) binding = ActivityConvertBinding.inflate(layoutInflater)
setContentView(binding.root) setContentView(binding.root)
WindowCompat.setDecorFitsSystemWindows(window, false)
val path = intent.getStringExtra(ARG_GAME_PATH) val path = intent.getStringExtra(ARG_GAME_PATH)
var fragment = supportFragmentManager var fragment = supportFragmentManager
@ -62,10 +60,6 @@ class ConvertActivity : AppCompatActivity() {
binding.scrollViewConvert.setPadding(insets.left, 0, insets.right, insets.bottom) binding.scrollViewConvert.setPadding(insets.left, 0, insets.right, insets.bottom)
InsetsHelper.applyNavbarWorkaround(insets.bottom, binding.workaroundView) InsetsHelper.applyNavbarWorkaround(insets.bottom, binding.workaroundView)
ThemeHelper.setNavigationBarColor(
this,
MaterialColors.getColor(binding.appbarConvert, R.attr.colorSurface)
)
windowInsets windowInsets
} }

View File

@ -10,12 +10,11 @@ import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.provider.DocumentsContract import android.provider.DocumentsContract
import android.view.View import android.view.View
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat import androidx.core.view.ViewCompat
import androidx.core.view.WindowCompat
import androidx.core.view.WindowInsetsCompat import androidx.core.view.WindowInsetsCompat
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import com.google.android.material.color.MaterialColors
import org.dolphinemu.dolphinemu.R import org.dolphinemu.dolphinemu.R
import org.dolphinemu.dolphinemu.databinding.ActivityUserDataBinding import org.dolphinemu.dolphinemu.databinding.ActivityUserDataBinding
import org.dolphinemu.dolphinemu.dialogs.NotificationDialog import org.dolphinemu.dolphinemu.dialogs.NotificationDialog
@ -25,7 +24,6 @@ import org.dolphinemu.dolphinemu.features.DocumentProvider
import org.dolphinemu.dolphinemu.model.TaskViewModel import org.dolphinemu.dolphinemu.model.TaskViewModel
import org.dolphinemu.dolphinemu.utils.* import org.dolphinemu.dolphinemu.utils.*
import org.dolphinemu.dolphinemu.utils.ThemeHelper.enableScrollTint import org.dolphinemu.dolphinemu.utils.ThemeHelper.enableScrollTint
import org.dolphinemu.dolphinemu.utils.ThemeHelper.setNavigationBarColor
import java.io.File import java.io.File
import java.io.FileInputStream import java.io.FileInputStream
import java.io.FileOutputStream import java.io.FileOutputStream
@ -43,14 +41,13 @@ class UserDataActivity : AppCompatActivity() {
taskViewModel = ViewModelProvider(this)[TaskViewModel::class.java] taskViewModel = ViewModelProvider(this)[TaskViewModel::class.java]
ThemeHelper.setTheme(this) ThemeHelper.setTheme(this)
enableEdgeToEdge()
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
mBinding = ActivityUserDataBinding.inflate(layoutInflater) mBinding = ActivityUserDataBinding.inflate(layoutInflater)
setContentView(mBinding.root) setContentView(mBinding.root)
WindowCompat.setDecorFitsSystemWindows(window, false)
val android7 = Build.VERSION.SDK_INT >= Build.VERSION_CODES.N val android7 = Build.VERSION.SDK_INT >= Build.VERSION_CODES.N
val android10 = Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q val android10 = Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q
val android11 = Build.VERSION.SDK_INT >= Build.VERSION_CODES.R val android11 = Build.VERSION.SDK_INT >= Build.VERSION_CODES.R
@ -334,10 +331,6 @@ class UserDataActivity : AppCompatActivity() {
mBinding.scrollViewUserData.setPadding(insets.left, 0, insets.right, insets.bottom) mBinding.scrollViewUserData.setPadding(insets.left, 0, insets.right, insets.bottom)
InsetsHelper.applyNavbarWorkaround(insets.bottom, mBinding.workaroundView) InsetsHelper.applyNavbarWorkaround(insets.bottom, mBinding.workaroundView)
setNavigationBarColor(
this,
MaterialColors.getColor(mBinding.appbarUserData, R.attr.colorSurface)
)
windowInsets windowInsets
} }
} }

View File

@ -10,10 +10,10 @@ import android.view.Menu
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.view.ViewGroup.MarginLayoutParams import android.view.ViewGroup.MarginLayoutParams
import androidx.activity.enableEdgeToEdge
import androidx.annotation.ColorInt import androidx.annotation.ColorInt
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat import androidx.core.view.ViewCompat
import androidx.core.view.WindowCompat
import androidx.core.view.WindowInsetsAnimationCompat import androidx.core.view.WindowInsetsAnimationCompat
import androidx.core.view.WindowInsetsCompat import androidx.core.view.WindowInsetsCompat
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
@ -51,6 +51,7 @@ class CheatsActivity : AppCompatActivity(), PanelSlideListener {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
ThemeHelper.setTheme(this) ThemeHelper.setTheme(this)
enableEdgeToEdge()
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
@ -69,8 +70,6 @@ class CheatsActivity : AppCompatActivity(), PanelSlideListener {
binding = ActivityCheatsBinding.inflate(layoutInflater) binding = ActivityCheatsBinding.inflate(layoutInflater)
setContentView(binding.root) setContentView(binding.root)
WindowCompat.setDecorFitsSystemWindows(window, false)
cheatListLastFocus = binding.cheatList cheatListLastFocus = binding.cheatList
cheatDetailsLastFocus = binding.cheatDetails cheatDetailsLastFocus = binding.cheatDetails
@ -225,10 +224,6 @@ class CheatsActivity : AppCompatActivity(), PanelSlideListener {
binding.cheatDetails.layoutParams = mlpDetails binding.cheatDetails.layoutParams = mlpDetails
InsetsHelper.applyNavbarWorkaround(barInsets.bottom, binding.workaroundView) InsetsHelper.applyNavbarWorkaround(barInsets.bottom, binding.workaroundView)
ThemeHelper.setNavigationBarColor(
this,
MaterialColors.getColor(binding.appbarCheats, R.attr.colorSurface)
)
windowInsets windowInsets
} }

View File

@ -6,13 +6,12 @@ import android.content.Context
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.view.View import android.view.View
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat import androidx.core.view.ViewCompat
import androidx.core.view.WindowCompat
import androidx.core.view.WindowInsetsCompat import androidx.core.view.WindowInsetsCompat
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import com.google.android.material.color.MaterialColors
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
@ -31,14 +30,13 @@ class RiivolutionBootActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
ThemeHelper.setTheme(this) ThemeHelper.setTheme(this)
enableEdgeToEdge()
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
binding = ActivityRiivolutionBootBinding.inflate(layoutInflater) binding = ActivityRiivolutionBootBinding.inflate(layoutInflater)
setContentView(binding.root) setContentView(binding.root)
WindowCompat.setDecorFitsSystemWindows(window, false)
val path = intent.getStringExtra(ARG_GAME_PATH) val path = intent.getStringExtra(ARG_GAME_PATH)
val gameId = intent.getStringExtra(ARG_GAME_ID) val gameId = intent.getStringExtra(ARG_GAME_ID)
val revision = intent.getIntExtra(ARG_REVISION, -1) val revision = intent.getIntExtra(ARG_REVISION, -1)
@ -96,10 +94,6 @@ class RiivolutionBootActivity : AppCompatActivity() {
binding.scrollViewRiivolution.setPadding(insets.left, 0, insets.right, insets.bottom) binding.scrollViewRiivolution.setPadding(insets.left, 0, insets.right, insets.bottom)
InsetsHelper.applyNavbarWorkaround(insets.bottom, binding.workaroundView) InsetsHelper.applyNavbarWorkaround(insets.bottom, binding.workaroundView)
ThemeHelper.setNavigationBarColor(
this,
MaterialColors.getColor(binding.appbarRiivolution, R.attr.colorSurface)
)
windowInsets windowInsets
} }

View File

@ -14,17 +14,16 @@ import android.os.Bundle
import android.view.Menu import android.view.Menu
import android.view.View import android.view.View
import android.widget.Toast import android.widget.Toast
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat import androidx.core.view.ViewCompat
import androidx.core.view.WindowCompat
import androidx.core.view.WindowInsetsCompat import androidx.core.view.WindowInsetsCompat
import androidx.fragment.app.DialogFragment import androidx.fragment.app.DialogFragment
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import com.google.android.material.appbar.CollapsingToolbarLayout import com.google.android.material.appbar.CollapsingToolbarLayout
import com.google.android.material.color.MaterialColors import com.google.android.material.color.MaterialColors
import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.snackbar.Snackbar
import org.dolphinemu.dolphinemu.NativeLibrary import org.dolphinemu.dolphinemu.NativeLibrary
import org.dolphinemu.dolphinemu.R import org.dolphinemu.dolphinemu.R
import org.dolphinemu.dolphinemu.databinding.ActivitySettingsBinding import org.dolphinemu.dolphinemu.databinding.ActivitySettingsBinding
@ -32,11 +31,9 @@ import org.dolphinemu.dolphinemu.features.settings.model.Settings
import org.dolphinemu.dolphinemu.features.settings.ui.SettingsFragment.Companion.newInstance import org.dolphinemu.dolphinemu.features.settings.ui.SettingsFragment.Companion.newInstance
import org.dolphinemu.dolphinemu.ui.main.MainPresenter import org.dolphinemu.dolphinemu.ui.main.MainPresenter
import org.dolphinemu.dolphinemu.utils.FileBrowserHelper import org.dolphinemu.dolphinemu.utils.FileBrowserHelper
import org.dolphinemu.dolphinemu.utils.GpuDriverInstallResult
import org.dolphinemu.dolphinemu.utils.InsetsHelper import org.dolphinemu.dolphinemu.utils.InsetsHelper
import org.dolphinemu.dolphinemu.utils.SerializableHelper.serializable import org.dolphinemu.dolphinemu.utils.SerializableHelper.serializable
import org.dolphinemu.dolphinemu.utils.ThemeHelper.enableScrollTint import org.dolphinemu.dolphinemu.utils.ThemeHelper.enableScrollTint
import org.dolphinemu.dolphinemu.utils.ThemeHelper.setNavigationBarColor
import org.dolphinemu.dolphinemu.utils.ThemeHelper.setTheme import org.dolphinemu.dolphinemu.utils.ThemeHelper.setTheme
class SettingsActivity : AppCompatActivity(), SettingsActivityView { class SettingsActivity : AppCompatActivity(), SettingsActivityView {
@ -55,6 +52,7 @@ class SettingsActivity : AppCompatActivity(), SettingsActivityView {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
setTheme(this) setTheme(this)
enableEdgeToEdge()
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
@ -69,8 +67,6 @@ class SettingsActivity : AppCompatActivity(), SettingsActivityView {
binding = ActivitySettingsBinding.inflate(layoutInflater) binding = ActivitySettingsBinding.inflate(layoutInflater)
setContentView(binding!!.root) setContentView(binding!!.root)
WindowCompat.setDecorFitsSystemWindows(window, false)
val launcher = intent val launcher = intent
var gameID = launcher.getStringExtra(ARG_GAME_ID) var gameID = launcher.getStringExtra(ARG_GAME_ID)
if (gameID == null) gameID = "" if (gameID == null) gameID = ""
@ -291,10 +287,6 @@ class SettingsActivity : AppCompatActivity(), SettingsActivityView {
) )
InsetsHelper.applyNavbarWorkaround(insets.bottom, binding!!.workaroundView) InsetsHelper.applyNavbarWorkaround(insets.bottom, binding!!.workaroundView)
setNavigationBarColor(
this,
MaterialColors.getColor(binding!!.appbarSettings, R.attr.colorSurface)
)
windowInsets windowInsets
} }

View File

@ -9,14 +9,13 @@ import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import android.view.View import android.view.View
import android.view.ViewGroup.MarginLayoutParams import android.view.ViewGroup.MarginLayoutParams
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
import androidx.core.view.ViewCompat import androidx.core.view.ViewCompat
import androidx.core.view.WindowCompat
import androidx.core.view.WindowInsetsCompat import androidx.core.view.WindowInsetsCompat
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout.OnRefreshListener import androidx.swiperefreshlayout.widget.SwipeRefreshLayout.OnRefreshListener
import com.google.android.material.appbar.AppBarLayout import com.google.android.material.appbar.AppBarLayout
import com.google.android.material.color.MaterialColors
import com.google.android.material.tabs.TabLayout import com.google.android.material.tabs.TabLayout
import org.dolphinemu.dolphinemu.R import org.dolphinemu.dolphinemu.R
import org.dolphinemu.dolphinemu.activities.EmulationActivity import org.dolphinemu.dolphinemu.activities.EmulationActivity
@ -53,13 +52,13 @@ class MainActivity : AppCompatActivity(), MainView, OnRefreshListener, ThemeProv
installSplashScreen().setKeepOnScreenCondition { !DirectoryInitialization.areDolphinDirectoriesReady() } installSplashScreen().setKeepOnScreenCondition { !DirectoryInitialization.areDolphinDirectoriesReady() }
ThemeHelper.setTheme(this) ThemeHelper.setTheme(this)
enableEdgeToEdge()
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater) binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root) setContentView(binding.root)
WindowCompat.setDecorFitsSystemWindows(window, false)
setInsets() setInsets()
ThemeHelper.enableStatusBarScrollTint(this, binding.appbarMain) ThemeHelper.enableStatusBarScrollTint(this, binding.appbarMain)
@ -330,10 +329,6 @@ class MainActivity : AppCompatActivity(), MainView, OnRefreshListener, ThemeProv
binding.pagerPlatforms.setPadding(insets.left, 0, insets.right, 0) binding.pagerPlatforms.setPadding(insets.left, 0, insets.right, 0)
InsetsHelper.applyNavbarWorkaround(insets.bottom, binding.workaroundView) InsetsHelper.applyNavbarWorkaround(insets.bottom, binding.workaroundView)
ThemeHelper.setNavigationBarColor(
this,
MaterialColors.getColor(binding.appbarMain, R.attr.colorSurface)
)
windowInsets windowInsets
} }

View File

@ -1,6 +1,5 @@
package org.dolphinemu.dolphinemu.utils package org.dolphinemu.dolphinemu.utils
import android.app.Activity
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import org.dolphinemu.dolphinemu.R import org.dolphinemu.dolphinemu.R
import android.os.Build import android.os.Build
@ -14,11 +13,8 @@ import com.google.android.material.appbar.MaterialToolbar
import com.google.android.material.appbar.AppBarLayout import com.google.android.material.appbar.AppBarLayout
import com.google.android.material.elevation.ElevationOverlayProvider import com.google.android.material.elevation.ElevationOverlayProvider
import com.google.android.material.color.MaterialColors import com.google.android.material.color.MaterialColors
import android.graphics.Color
import androidx.annotation.ColorInt import androidx.annotation.ColorInt
import androidx.annotation.RequiresApi
import androidx.preference.PreferenceManager import androidx.preference.PreferenceManager
import kotlin.math.roundToInt
object ThemeHelper { object ThemeHelper {
@ -32,8 +28,6 @@ object ThemeHelper {
const val GREEN = 3 const val GREEN = 3
const val PINK = 4 const val PINK = 4
const val NAV_BAR_ALPHA = 0.9f
@JvmStatic @JvmStatic
fun setTheme(activity: AppCompatActivity) { fun setTheme(activity: AppCompatActivity) {
// We have to use shared preferences in addition to Dolphin's settings to guarantee that the // We have to use shared preferences in addition to Dolphin's settings to guarantee that the
@ -166,32 +160,6 @@ object ThemeHelper {
} }
} }
@JvmStatic
fun setNavigationBarColor(activity: Activity, @ColorInt color: Int) {
val gestureType = InsetsHelper.getSystemGestureType(activity.applicationContext)
val orientation = activity.resources.configuration.orientation
// Use black if the Android version is too low to support changing button colors
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O_MR1) {
activity.window.navigationBarColor =
ContextCompat.getColor(activity.applicationContext, android.R.color.black)
} else if ((gestureType == InsetsHelper.THREE_BUTTON_NAVIGATION ||
gestureType == InsetsHelper.TWO_BUTTON_NAVIGATION) &&
orientation == Configuration.ORIENTATION_LANDSCAPE
) {
activity.window.navigationBarColor = color
} else if (gestureType == InsetsHelper.THREE_BUTTON_NAVIGATION ||
gestureType == InsetsHelper.TWO_BUTTON_NAVIGATION
) {
activity.window.navigationBarColor = getColorWithOpacity(color, NAV_BAR_ALPHA)
} else {
activity.window.navigationBarColor = ContextCompat.getColor(
activity.applicationContext,
android.R.color.transparent
)
}
}
@JvmStatic @JvmStatic
fun enableScrollTint( fun enableScrollTint(
activity: AppCompatActivity, toolbar: MaterialToolbar, appBarLayout: AppBarLayout activity: AppCompatActivity, toolbar: MaterialToolbar, appBarLayout: AppBarLayout
@ -232,13 +200,4 @@ object ThemeHelper {
} }
} }
} }
@RequiresApi(api = Build.VERSION_CODES.O_MR1)
@ColorInt
private fun getColorWithOpacity(@ColorInt color: Int, alphaFactor: Float): Int {
return Color.argb(
(alphaFactor * Color.alpha(color)).roundToInt(), Color.red(color),
Color.green(color), Color.blue(color)
)
}
} }