Fix edge-to-edge bug in landscape
Fix a bug where the drag handles in QueueFragment would be covered up by the navigation bar in edge-to-edge + landscape mode.
This commit is contained in:
parent
28b6edb5d6
commit
fcebfda406
12 changed files with 84 additions and 30 deletions
|
@ -69,12 +69,12 @@ dependencies {
|
|||
implementation 'androidx.viewpager2:viewpager2:1.0.0'
|
||||
|
||||
// Navigation
|
||||
def navigation_version = "2.3.1"
|
||||
def navigation_version = "2.3.2"
|
||||
implementation "androidx.navigation:navigation-fragment-ktx:$navigation_version"
|
||||
implementation "androidx.navigation:navigation-ui-ktx:$navigation_version"
|
||||
|
||||
// Media
|
||||
implementation 'androidx.media:media:1.2.0'
|
||||
implementation 'androidx.media:media:1.2.1'
|
||||
|
||||
// Preferences
|
||||
implementation 'androidx.preference:preference-ktx:1.1.1'
|
||||
|
@ -104,7 +104,7 @@ dependencies {
|
|||
ktlint "com.pinterest:ktlint:0.37.2"
|
||||
|
||||
// Memory Leak checking
|
||||
debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.4'
|
||||
debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.5'
|
||||
}
|
||||
|
||||
task ktlint(type: JavaExec, group: "verification") {
|
||||
|
|
|
@ -53,6 +53,8 @@ class MainActivity : AppCompatActivity() {
|
|||
|
||||
@Suppress("DEPRECATION")
|
||||
private fun doEdgeToEdgeSetup(binding: ActivityMainBinding) {
|
||||
// TODO: Add landscape edge-to-edge support
|
||||
|
||||
window?.apply {
|
||||
statusBarColor = Color.TRANSPARENT
|
||||
|
||||
|
|
|
@ -111,7 +111,6 @@ class PlaybackStateDatabase(context: Context) :
|
|||
/**
|
||||
* Read the stored [PlaybackState] from the database, if there is one.
|
||||
* @return The stored [PlaybackState], null if there isn't one,.
|
||||
* @author OxygenCobalt
|
||||
*/
|
||||
fun readState(): PlaybackState? {
|
||||
val database = writableDatabase
|
||||
|
@ -163,7 +162,6 @@ class PlaybackStateDatabase(context: Context) :
|
|||
/**
|
||||
* Write a list of [QueueItem]s to the database, clearing the previous queue present.
|
||||
* @param queue The list of [QueueItem]s to be written.
|
||||
* @author OxygenCobalt
|
||||
*/
|
||||
fun writeQueue(queue: List<QueueItem>) {
|
||||
val database = readableDatabase
|
||||
|
@ -218,7 +216,6 @@ class PlaybackStateDatabase(context: Context) :
|
|||
/**
|
||||
* Read the database for any [QueueItem]s.
|
||||
* @return A list of any stored [QueueItem]s.
|
||||
* @author OxygenCobalt
|
||||
*/
|
||||
fun readQueue(): List<QueueItem> {
|
||||
val database = readableDatabase
|
||||
|
|
|
@ -8,7 +8,6 @@ import androidx.appcompat.widget.PopupMenu
|
|||
import androidx.fragment.app.activityViewModels
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.navigation.fragment.navArgs
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import org.oxycblt.auxio.R
|
||||
import org.oxycblt.auxio.databinding.FragmentAlbumDetailBinding
|
||||
import org.oxycblt.auxio.detail.adapters.AlbumSongAdapter
|
||||
|
@ -20,7 +19,6 @@ import org.oxycblt.auxio.playback.PlaybackViewModel
|
|||
import org.oxycblt.auxio.playback.state.PlaybackMode
|
||||
import org.oxycblt.auxio.ui.createToast
|
||||
import org.oxycblt.auxio.ui.disable
|
||||
import org.oxycblt.auxio.ui.isLandscape
|
||||
import org.oxycblt.auxio.ui.setupAlbumSongActions
|
||||
|
||||
/**
|
||||
|
|
|
@ -8,7 +8,6 @@ import androidx.appcompat.widget.PopupMenu
|
|||
import androidx.fragment.app.activityViewModels
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.navigation.fragment.navArgs
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import org.oxycblt.auxio.R
|
||||
import org.oxycblt.auxio.databinding.FragmentArtistDetailBinding
|
||||
import org.oxycblt.auxio.detail.adapters.ArtistAlbumAdapter
|
||||
|
@ -17,7 +16,6 @@ import org.oxycblt.auxio.music.Artist
|
|||
import org.oxycblt.auxio.music.MusicStore
|
||||
import org.oxycblt.auxio.playback.PlaybackViewModel
|
||||
import org.oxycblt.auxio.ui.disable
|
||||
import org.oxycblt.auxio.ui.isLandscape
|
||||
import org.oxycblt.auxio.ui.setupAlbumActions
|
||||
|
||||
/**
|
||||
|
|
|
@ -8,7 +8,6 @@ import androidx.appcompat.widget.PopupMenu
|
|||
import androidx.fragment.app.activityViewModels
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.navigation.fragment.navArgs
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import org.oxycblt.auxio.R
|
||||
import org.oxycblt.auxio.databinding.FragmentGenreDetailBinding
|
||||
import org.oxycblt.auxio.detail.adapters.GenreArtistAdapter
|
||||
|
@ -16,7 +15,6 @@ import org.oxycblt.auxio.logD
|
|||
import org.oxycblt.auxio.music.MusicStore
|
||||
import org.oxycblt.auxio.playback.PlaybackViewModel
|
||||
import org.oxycblt.auxio.ui.disable
|
||||
import org.oxycblt.auxio.ui.isLandscape
|
||||
import org.oxycblt.auxio.ui.setupArtistActions
|
||||
|
||||
/**
|
||||
|
|
|
@ -144,7 +144,6 @@ class MusicLoader(
|
|||
}.toMutableList()
|
||||
|
||||
// Then try to associate any genres with their respective artists.
|
||||
// TODO: This is already querying all genre songs, just move it.
|
||||
for (genre in genres) {
|
||||
val artistGenreCursor = resolver.query(
|
||||
Genres.Members.getContentUri("external", genre.id),
|
||||
|
|
|
@ -84,7 +84,8 @@ class PlaybackFragment : Fragment(), SeekBar.OnSeekBarChangeListener {
|
|||
}
|
||||
|
||||
// Make ellipsizing of song title work
|
||||
binding.playbackSong.isSelected = true
|
||||
// Disabled until I can figure out why marquee causes a memory leak.
|
||||
// binding.playbackSong.isSelected = true
|
||||
|
||||
binding.playbackSeekBar.setOnSeekBarChangeListener(this)
|
||||
|
||||
|
|
|
@ -17,6 +17,9 @@ import org.oxycblt.auxio.music.BaseModel
|
|||
import org.oxycblt.auxio.music.Header
|
||||
import org.oxycblt.auxio.playback.PlaybackViewModel
|
||||
import org.oxycblt.auxio.playback.state.PlaybackMode
|
||||
import org.oxycblt.auxio.settings.SettingsManager
|
||||
import org.oxycblt.auxio.ui.isLandscape
|
||||
import org.oxycblt.auxio.ui.isSystemBarOnBottom
|
||||
|
||||
/**
|
||||
* A [Fragment] that contains both the user queue and the next queue, with the ability to
|
||||
|
@ -35,6 +38,7 @@ class QueueFragment : Fragment() {
|
|||
): View {
|
||||
val binding = FragmentQueueBinding.inflate(inflater)
|
||||
|
||||
val settingsManager = SettingsManager.getInstance()
|
||||
val callback = QueueDragCallback(playbackModel)
|
||||
val helper = ItemTouchHelper(callback)
|
||||
val queueAdapter = QueueAdapter(helper) {
|
||||
|
@ -45,6 +49,14 @@ class QueueFragment : Fragment() {
|
|||
|
||||
// --- UI SETUP ---
|
||||
|
||||
// Band-aid that fixes a bug with landscape edge-to-edge where the queue drag buttons
|
||||
// will be behind the status bar.
|
||||
if (settingsManager.edgeEnabled) {
|
||||
if (isLandscape(resources) && !isSystemBarOnBottom(requireActivity())) {
|
||||
binding.root.rootView.fitsSystemWindows = true
|
||||
}
|
||||
}
|
||||
|
||||
binding.queueToolbar.apply {
|
||||
setNavigationOnClickListener {
|
||||
findNavController().navigateUp()
|
||||
|
@ -53,18 +65,20 @@ class QueueFragment : Fragment() {
|
|||
// Since QueueFragment doesn't fit system windows, inset padding needs to be
|
||||
// artificially applied to the Toolbar so that it fits on the main window AND
|
||||
// so that the elevation doesn't show on the top.
|
||||
setOnApplyWindowInsetsListener @Suppress("DEPRECATION") { _, insets ->
|
||||
val top = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
insets.getInsets(WindowInsets.Type.systemBars()).top
|
||||
} else {
|
||||
insets.systemWindowInsetTop
|
||||
if (!binding.root.rootView.fitsSystemWindows) {
|
||||
setOnApplyWindowInsetsListener @Suppress("DEPRECATION") { _, insets ->
|
||||
val top = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
insets.getInsets(WindowInsets.Type.systemBars()).top
|
||||
} else {
|
||||
insets.systemWindowInsetTop
|
||||
}
|
||||
|
||||
(parent as View).updatePadding(
|
||||
top = top
|
||||
)
|
||||
|
||||
insets
|
||||
}
|
||||
|
||||
(parent as View).updatePadding(
|
||||
top = top
|
||||
)
|
||||
|
||||
insets
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,18 +1,22 @@
|
|||
package org.oxycblt.auxio.ui
|
||||
|
||||
import android.annotation.TargetApi
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.content.res.ColorStateList
|
||||
import android.content.res.Configuration
|
||||
import android.content.res.Resources
|
||||
import android.graphics.Point
|
||||
import android.os.Build
|
||||
import android.text.SpannableString
|
||||
import android.text.Spanned
|
||||
import android.text.style.ForegroundColorSpan
|
||||
import android.util.DisplayMetrics
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.view.Window
|
||||
import android.view.WindowInsetsController
|
||||
import android.view.WindowManager
|
||||
import android.widget.ImageButton
|
||||
import android.widget.Toast
|
||||
import androidx.annotation.ColorInt
|
||||
|
@ -31,6 +35,13 @@ import org.oxycblt.auxio.settings.SettingsManager
|
|||
|
||||
// Functions for managing UI elements [Not Colors]
|
||||
|
||||
object InterfaceUtils {
|
||||
const val NAV_HIDDEN = -1
|
||||
const val NAV_ON_LEFT = 0
|
||||
const val NAV_ON_RIGHT = 1
|
||||
const val NAV_ON_BOTTOM = 2
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply a text color to a [MenuItem]
|
||||
* @param color The text color that should be applied.
|
||||
|
@ -81,6 +92,43 @@ fun Spanned.render(): Spanned {
|
|||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the system bars are on the bottom.
|
||||
* @return If the system bars are on the bottom, false if no.
|
||||
*/
|
||||
@Suppress("DEPRECATION")
|
||||
fun isSystemBarOnBottom(activity: Activity): Boolean {
|
||||
val realPoint = Point()
|
||||
val metrics = DisplayMetrics()
|
||||
|
||||
var width = 0
|
||||
var height = 0
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
activity.display?.let { display ->
|
||||
display.getRealSize(realPoint)
|
||||
|
||||
activity.windowManager.currentWindowMetrics.bounds.also {
|
||||
width = it.width()
|
||||
height = it.height()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
(activity.getSystemService(Context.WINDOW_SERVICE) as WindowManager).apply {
|
||||
defaultDisplay.getRealSize(realPoint)
|
||||
defaultDisplay.getMetrics(metrics)
|
||||
|
||||
width = metrics.widthPixels
|
||||
height = metrics.heightPixels
|
||||
}
|
||||
}
|
||||
|
||||
val config = activity.resources.configuration
|
||||
val canMove = (width != height && config.smallestScreenWidthDp < 600)
|
||||
|
||||
return (!canMove || width < height)
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle transparent system bars. Adapted from Music Player GO
|
||||
* (https://github.com/enricocid/Music-Player-GO)
|
||||
|
|
|
@ -53,15 +53,16 @@
|
|||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/margin_mid_large"
|
||||
android:ellipsize="marquee"
|
||||
android:layout_marginEnd="24dp"
|
||||
android:ellipsize="end"
|
||||
android:focusable="true"
|
||||
android:fontFamily="@font/inter_semibold"
|
||||
android:marqueeRepeatLimit="marquee_forever"
|
||||
android:onClick="@{() -> playbackModel.navToItem(playbackModel.song)}"
|
||||
android:singleLine="true"
|
||||
android:text="@{song.name}"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Headline6"
|
||||
app:layout_constraintBottom_toTopOf="@+id/playback_artist"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@+id/playback_cover"
|
||||
app:layout_constraintTop_toBottomOf="@+id/playback_toolbar"
|
||||
app:layout_constraintVertical_chainStyle="packed"
|
||||
|
|
|
@ -56,10 +56,8 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/margin_mid_large"
|
||||
android:layout_marginEnd="@dimen/margin_mid_large"
|
||||
android:ellipsize="marquee"
|
||||
android:focusable="true"
|
||||
android:ellipsize="end"
|
||||
android:fontFamily="@font/inter_semibold"
|
||||
android:marqueeRepeatLimit="marquee_forever"
|
||||
android:onClick="@{() -> playbackModel.navToItem(playbackModel.song)}"
|
||||
android:singleLine="true"
|
||||
android:text="@{song.name}"
|
||||
|
|
Loading…
Reference in a new issue