home: re-add grid spans

Re-add grid spans to HomeFragment when on landscape mode.
This commit is contained in:
OxygenCobalt 2021-08-22 09:01:30 -06:00
parent a3e7cb93aa
commit b5c5fabad0
No known key found for this signature in database
GPG key ID: 37DBE3621FE9AD47
10 changed files with 72 additions and 166 deletions

View file

@ -26,17 +26,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.Parent
import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.recycler.viewholders.AlbumViewHolder
import org.oxycblt.auxio.recycler.viewholders.ArtistViewHolder
import org.oxycblt.auxio.recycler.viewholders.GenreViewHolder
import org.oxycblt.auxio.recycler.viewholders.SongViewHolder
/**
* An adapter for displaying library items. Supports [Parent]s only.
* @author OxygenCobalt
*/
class HomeAdapter(
private val doOnClick: (data: BaseModel) -> Unit,
private val doOnLongClick: (view: View, data: BaseModel) -> Unit

View file

@ -25,7 +25,9 @@ import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.navigation.fragment.findNavController
import androidx.recyclerview.widget.RecyclerView
import androidx.viewpager2.adapter.FragmentStateAdapter
import androidx.viewpager2.widget.ViewPager2
import com.google.android.material.tabs.TabLayoutMediator
import org.oxycblt.auxio.MainFragmentDirections
import org.oxycblt.auxio.R
@ -35,12 +37,15 @@ import org.oxycblt.auxio.home.pager.ArtistListFragment
import org.oxycblt.auxio.home.pager.GenreListFragment
import org.oxycblt.auxio.home.pager.SongListFragment
import org.oxycblt.auxio.logD
import org.oxycblt.auxio.logE
import org.oxycblt.auxio.playback.PlaybackViewModel
import java.lang.Exception
/**
* The main "Launching Point" fragment of Auxio, allowing navigation to the detail
* views for each respective fragment.
* TODO: Re-add sorting (but new and improved)
* TODO: Fix issue where elevation will act wrong when switching tabs
* @author OxygenCobalt
*/
class HomeFragment : Fragment() {

View file

@ -23,17 +23,16 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.navigation.fragment.findNavController
import androidx.recyclerview.widget.GridLayoutManager
import org.oxycblt.auxio.databinding.FragmentHomeListBinding
import org.oxycblt.auxio.home.HomeAdapter
import org.oxycblt.auxio.home.HomeFragmentDirections
import org.oxycblt.auxio.music.MusicStore
import org.oxycblt.auxio.playback.PlaybackViewModel
import org.oxycblt.auxio.spans
import org.oxycblt.auxio.ui.newMenu
class AlbumListFragment : Fragment() {
private val playbackModel: PlaybackViewModel by viewModels()
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
@ -41,18 +40,25 @@ class AlbumListFragment : Fragment() {
): View {
val binding = FragmentHomeListBinding.inflate(inflater)
val adapter = HomeAdapter(
val homeAdapter = HomeAdapter(
doOnClick = { item ->
HomeFragmentDirections.actionShowAlbum(item.id)
findNavController().navigate(HomeFragmentDirections.actionShowAlbum(item.id))
},
::newMenu
)
adapter.updateData(MusicStore.getInstance().albums)
homeAdapter.updateData(MusicStore.getInstance().albums)
// --- UI SETUP ---
binding.homeRecycler.adapter = adapter
binding.homeRecycler.apply {
adapter = homeAdapter
setHasFixedSize(true)
if (spans != 1) {
layoutManager = GridLayoutManager(requireContext(), spans)
}
}
return binding.root
}

View file

@ -23,17 +23,16 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.navigation.fragment.findNavController
import androidx.recyclerview.widget.GridLayoutManager
import org.oxycblt.auxio.databinding.FragmentHomeListBinding
import org.oxycblt.auxio.home.HomeAdapter
import org.oxycblt.auxio.home.HomeFragmentDirections
import org.oxycblt.auxio.music.MusicStore
import org.oxycblt.auxio.playback.PlaybackViewModel
import org.oxycblt.auxio.spans
import org.oxycblt.auxio.ui.newMenu
class ArtistListFragment : Fragment() {
private val playbackModel: PlaybackViewModel by viewModels()
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
@ -41,18 +40,25 @@ class ArtistListFragment : Fragment() {
): View {
val binding = FragmentHomeListBinding.inflate(inflater)
val adapter = HomeAdapter(
val homeAdapter = HomeAdapter(
doOnClick = { item ->
HomeFragmentDirections.actionShowArtist(item.id)
findNavController().navigate(HomeFragmentDirections.actionShowArtist(item.id))
},
::newMenu
)
adapter.updateData(MusicStore.getInstance().artists)
homeAdapter.updateData(MusicStore.getInstance().artists)
// --- UI SETUP ---
binding.homeRecycler.adapter = adapter
binding.homeRecycler.apply {
adapter = homeAdapter
setHasFixedSize(true)
if (spans != 1) {
layoutManager = GridLayoutManager(requireContext(), spans)
}
}
return binding.root
}

View file

@ -23,17 +23,16 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.navigation.fragment.findNavController
import androidx.recyclerview.widget.GridLayoutManager
import org.oxycblt.auxio.databinding.FragmentHomeListBinding
import org.oxycblt.auxio.home.HomeAdapter
import org.oxycblt.auxio.home.HomeFragmentDirections
import org.oxycblt.auxio.music.MusicStore
import org.oxycblt.auxio.playback.PlaybackViewModel
import org.oxycblt.auxio.spans
import org.oxycblt.auxio.ui.newMenu
class GenreListFragment : Fragment() {
private val playbackModel: PlaybackViewModel by viewModels()
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
@ -41,18 +40,25 @@ class GenreListFragment : Fragment() {
): View {
val binding = FragmentHomeListBinding.inflate(inflater)
val adapter = HomeAdapter(
val homeAdapter = HomeAdapter(
doOnClick = { item ->
HomeFragmentDirections.actionShowGenre(item.id)
findNavController().navigate(HomeFragmentDirections.actionShowGenre(item.id))
},
::newMenu
)
adapter.updateData(MusicStore.getInstance().genres)
homeAdapter.updateData(MusicStore.getInstance().genres)
// --- UI SETUP ---
binding.homeRecycler.adapter = adapter
binding.homeRecycler.apply {
adapter = homeAdapter
setHasFixedSize(true)
if (spans != 1) {
layoutManager = GridLayoutManager(requireContext(), spans)
}
}
return binding.root
}

View file

@ -24,11 +24,13 @@ import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.recyclerview.widget.GridLayoutManager
import org.oxycblt.auxio.databinding.FragmentHomeListBinding
import org.oxycblt.auxio.home.HomeAdapter
import org.oxycblt.auxio.music.MusicStore
import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.playback.PlaybackViewModel
import org.oxycblt.auxio.spans
import org.oxycblt.auxio.ui.newMenu
class SongListFragment : Fragment() {
@ -41,18 +43,25 @@ class SongListFragment : Fragment() {
): View {
val binding = FragmentHomeListBinding.inflate(inflater)
val adapter = HomeAdapter(
val homeAdapter = HomeAdapter(
doOnClick = { item ->
playbackModel.playSong(item as Song)
},
::newMenu
)
adapter.updateData(MusicStore.getInstance().songs)
homeAdapter.updateData(MusicStore.getInstance().songs)
// --- UI SETUP ---
binding.homeRecycler.adapter = adapter
binding.homeRecycler.apply {
adapter = homeAdapter
setHasFixedSize(true)
if (spans != 1) {
layoutManager = GridLayoutManager(requireContext(), spans)
}
}
return binding.root
}

View file

@ -1,133 +0,0 @@
/*
* Copyright (c) 2021 Auxio Project
* SlideLinearLayout.kt is part of Auxio.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package org.oxycblt.auxio.ui
import android.annotation.SuppressLint
import android.content.Context
import android.graphics.Canvas
import android.util.AttributeSet
import android.view.View
import android.view.ViewGroup
import android.widget.LinearLayout
import org.oxycblt.auxio.logD
import org.oxycblt.auxio.logE
import java.lang.reflect.Field
/**
* Hack layout that fixes an issue where disappearing views would draw over non-disappearing
* views when animated with a stock LayoutTransition. If something breaks on the playback controls
* or nav bar, this is probably the culprit.
*
* "But oxygencobalt, couldn't you just write your own animation code and run that instea-"
* **NO.**
*
* Adapted from this StackOverflow answer:
* https://stackoverflow.com/a/35087229
* @author OxygenCobalt
*/
class SlideLinearLayout @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = -1
) : LinearLayout(context, attrs, defStyleAttr) {
@SuppressLint("DiscouragedPrivateApi")
private val disappearingChildrenField: Field? = try {
// We need to read this field to correctly draw the disappearing children
// If google ever hides this API I am going to scream, because its their busted
// ViewGroup code that forces me to do this in the first place
ViewGroup::class.java.getDeclaredField("mDisappearingChildren").also {
it.isAccessible = true
}
} catch (e: NoSuchFieldException) {
logE("Could not get mDisappearingChildren. This is very ungood.")
null
}
private var disappearingChildren: List<View>? = null
private var dumpView: View? = null
private var doDrawingTrick: Boolean = false
init {
if (disappearingChildrenField != null) {
// Create a invisible junk view and add it, which makes all the magic happen [I think].
dumpView = View(context)
addView(dumpView, 0, 0)
}
}
override fun dispatchDraw(canvas: Canvas?) {
doDrawingTrick = beforeDispatchDraw()
super.dispatchDraw(canvas)
if (doDrawingTrick) {
doDrawingTrick = false
}
}
override fun drawChild(canvas: Canvas?, child: View?, drawingTime: Long): Boolean {
val children = getDisappearingChildren()
if (doDrawingTrick && children != null) {
// Use the dump view as a marker for when to do the trick
if (child == dumpView) {
// I dont even know what this does.
var consumed = false
children.forEach { view ->
consumed = consumed || super.drawChild(canvas, view, drawingTime)
}
return consumed
} else if (children.contains(child)) {
// Ignore the disappearing children
return false
}
}
return super.drawChild(canvas, child, drawingTime)
}
private fun beforeDispatchDraw(): Boolean {
val children = getDisappearingChildren()
// Dont do trick if there are no disappearing children or if there arent any children other
// than the dump view.
if (children == null || children.isEmpty() || childCount <= 1) {
return false
}
return true
}
private fun getDisappearingChildren(): List<View>? {
if (disappearingChildrenField == null || disappearingChildren != null) {
return disappearingChildren
}
try {
@Suppress("UNCHECKED_CAST")
disappearingChildren = disappearingChildrenField.get(this) as List<View>?
} catch (e: Exception) {
logD("Could not get list of disappearing children.")
}
return disappearingChildren
}
}

View file

@ -44,7 +44,7 @@
android:layout_height="match_parent"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior"
tools:listitem="@layout/item_artist" />
tools:layout="@layout/fragment_home_list" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</layout>

View file

@ -21,6 +21,15 @@
<item
android:id="@+id/option_sort_alpha_up"
android:title="@string/lbl_sort_alpha_up" />
<item
android:id="@+id/option_sort_artist"
android:title="@string/lbl_sort_artist" />
<item
android:id="@+id/option_sort_album"
android:title="@string/lbl_sort_album" />
<item
android:id="@+id/option_sort_year"
android:title="@string/lbl_sort_year" />
</group>
</menu>
</item>

View file

@ -25,6 +25,9 @@
<string name="lbl_sort">Sort</string>
<string name="lbl_sort_alpha_down">Ascending</string>
<string name="lbl_sort_alpha_up">Descending</string>
<string name="lbl_sort_artist">Artist</string>
<string name="lbl_sort_album">Album</string>
<string name="lbl_sort_year">Year</string>
<string name="lbl_play">Play</string>
<string name="lbl_shuffle">Shuffle</string>