ui: use compat edge-to-edge

Use androidx compat tools when setting up edge-to-edge and applying
window insets.

This is mostly a readability tweak ahead of making edge-to-edge a
setting.
This commit is contained in:
OxygenCobalt 2022-06-07 13:38:15 -06:00
parent 1482333adc
commit bd683ca09a
No known key found for this signature in database
GPG key ID: 37DBE3621FE9AD47
2 changed files with 20 additions and 90 deletions

View file

@ -22,10 +22,10 @@ import android.net.Uri
import android.os.Build import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.view.View import android.view.View
import android.view.WindowInsets
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.app.AppCompatDelegate import androidx.appcompat.app.AppCompatDelegate
import androidx.core.view.WindowCompat
import androidx.core.view.updatePadding import androidx.core.view.updatePadding
import org.oxycblt.auxio.databinding.ActivityMainBinding import org.oxycblt.auxio.databinding.ActivityMainBinding
import org.oxycblt.auxio.music.IndexerService import org.oxycblt.auxio.music.IndexerService
@ -34,7 +34,6 @@ import org.oxycblt.auxio.playback.system.PlaybackService
import org.oxycblt.auxio.settings.SettingsManager import org.oxycblt.auxio.settings.SettingsManager
import org.oxycblt.auxio.util.isNight import org.oxycblt.auxio.util.isNight
import org.oxycblt.auxio.util.logD import org.oxycblt.auxio.util.logD
import org.oxycblt.auxio.util.replaceSystemBarInsetsCompat
import org.oxycblt.auxio.util.systemBarInsetsCompat import org.oxycblt.auxio.util.systemBarInsetsCompat
/** /**
@ -130,50 +129,15 @@ class MainActivity : AppCompatActivity() {
} }
private fun applyEdgeToEdgeWindow(contentView: View) { private fun applyEdgeToEdgeWindow(contentView: View) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { WindowCompat.setDecorFitsSystemWindows(window, false)
logD("Doing R+ edge-to-edge")
window?.setDecorFitsSystemWindows(false) contentView.setOnApplyWindowInsetsListener { view, insets ->
val bars = insets.systemBarInsetsCompat
// Instead of automatically fetching these insets and exposing them, view.updatePadding(left = bars.left, right = bars.right)
// the R+ SDK decides to make you specify the insets yourself with a barely insets
// documented API that isn't even mentioned in any of the edge-to-edge
// tutorials. Thanks android, very cool!
contentView.setOnApplyWindowInsetsListener { view, insets ->
WindowInsets.Builder()
.setInsets(
WindowInsets.Type.systemBars(),
insets.getInsetsIgnoringVisibility(WindowInsets.Type.systemBars()))
.setInsets(
WindowInsets.Type.systemGestures(),
insets.getInsetsIgnoringVisibility(WindowInsets.Type.systemGestures()))
.build()
.applyLeftRightInsets(view)
}
} else {
// Do old edge-to-edge otherwise.
logD("Doing legacy edge-to-edge")
@Suppress("DEPRECATION")
contentView.apply {
systemUiVisibility =
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION or View.SYSTEM_UI_FLAG_LAYOUT_STABLE
setOnApplyWindowInsetsListener { view, insets -> insets.applyLeftRightInsets(view) }
}
} }
} }
/**
* Apply blind padding to accommodate left/right window insets. This is done because
* implementing insets on *phone* landscape mode is pretty impractical.
*/
private fun WindowInsets.applyLeftRightInsets(contentView: View): WindowInsets {
val bars = systemBarInsetsCompat
contentView.updatePadding(left = bars.left, right = bars.right)
return replaceSystemBarInsetsCompat(0, bars.top, 0, bars.bottom)
}
companion object { companion object {
private const val KEY_INTENT_USED = BuildConfig.APPLICATION_ID + ".key.FILE_INTENT_USED" private const val KEY_INTENT_USED = BuildConfig.APPLICATION_ID + ".key.FILE_INTENT_USED"
} }

View file

