From 07e7e1ae5b39d5b0f82818fd41822d78b63d3e34 Mon Sep 17 00:00:00 2001 From: OxygenCobalt Date: Mon, 14 Dec 2020 12:01:24 -0700 Subject: [PATCH] Add landscape support to list fragments Add a landscape mode for LibraryFragment & SongsFragment. --- .../oxycblt/auxio/library/LibraryFragment.kt | 21 +++++++++++++++++-- .../oxycblt/auxio/library/LibraryViewModel.kt | 8 ------- .../org/oxycblt/auxio/music/MusicStore.kt | 4 ++-- .../auxio/music/processing/MusicLoader.kt | 2 +- .../org/oxycblt/auxio/songs/SongsFragment.kt | 8 +++++++ .../main/res/layout-land/fragment_main.xml | 3 +-- .../res/layout-land/fragment_playback.xml | 5 ++--- app/src/main/res/layout/fragment_playback.xml | 8 +++---- app/src/main/res/values/dimens.xml | 2 +- 9 files changed, 38 insertions(+), 23 deletions(-) diff --git a/app/src/main/java/org/oxycblt/auxio/library/LibraryFragment.kt b/app/src/main/java/org/oxycblt/auxio/library/LibraryFragment.kt index d226a836f..554e51931 100644 --- a/app/src/main/java/org/oxycblt/auxio/library/LibraryFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/library/LibraryFragment.kt @@ -12,6 +12,7 @@ import androidx.core.view.forEach import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels import androidx.navigation.fragment.findNavController +import androidx.recyclerview.widget.GridLayoutManager import androidx.transition.Fade import androidx.transition.TransitionManager import org.oxycblt.auxio.R @@ -23,10 +24,12 @@ import org.oxycblt.auxio.music.Album import org.oxycblt.auxio.music.Artist import org.oxycblt.auxio.music.BaseModel import org.oxycblt.auxio.music.Genre +import org.oxycblt.auxio.music.Header import org.oxycblt.auxio.music.Song import org.oxycblt.auxio.playback.PlaybackViewModel import org.oxycblt.auxio.settings.SettingsManager import org.oxycblt.auxio.utils.applyColor +import org.oxycblt.auxio.utils.isLandscape import org.oxycblt.auxio.utils.resolveAttr import org.oxycblt.auxio.utils.setupAlbumActions import org.oxycblt.auxio.utils.setupArtistActions @@ -92,7 +95,6 @@ class LibraryFragment : Fragment(), SearchView.OnQueryTextListener { searchView.maxWidth = Int.MAX_VALUE searchView.setOnQueryTextListener(this@LibraryFragment) searchView.setOnQueryTextFocusChangeListener { _, hasFocus -> - libraryModel.updateSearchFocusStatus(hasFocus) item.isVisible = !hasFocus } @@ -100,6 +102,7 @@ class LibraryFragment : Fragment(), SearchView.OnQueryTextListener { override fun onMenuItemActionExpand(item: MenuItem): Boolean { binding.libraryRecycler.adapter = searchAdapter setGroupVisible(R.id.group_sorting, false) + libraryModel.resetQuery() return true @@ -108,6 +111,7 @@ class LibraryFragment : Fragment(), SearchView.OnQueryTextListener { override fun onMenuItemActionCollapse(item: MenuItem): Boolean { binding.libraryRecycler.adapter = libraryAdapter setGroupVisible(R.id.group_sorting, true) + libraryModel.resetQuery() return true @@ -119,6 +123,19 @@ class LibraryFragment : Fragment(), SearchView.OnQueryTextListener { binding.libraryRecycler.apply { adapter = libraryAdapter setHasFixedSize(true) + + if (isLandscape(resources)) { + layoutManager = GridLayoutManager(requireContext(), GridLayoutManager.VERTICAL).apply { + spanCount = 3 + spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() { + override fun getSpanSize(position: Int): Int { + return if (binding.libraryRecycler.adapter == searchAdapter) { + if (searchAdapter.currentList[position] is Header) 3 else 1 + } else 1 + } + } + } + } } // --- VIEWMODEL SETUP --- @@ -128,7 +145,7 @@ class LibraryFragment : Fragment(), SearchView.OnQueryTextListener { } libraryModel.searchResults.observe(viewLifecycleOwner) { - if (libraryModel.searchHasFocus) { + if (binding.libraryRecycler.adapter == searchAdapter) { searchAdapter.submitList(it) { binding.libraryRecycler.scrollToPosition(0) } diff --git a/app/src/main/java/org/oxycblt/auxio/library/LibraryViewModel.kt b/app/src/main/java/org/oxycblt/auxio/library/LibraryViewModel.kt index edcd6ec05..180025f7f 100644 --- a/app/src/main/java/org/oxycblt/auxio/library/LibraryViewModel.kt +++ b/app/src/main/java/org/oxycblt/auxio/library/LibraryViewModel.kt @@ -34,10 +34,6 @@ class LibraryViewModel : ViewModel(), SettingsManager.Callback { private var mIsNavigating = false val isNavigating: Boolean get() = mIsNavigating - - private var mSearchHasFocus = false - val searchHasFocus: Boolean get() = mSearchHasFocus - private val settingsManager = SettingsManager.getInstance() private val musicStore = MusicStore.getInstance() @@ -111,10 +107,6 @@ class LibraryViewModel : ViewModel(), SettingsManager.Callback { } } - fun updateSearchFocusStatus(value: Boolean) { - mSearchHasFocus = value - } - fun resetQuery() { mSearchResults.value = listOf() } diff --git a/app/src/main/java/org/oxycblt/auxio/music/MusicStore.kt b/app/src/main/java/org/oxycblt/auxio/music/MusicStore.kt index e0cfc4ed0..7df0e9061 100644 --- a/app/src/main/java/org/oxycblt/auxio/music/MusicStore.kt +++ b/app/src/main/java/org/oxycblt/auxio/music/MusicStore.kt @@ -45,7 +45,7 @@ class MusicStore private constructor() { */ suspend fun load(app: Application): MusicLoaderResponse { return withContext(Dispatchers.IO) { - logD("Starting initial music load...") + this@MusicStore.logD("Starting initial music load...") val start = System.currentTimeMillis() @@ -83,7 +83,7 @@ class MusicStore private constructor() { val elapsed = System.currentTimeMillis() - start - logD("Music load completed successfully in ${elapsed}ms.") + this@MusicStore.logD("Music load completed successfully in ${elapsed}ms.") loaded = true } diff --git a/app/src/main/java/org/oxycblt/auxio/music/processing/MusicLoader.kt b/app/src/main/java/org/oxycblt/auxio/music/processing/MusicLoader.kt index b4562f835..f733eed0e 100644 --- a/app/src/main/java/org/oxycblt/auxio/music/processing/MusicLoader.kt +++ b/app/src/main/java/org/oxycblt/auxio/music/processing/MusicLoader.kt @@ -144,6 +144,7 @@ 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), @@ -155,7 +156,6 @@ class MusicLoader( artistGenreCursor?.let { cursor -> val idIndex = cursor.getColumnIndexOrThrow(Genres.Members.ARTIST_ID) - while (cursor.moveToNext()) { val id = cursor.getLong(idIndex) diff --git a/app/src/main/java/org/oxycblt/auxio/songs/SongsFragment.kt b/app/src/main/java/org/oxycblt/auxio/songs/SongsFragment.kt index 0705f1b0c..260f9f943 100644 --- a/app/src/main/java/org/oxycblt/auxio/songs/SongsFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/songs/SongsFragment.kt @@ -8,6 +8,7 @@ import android.view.ViewGroup import androidx.appcompat.widget.PopupMenu import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels +import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.LinearLayoutManager import com.reddit.indicatorfastscroll.FastScrollItemIndicator import com.reddit.indicatorfastscroll.FastScrollerView @@ -17,6 +18,7 @@ import org.oxycblt.auxio.logD import org.oxycblt.auxio.music.MusicStore import org.oxycblt.auxio.playback.PlaybackViewModel import org.oxycblt.auxio.settings.SettingsManager +import org.oxycblt.auxio.utils.isLandscape import org.oxycblt.auxio.utils.setupSongActions import kotlin.math.ceil @@ -70,6 +72,12 @@ class SongsFragment : Fragment() { adapter = songAdapter setHasFixedSize(true) + if (isLandscape(resources)) { + layoutManager = GridLayoutManager(requireContext(), GridLayoutManager.VERTICAL).also { + it.spanCount = 3 + } + } + post { if (computeVerticalScrollRange() < height) { binding.songFastScroll.visibility = View.GONE diff --git a/app/src/main/res/layout-land/fragment_main.xml b/app/src/main/res/layout-land/fragment_main.xml index eaedd8339..4f42ae865 100644 --- a/app/src/main/res/layout-land/fragment_main.xml +++ b/app/src/main/res/layout-land/fragment_main.xml @@ -28,7 +28,7 @@ android:layout_width="0dp" android:layout_height="0dp" android:background="?android:attr/windowBackground" - android:elevation="@dimen/elevation_weird" + android:elevation="@dimen/elevation_high" android:outlineProvider="bounds" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" @@ -41,7 +41,6 @@ android:layout_width="0dp" android:layout_height="wrap_content" android:background="@color/background" - app:elevation="@dimen/elevation_normal" app:labelVisibilityMode="selected" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintStart_toStartOf="parent" diff --git a/app/src/main/res/layout-land/fragment_playback.xml b/app/src/main/res/layout-land/fragment_playback.xml index 66771aac4..4b3e95b62 100644 --- a/app/src/main/res/layout-land/fragment_playback.xml +++ b/app/src/main/res/layout-land/fragment_playback.xml @@ -27,7 +27,6 @@ diff --git a/app/src/main/res/layout/fragment_playback.xml b/app/src/main/res/layout/fragment_playback.xml index 22326a0d5..05f671b3a 100644 --- a/app/src/main/res/layout/fragment_playback.xml +++ b/app/src/main/res/layout/fragment_playback.xml @@ -193,13 +193,13 @@ style="@style/Widget.AppCompat.Button.Borderless" android:layout_width="@dimen/size_play_pause_compact" android:layout_height="@dimen/size_play_pause_compact" - android:layout_marginEnd="@dimen/margin_mid_large" + android:layout_marginStart="@dimen/margin_mid_large" android:background="@drawable/ui_unbounded_ripple" android:contentDescription="@{playbackModel.isShuffling() ? @string/description_shuffle_off : @string/description_shuffle_on" android:onClick="@{() -> playbackModel.invertShuffleStatus()}" android:src="@drawable/ic_shuffle_large" app:layout_constraintBottom_toBottomOf="@+id/playback_play_pause" - app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toEndOf="@+id/playback_skip_next" app:layout_constraintTop_toTopOf="@+id/playback_play_pause" /> diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index 1014e0db2..6a41fa806 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -10,6 +10,7 @@ 10dp 16dp 24dp + 32dp 2dp @@ -39,7 +40,6 @@ 4dp - 4.2dp 8dp 4dp \ No newline at end of file