From f1245d7d405725ff8653b169904ea10b7ca253f7 Mon Sep 17 00:00:00 2001 From: OxygenCobalt Date: Sat, 13 Feb 2021 10:20:48 -0700 Subject: [PATCH] Improve layout responsiveness Make layouts better on all screen sizes. --- .github/CONTRIBUTING.md | 2 +- .../main/java/org/oxycblt/auxio/AuxioApp.kt | 5 +- .../org/oxycblt/auxio/coil/AlbumArtFetcher.kt | 2 +- .../org/oxycblt/auxio/coil/MosaicFetcher.kt | 13 +- .../java/org/oxycblt/auxio/ui/ActionMenu.kt | 2 +- .../org/oxycblt/auxio/ui/InterfaceUtils.kt | 15 +- .../res/layout-land/fragment_playback.xml | 20 +- .../res/layout-xlarge/fragment_playback.xml | 214 ++++++++++++++++++ app/src/main/res/values-de/strings.xml | 6 +- info/ARCHITECTURE.md | 2 +- 10 files changed, 247 insertions(+), 34 deletions(-) create mode 100644 app/src/main/res/layout-xlarge/fragment_playback.xml diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 155787fc9..75c2c7895 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -31,7 +31,7 @@ If you do make a request, provide the following: - Why do you think it will benefit everyone's usage of the app? If you have the knowledge, you can also implement the feature yourself and create a [Pull Request](https://github.com/OxygenCobalt/Auxio/pulls), but its recommended that **you create an issue beforehand to give me a heads up.** -Its also recommended that you read about [Auxio's Architecture](../info/ARCHITECTURE.md) so that your change does not harm the codebase. +Its also recommended that you read about [Auxio's Architecture](../info/ARCHITECTURE.md) as well to make changes better and more efficient. ## Translations diff --git a/app/src/main/java/org/oxycblt/auxio/AuxioApp.kt b/app/src/main/java/org/oxycblt/auxio/AuxioApp.kt index 75d5d6771..e0cdb2a3a 100644 --- a/app/src/main/java/org/oxycblt/auxio/AuxioApp.kt +++ b/app/src/main/java/org/oxycblt/auxio/AuxioApp.kt @@ -17,11 +17,8 @@ class AuxioApp : Application(), ImageLoaderFactory { } override fun newImageLoader(): ImageLoader { - // Don't cache images on-disk [The covers are already on-disk] - // Crossfade by default - // Use a transparent placeholder return ImageLoader.Builder(applicationContext) - .diskCachePolicy(CachePolicy.DISABLED) + .diskCachePolicy(CachePolicy.DISABLED) // Not downloading anything, so no disk-caching .crossfade(true) .placeholder(android.R.color.transparent) .build() diff --git a/app/src/main/java/org/oxycblt/auxio/coil/AlbumArtFetcher.kt b/app/src/main/java/org/oxycblt/auxio/coil/AlbumArtFetcher.kt index eda026938..0d2a34d7f 100644 --- a/app/src/main/java/org/oxycblt/auxio/coil/AlbumArtFetcher.kt +++ b/app/src/main/java/org/oxycblt/auxio/coil/AlbumArtFetcher.kt @@ -77,5 +77,5 @@ class AlbumArtFetcher(private val context: Context) : Fetcher { return loadMediaStoreCovers(data) } - override fun key(data: Album) = data.id.toString() + override fun key(data: Album) = data.coverUri.toString() } diff --git a/app/src/main/java/org/oxycblt/auxio/coil/MosaicFetcher.kt b/app/src/main/java/org/oxycblt/auxio/coil/MosaicFetcher.kt index d332dd664..01edae029 100644 --- a/app/src/main/java/org/oxycblt/auxio/coil/MosaicFetcher.kt +++ b/app/src/main/java/org/oxycblt/auxio/coil/MosaicFetcher.kt @@ -83,7 +83,7 @@ class MosaicFetcher(private val context: Context) : Fetcher { } /** - * Create the mosaic, Code adapted from Phonograph + * Create the mosaic image, Code adapted from Phonograph * https://github.com/kabouzeid/Phonograph */ private fun drawMosaic(streams: List): Bitmap { @@ -122,16 +122,13 @@ class MosaicFetcher(private val context: Context) : Fetcher { } /** - * Iterate through a list of [Closeable]s, running [use] on each. - * @param action What to do for each [Closeable] + * Iterate through a list of [Closeable]s, running [block] on each and closing it when done. */ - private fun List.useForEach(action: (T) -> Unit) { - forEach { - it.use(action) - } + private fun List.useForEach(block: (T) -> Unit) { + forEach { it.use(block) } } - override fun key(data: Parent): String = data.id.toString() + override fun key(data: Parent): String = data.hashCode().toString() override fun handles(data: Parent) = data !is Album // Albums are not used here companion object { diff --git a/app/src/main/java/org/oxycblt/auxio/ui/ActionMenu.kt b/app/src/main/java/org/oxycblt/auxio/ui/ActionMenu.kt index 5a94672a6..1f2d9b7a6 100644 --- a/app/src/main/java/org/oxycblt/auxio/ui/ActionMenu.kt +++ b/app/src/main/java/org/oxycblt/auxio/ui/ActionMenu.kt @@ -33,7 +33,7 @@ fun Fragment.newMenu(anchor: View, data: BaseModel, flag: Int = ActionMenu.FLAG_ * @param activity [AppCompatActivity] required as both a context and ViewModelStore owner. * @param anchor [View] This should be centered around * @param data [BaseModel] this menu corresponds to - * @param flag Any extra flags to accompany the data. See [FLAG_NONE], [FLAG_IN_ALBUM], [FLAG_IN_ARTIST], [FLAG_IN_GENRE] for more detials. + * @param flag Any extra flags to accompany the data. See [FLAG_NONE], [FLAG_IN_ALBUM], [FLAG_IN_ARTIST], [FLAG_IN_GENRE] for more details. * @throws IllegalArgumentException When there is no menu for this specific datatype/flag */ class ActionMenu( diff --git a/app/src/main/java/org/oxycblt/auxio/ui/InterfaceUtils.kt b/app/src/main/java/org/oxycblt/auxio/ui/InterfaceUtils.kt index 21d918929..3e6f8f466 100644 --- a/app/src/main/java/org/oxycblt/auxio/ui/InterfaceUtils.kt +++ b/app/src/main/java/org/oxycblt/auxio/ui/InterfaceUtils.kt @@ -162,13 +162,22 @@ fun isTablet(resources: Resources): Boolean { } /** - * Get the span count for most RecyclerViews + * Determine if the tablet is XLARGE, ignoring normal tablets. + */ +fun isXLTablet(resources: Resources): Boolean { + val layout = resources.configuration.screenLayout and Configuration.SCREENLAYOUT_SIZE_MASK + + return layout == Configuration.SCREENLAYOUT_SIZE_XLARGE +} + +/** + * Get the span count for most RecyclerViews. These probably work right on most displays. Trust me. */ fun RecyclerView.getSpans(): Int { return if (isLandscape(resources)) { - if (isTablet(resources)) 3 else 2 + if (isXLTablet(resources)) 3 else 2 } else { - if (isTablet(resources)) 2 else 1 + if (isXLTablet(resources)) 2 else 1 } } diff --git a/app/src/main/res/layout-land/fragment_playback.xml b/app/src/main/res/layout-land/fragment_playback.xml index 255579cfa..a5b07b5d9 100644 --- a/app/src/main/res/layout-land/fragment_playback.xml +++ b/app/src/main/res/layout-land/fragment_playback.xml @@ -4,9 +4,6 @@ xmlns:tools="http://schemas.android.com/tools" tools:context=".playback.PlaybackFragment"> - - - diff --git a/app/src/main/res/layout-xlarge/fragment_playback.xml b/app/src/main/res/layout-xlarge/fragment_playback.xml new file mode 100644 index 000000000..ff6606ac4 --- /dev/null +++ b/app/src/main/res/layout-xlarge/fragment_playback.xml @@ -0,0 +1,214 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 884ecae3d..dfd09bec9 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -3,7 +3,7 @@ Ein einfacher und flexibeler Musik-Player für Android. Musikwiedergabe - der Musikwiedergabe-Service von Auxio + der Musikwiedergabe-Dienst von Auxio Wieder Versuchen @@ -82,8 +82,8 @@ Wenn eine Abspielliste zu Ende ist Weiderholen und Pausieren Weiderholen - Halten - Shuffle-Einstellung merken + Stoppen + Zufällig-Einstellung merken Lassen Zufällig an, wenn ein neues Lied anspielen Zurückspulen, bevor zurück springen Zurückspulen, bevor zum vorheriger Lied springen diff --git a/info/ARCHITECTURE.md b/info/ARCHITECTURE.md index 57a161ae1..0869da64a 100644 --- a/info/ARCHITECTURE.md +++ b/info/ARCHITECTURE.md @@ -111,7 +111,7 @@ PlaybackStateManager───────────────────┘ `PlaybackStateManager` is the shared object that contains the master copy of the playback state, doing all operations on it. This object should ***NEVER*** be used in a UI, as it does not sanitize input and can cause major problems if a Volatile UI interacts with it. It's callback system is also prone to memory leaks if not cleared when done. `PlaybackViewModel` should be used instead, as it exposes stable data and safe functions that UI's can use to interact with the playback state. -`PlaybackService`'s job is to use the playback state to manage the ExoPlayer instance and also modify the state depending on system events, such as when a button is pressed on a headset. It should **never** be bound to, mostly because there is no need given that `PlaybackViewModel` exposes the same data in a much safer fashion. +`PlaybackService`'s job is to use the playback state to manage the ExoPlayer instance and notification and also modify the state depending on system events, such as when a button is pressed on a headset. It should **never** be bound to, mostly because there is no need given that `PlaybackViewModel` exposes the same data in a much safer fashion. #### `.recycler`