home: re-add grid spans
Re-add grid spans to HomeFragment when on landscape mode.
This commit is contained in:
parent
a3e7cb93aa
commit
b5c5fabad0
10 changed files with 72 additions and 166 deletions
|
@ -26,17 +26,12 @@ import org.oxycblt.auxio.music.Album
|
||||||
import org.oxycblt.auxio.music.Artist
|
import org.oxycblt.auxio.music.Artist
|
||||||
import org.oxycblt.auxio.music.BaseModel
|
import org.oxycblt.auxio.music.BaseModel
|
||||||
import org.oxycblt.auxio.music.Genre
|
import org.oxycblt.auxio.music.Genre
|
||||||
import org.oxycblt.auxio.music.Parent
|
|
||||||
import org.oxycblt.auxio.music.Song
|
import org.oxycblt.auxio.music.Song
|
||||||
import org.oxycblt.auxio.recycler.viewholders.AlbumViewHolder
|
import org.oxycblt.auxio.recycler.viewholders.AlbumViewHolder
|
||||||
import org.oxycblt.auxio.recycler.viewholders.ArtistViewHolder
|
import org.oxycblt.auxio.recycler.viewholders.ArtistViewHolder
|
||||||
import org.oxycblt.auxio.recycler.viewholders.GenreViewHolder
|
import org.oxycblt.auxio.recycler.viewholders.GenreViewHolder
|
||||||
import org.oxycblt.auxio.recycler.viewholders.SongViewHolder
|
import org.oxycblt.auxio.recycler.viewholders.SongViewHolder
|
||||||
|
|
||||||
/**
|
|
||||||
* An adapter for displaying library items. Supports [Parent]s only.
|
|
||||||
* @author OxygenCobalt
|
|
||||||
*/
|
|
||||||
class HomeAdapter(
|
class HomeAdapter(
|
||||||
private val doOnClick: (data: BaseModel) -> Unit,
|
private val doOnClick: (data: BaseModel) -> Unit,
|
||||||
private val doOnLongClick: (view: View, data: BaseModel) -> Unit
|
private val doOnLongClick: (view: View, data: BaseModel) -> Unit
|
||||||
|
|
|
@ -25,7 +25,9 @@ import android.view.ViewGroup
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.fragment.app.activityViewModels
|
import androidx.fragment.app.activityViewModels
|
||||||
import androidx.navigation.fragment.findNavController
|
import androidx.navigation.fragment.findNavController
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import androidx.viewpager2.adapter.FragmentStateAdapter
|
import androidx.viewpager2.adapter.FragmentStateAdapter
|
||||||
|
import androidx.viewpager2.widget.ViewPager2
|
||||||
import com.google.android.material.tabs.TabLayoutMediator
|
import com.google.android.material.tabs.TabLayoutMediator
|
||||||
import org.oxycblt.auxio.MainFragmentDirections
|
import org.oxycblt.auxio.MainFragmentDirections
|
||||||
import org.oxycblt.auxio.R
|
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.GenreListFragment
|
||||||
import org.oxycblt.auxio.home.pager.SongListFragment
|
import org.oxycblt.auxio.home.pager.SongListFragment
|
||||||
import org.oxycblt.auxio.logD
|
import org.oxycblt.auxio.logD
|
||||||
|
import org.oxycblt.auxio.logE
|
||||||
import org.oxycblt.auxio.playback.PlaybackViewModel
|
import org.oxycblt.auxio.playback.PlaybackViewModel
|
||||||
|
import java.lang.Exception
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The main "Launching Point" fragment of Auxio, allowing navigation to the detail
|
* The main "Launching Point" fragment of Auxio, allowing navigation to the detail
|
||||||
* views for each respective fragment.
|
* views for each respective fragment.
|
||||||
* TODO: Re-add sorting (but new and improved)
|
* TODO: Re-add sorting (but new and improved)
|
||||||
|
* TODO: Fix issue where elevation will act wrong when switching tabs
|
||||||
* @author OxygenCobalt
|
* @author OxygenCobalt
|
||||||
*/
|
*/
|
||||||
class HomeFragment : Fragment() {
|
class HomeFragment : Fragment() {
|
||||||
|
|
|
@ -23,17 +23,16 @@ import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.fragment.app.Fragment
|
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.databinding.FragmentHomeListBinding
|
||||||
import org.oxycblt.auxio.home.HomeAdapter
|
import org.oxycblt.auxio.home.HomeAdapter
|
||||||
import org.oxycblt.auxio.home.HomeFragmentDirections
|
import org.oxycblt.auxio.home.HomeFragmentDirections
|
||||||
import org.oxycblt.auxio.music.MusicStore
|
import org.oxycblt.auxio.music.MusicStore
|
||||||
import org.oxycblt.auxio.playback.PlaybackViewModel
|
import org.oxycblt.auxio.spans
|
||||||
import org.oxycblt.auxio.ui.newMenu
|
import org.oxycblt.auxio.ui.newMenu
|
||||||
|
|
||||||
class AlbumListFragment : Fragment() {
|
class AlbumListFragment : Fragment() {
|
||||||
private val playbackModel: PlaybackViewModel by viewModels()
|
|
||||||
|
|
||||||
override fun onCreateView(
|
override fun onCreateView(
|
||||||
inflater: LayoutInflater,
|
inflater: LayoutInflater,
|
||||||
container: ViewGroup?,
|
container: ViewGroup?,
|
||||||
|
@ -41,18 +40,25 @@ class AlbumListFragment : Fragment() {
|
||||||
): View {
|
): View {
|
||||||
val binding = FragmentHomeListBinding.inflate(inflater)
|
val binding = FragmentHomeListBinding.inflate(inflater)
|
||||||
|
|
||||||
val adapter = HomeAdapter(
|
val homeAdapter = HomeAdapter(
|
||||||
doOnClick = { item ->
|
doOnClick = { item ->
|
||||||
HomeFragmentDirections.actionShowAlbum(item.id)
|
findNavController().navigate(HomeFragmentDirections.actionShowAlbum(item.id))
|
||||||
},
|
},
|
||||||
::newMenu
|
::newMenu
|
||||||
)
|
)
|
||||||
|
|
||||||
adapter.updateData(MusicStore.getInstance().albums)
|
homeAdapter.updateData(MusicStore.getInstance().albums)
|
||||||
|
|
||||||
// --- UI SETUP ---
|
// --- UI SETUP ---
|
||||||
|
|
||||||
binding.homeRecycler.adapter = adapter
|
binding.homeRecycler.apply {
|
||||||
|
adapter = homeAdapter
|
||||||
|
setHasFixedSize(true)
|
||||||
|
|
||||||
|
if (spans != 1) {
|
||||||
|
layoutManager = GridLayoutManager(requireContext(), spans)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return binding.root
|
return binding.root
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,17 +23,16 @@ import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.fragment.app.Fragment
|
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.databinding.FragmentHomeListBinding
|
||||||
import org.oxycblt.auxio.home.HomeAdapter
|
import org.oxycblt.auxio.home.HomeAdapter
|
||||||
import org.oxycblt.auxio.home.HomeFragmentDirections
|
import org.oxycblt.auxio.home.HomeFragmentDirections
|
||||||
import org.oxycblt.auxio.music.MusicStore
|
import org.oxycblt.auxio.music.MusicStore
|
||||||
import org.oxycblt.auxio.playback.PlaybackViewModel
|
import org.oxycblt.auxio.spans
|
||||||
import org.oxycblt.auxio.ui.newMenu
|
import org.oxycblt.auxio.ui.newMenu
|
||||||
|
|
||||||
class ArtistListFragment : Fragment() {
|
class ArtistListFragment : Fragment() {
|
||||||
private val playbackModel: PlaybackViewModel by viewModels()
|
|
||||||
|
|
||||||
override fun onCreateView(
|
override fun onCreateView(
|
||||||
inflater: LayoutInflater,
|
inflater: LayoutInflater,
|
||||||
container: ViewGroup?,
|
container: ViewGroup?,
|
||||||
|
@ -41,18 +40,25 @@ class ArtistListFragment : Fragment() {
|
||||||
): View {
|
): View {
|
||||||
val binding = FragmentHomeListBinding.inflate(inflater)
|
val binding = FragmentHomeListBinding.inflate(inflater)
|
||||||
|
|
||||||
val adapter = HomeAdapter(
|
val homeAdapter = HomeAdapter(
|
||||||
doOnClick = { item ->
|
doOnClick = { item ->
|
||||||
HomeFragmentDirections.actionShowArtist(item.id)
|
findNavController().navigate(HomeFragmentDirections.actionShowArtist(item.id))
|
||||||
},
|
},
|
||||||
::newMenu
|
::newMenu
|
||||||
)
|
)
|
||||||
|
|
||||||
adapter.updateData(MusicStore.getInstance().artists)
|
homeAdapter.updateData(MusicStore.getInstance().artists)
|
||||||
|
|
||||||
// --- UI SETUP ---
|
// --- UI SETUP ---
|
||||||
|
|
||||||
binding.homeRecycler.adapter = adapter
|
binding.homeRecycler.apply {
|
||||||
|
adapter = homeAdapter
|
||||||
|
setHasFixedSize(true)
|
||||||
|
|
||||||
|
if (spans != 1) {
|
||||||
|
layoutManager = GridLayoutManager(requireContext(), spans)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return binding.root
|
return binding.root
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,17 +23,16 @@ import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.fragment.app.Fragment
|
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.databinding.FragmentHomeListBinding
|
||||||
import org.oxycblt.auxio.home.HomeAdapter
|
import org.oxycblt.auxio.home.HomeAdapter
|
||||||
import org.oxycblt.auxio.home.HomeFragmentDirections
|
import org.oxycblt.auxio.home.HomeFragmentDirections
|
||||||
import org.oxycblt.auxio.music.MusicStore
|
import org.oxycblt.auxio.music.MusicStore
|
||||||
import org.oxycblt.auxio.playback.PlaybackViewModel
|
import org.oxycblt.auxio.spans
|
||||||
import org.oxycblt.auxio.ui.newMenu
|
import org.oxycblt.auxio.ui.newMenu
|
||||||
|
|
||||||
class GenreListFragment : Fragment() {
|
class GenreListFragment : Fragment() {
|
||||||
private val playbackModel: PlaybackViewModel by viewModels()
|
|
||||||
|
|
||||||
override fun onCreateView(
|
override fun onCreateView(
|
||||||
inflater: LayoutInflater,
|
inflater: LayoutInflater,
|
||||||
container: ViewGroup?,
|
container: ViewGroup?,
|
||||||
|
@ -41,18 +40,25 @@ class GenreListFragment : Fragment() {
|
||||||
): View {
|
): View {
|
||||||
val binding = FragmentHomeListBinding.inflate(inflater)
|
val binding = FragmentHomeListBinding.inflate(inflater)
|
||||||
|
|
||||||
val adapter = HomeAdapter(
|
val homeAdapter = HomeAdapter(
|
||||||
doOnClick = { item ->
|
doOnClick = { item ->
|
||||||
HomeFragmentDirections.actionShowGenre(item.id)
|
findNavController().navigate(HomeFragmentDirections.actionShowGenre(item.id))
|
||||||
},
|
},
|
||||||
::newMenu
|
::newMenu
|
||||||
)
|
)
|
||||||
|
|
||||||
adapter.updateData(MusicStore.getInstance().genres)
|
homeAdapter.updateData(MusicStore.getInstance().genres)
|
||||||
|
|
||||||
// --- UI SETUP ---
|
// --- UI SETUP ---
|
||||||
|
|
||||||
binding.homeRecycler.adapter = adapter
|
binding.homeRecycler.apply {
|
||||||
|
adapter = homeAdapter
|
||||||
|
setHasFixedSize(true)
|
||||||
|
|
||||||
|
if (spans != 1) {
|
||||||
|
layoutManager = GridLayoutManager(requireContext(), spans)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return binding.root
|
return binding.root
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,11 +24,13 @@ import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.fragment.app.viewModels
|
import androidx.fragment.app.viewModels
|
||||||
|
import androidx.recyclerview.widget.GridLayoutManager
|
||||||
import org.oxycblt.auxio.databinding.FragmentHomeListBinding
|
import org.oxycblt.auxio.databinding.FragmentHomeListBinding
|
||||||
import org.oxycblt.auxio.home.HomeAdapter
|
import org.oxycblt.auxio.home.HomeAdapter
|
||||||
import org.oxycblt.auxio.music.MusicStore
|
import org.oxycblt.auxio.music.MusicStore
|
||||||
import org.oxycblt.auxio.music.Song
|
import org.oxycblt.auxio.music.Song
|
||||||
import org.oxycblt.auxio.playback.PlaybackViewModel
|
import org.oxycblt.auxio.playback.PlaybackViewModel
|
||||||
|
import org.oxycblt.auxio.spans
|
||||||
import org.oxycblt.auxio.ui.newMenu
|
import org.oxycblt.auxio.ui.newMenu
|
||||||
|
|
||||||
class SongListFragment : Fragment() {
|
class SongListFragment : Fragment() {
|
||||||
|
@ -41,18 +43,25 @@ class SongListFragment : Fragment() {
|
||||||
): View {
|
): View {
|
||||||
val binding = FragmentHomeListBinding.inflate(inflater)
|
val binding = FragmentHomeListBinding.inflate(inflater)
|
||||||
|
|
||||||
val adapter = HomeAdapter(
|
val homeAdapter = HomeAdapter(
|
||||||
doOnClick = { item ->
|
doOnClick = { item ->
|
||||||
playbackModel.playSong(item as Song)
|
playbackModel.playSong(item as Song)
|
||||||
},
|
},
|
||||||
::newMenu
|
::newMenu
|
||||||
)
|
)
|
||||||
|
|
||||||
adapter.updateData(MusicStore.getInstance().songs)
|
homeAdapter.updateData(MusicStore.getInstance().songs)
|
||||||
|
|
||||||
// --- UI SETUP ---
|
// --- UI SETUP ---
|
||||||
|
|
||||||
binding.homeRecycler.adapter = adapter
|
binding.homeRecycler.apply {
|
||||||
|
adapter = homeAdapter
|
||||||
|
setHasFixedSize(true)
|
||||||
|
|
||||||
|
if (spans != 1) {
|
||||||
|
layoutManager = GridLayoutManager(requireContext(), spans)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return binding.root
|
return binding.root
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -44,7 +44,7 @@
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||||
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior"
|
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>
|
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||||
</layout>
|
</layout>
|
|
@ -21,6 +21,15 @@
|
||||||
<item
|
<item
|
||||||
android:id="@+id/option_sort_alpha_up"
|
android:id="@+id/option_sort_alpha_up"
|
||||||
android:title="@string/lbl_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>
|
</group>
|
||||||
</menu>
|
</menu>
|
||||||
</item>
|
</item>
|
||||||
|
|
|
@ -25,6 +25,9 @@
|
||||||
<string name="lbl_sort">Sort</string>
|
<string name="lbl_sort">Sort</string>
|
||||||
<string name="lbl_sort_alpha_down">Ascending</string>
|
<string name="lbl_sort_alpha_down">Ascending</string>
|
||||||
<string name="lbl_sort_alpha_up">Descending</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_play">Play</string>
|
||||||
<string name="lbl_shuffle">Shuffle</string>
|
<string name="lbl_shuffle">Shuffle</string>
|
||||||
|
|
Loading…
Reference in a new issue