@ -21,15 +21,15 @@ import android.content.Context
import android.content.res.ColorStateList import android.content.res.ColorStateList
import android.database.Cursor import android.database.Cursor
import android.database.sqlite.SQLiteDatabase import android.database.sqlite.SQLiteDatabase
import android.graphics.Insets
import android.graphics.Rect
import android.graphics.drawable.Drawable import android.graphics.drawable.Drawable
import android.os.Build import android.os.Build
import android.view.View import android.view.View
import android.view.WindowInsets import android.view.WindowInsets
import android.widget.TextView import android.widget.TextView
import androidx.annotation.ColorRes import androidx.annotation.ColorRes
import androidx.core.graphics.Insets
import androidx.core.graphics.drawable.DrawableCompat import androidx.core.graphics.drawable.DrawableCompat
import androidx.core.view.WindowInsetsCompat
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.lifecycle.Lifecycle import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
@ -188,61 +188,27 @@ fun <R> SQLiteDatabase.queryAll(tableName: String, block: (Cursor) -> R) =
* Resolve system bar insets in a version-aware manner. This can be used to apply padding to a view * Resolve system bar insets in a version-aware manner. This can be used to apply padding to a view
* that properly follows all the frustrating changes that were made between Android 8-11. * that properly follows all the frustrating changes that were made between Android 8-11.
*/ */
val WindowInsets.systemBarInsetsCompat: Rect val WindowInsets.systemBarInsetsCompat: Insets
get() = get() =
when { WindowInsetsCompat.toWindowInsetsCompat(this)
Build.VERSION.SDK_INT >= Build.VERSION_CODES.R -> { .getInsets(WindowInsetsCompat.Type.systemBars())
getInsets(WindowInsets.Type.systemBars()).run { Rect(left, top, right, bottom) }
}
else -> {
@Suppress("DEPRECATION")
Rect(
systemWindowInsetLeft,
systemWindowInsetTop,
systemWindowInsetRight,
systemWindowInsetBottom)
}
}
/** /**
* Resolve gesture insets in a version-aware manner. This can be used to apply padding to a view * Resolve gesture insets in a version-aware manner. This can be used to apply padding to a view
* that properly follows all the frustrating changes that were made between Android 8-11. * that properly follows all the frustrating changes that were made between Android 8-11.
*/ */
val WindowInsets.systemGestureInsetsCompat: Rect val WindowInsets.systemGestureInsetsCompat: Insets
get() = get() =
when { WindowInsetsCompat.toWindowInsetsCompat(this)
Build.VERSION.SDK_INT >= Build.VERSION_CODES.R -> { .getInsets(WindowInsetsCompat.Type.systemGestures())
getInsets(WindowInsets.Type.systemGestures()).run { Rect(left, top, right, bottom) }
}
Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q -> {
@Suppress("DEPRECATION") val gestureInsets = systemGestureInsets
Rect(
gestureInsets.left,
gestureInsets.top,
gestureInsets.right,
gestureInsets.bottom)
}
else -> Rect(0, 0, 0, 0)
}
/** /**
* Replaces the system bar insets in a version-aware manner. This can be used to modify the insets * Replaces the system bar insets in a version-aware manner. This can be used to modify the insets
* for child views in a way that follows all of the frustrating changes that were made between 8-11. * for child views in a way that follows all of the frustrating changes that were made between 8-11.
*/ */
fun WindowInsets.replaceSystemBarInsetsCompat( fun WindowInsets.replaceSystemBarInsetsCompat(left: Int, top: Int, right: Int, bottom: Int) =
left: Int, requireNotNull(
top: Int, WindowInsetsCompat.Builder(WindowInsetsCompat.toWindowInsetsCompat(this))
right: Int, .setInsets(WindowInsetsCompat.Type.systemBars(), Insets.of(left, top, right, bottom))
bottom: Int .build()
): WindowInsets { .toWindowInsets())
return when {
Build.VERSION.SDK_INT >= Build.VERSION_CODES.R -> {
WindowInsets.Builder(this)
.setInsets(WindowInsets.Type.systemBars(), Insets.of(left, top, right, bottom))
.build()
}
else -> {
@Suppress("DEPRECATION") replaceSystemWindowInsets(left, top, right, bottom)
}
}
}