Add actionmenu extension function
Simplify menu creation by using a Fragment extension to create a new ActionMenu.
This commit is contained in:
parent
eb5292d083
commit
26dd1036ec
27 changed files with 67 additions and 80 deletions
|
@ -18,7 +18,7 @@ import org.oxycblt.auxio.playback.state.PlaybackMode
|
|||
import org.oxycblt.auxio.recycler.CenterSmoothScroller
|
||||
import org.oxycblt.auxio.ui.ActionMenu
|
||||
import org.oxycblt.auxio.ui.createToast
|
||||
import org.oxycblt.auxio.ui.requireCompatActivity
|
||||
import org.oxycblt.auxio.ui.newMenu
|
||||
|
||||
/**
|
||||
* The [DetailFragment] for an album.
|
||||
|
@ -47,9 +47,7 @@ class AlbumDetailFragment : DetailFragment() {
|
|||
val detailAdapter = AlbumDetailAdapter(
|
||||
detailModel, playbackModel, viewLifecycleOwner,
|
||||
doOnClick = { playbackModel.playSong(it, PlaybackMode.IN_ALBUM) },
|
||||
doOnLongClick = { view, data ->
|
||||
ActionMenu(requireCompatActivity(), view, data, ActionMenu.FLAG_IN_ALBUM)
|
||||
}
|
||||
doOnLongClick = { view, data -> newMenu(view, data, ActionMenu.FLAG_IN_ALBUM) }
|
||||
)
|
||||
|
||||
// --- UI SETUP ---
|
||||
|
|
|
@ -15,7 +15,7 @@ import org.oxycblt.auxio.music.Genre
|
|||
import org.oxycblt.auxio.music.MusicStore
|
||||
import org.oxycblt.auxio.music.Song
|
||||
import org.oxycblt.auxio.ui.ActionMenu
|
||||
import org.oxycblt.auxio.ui.requireCompatActivity
|
||||
import org.oxycblt.auxio.ui.newMenu
|
||||
|
||||
/**
|
||||
* The [DetailFragment] for an artist.
|
||||
|
@ -53,9 +53,7 @@ class ArtistDetailFragment : DetailFragment() {
|
|||
)
|
||||
}
|
||||
},
|
||||
doOnLongClick = { view, data ->
|
||||
ActionMenu(requireCompatActivity(), view, data, ActionMenu.FLAG_IN_ARTIST)
|
||||
}
|
||||
doOnLongClick = { view, data -> newMenu(view, data, ActionMenu.FLAG_IN_ARTIST) }
|
||||
)
|
||||
|
||||
// --- UI SETUP ---
|
||||
|
|
|
@ -15,7 +15,7 @@ import org.oxycblt.auxio.music.MusicStore
|
|||
import org.oxycblt.auxio.music.Song
|
||||
import org.oxycblt.auxio.playback.state.PlaybackMode
|
||||
import org.oxycblt.auxio.ui.ActionMenu
|
||||
import org.oxycblt.auxio.ui.requireCompatActivity
|
||||
import org.oxycblt.auxio.ui.newMenu
|
||||
|
||||
/**
|
||||
* The [DetailFragment] for a genre.
|
||||
|
@ -46,9 +46,7 @@ class GenreDetailFragment : DetailFragment() {
|
|||
doOnClick = {
|
||||
playbackModel.playSong(it, PlaybackMode.IN_GENRE)
|
||||
},
|
||||
doOnLongClick = { view, data ->
|
||||
ActionMenu(requireCompatActivity(), view, data, ActionMenu.FLAG_IN_GENRE)
|
||||
}
|
||||
doOnLongClick = { view, data -> newMenu(view, data, ActionMenu.FLAG_IN_GENRE) }
|
||||
)
|
||||
|
||||
// --- UI SETUP ---
|
||||
|
|
|
@ -17,10 +17,9 @@ import org.oxycblt.auxio.music.Artist
|
|||
import org.oxycblt.auxio.music.Genre
|
||||
import org.oxycblt.auxio.music.Parent
|
||||
import org.oxycblt.auxio.music.Song
|
||||
import org.oxycblt.auxio.ui.ActionMenu
|
||||
import org.oxycblt.auxio.ui.fixAnimInfoLeak
|
||||
import org.oxycblt.auxio.ui.getSpans
|
||||
import org.oxycblt.auxio.ui.requireCompatActivity
|
||||
import org.oxycblt.auxio.ui.newMenu
|
||||
|
||||
/**
|
||||
* A [Fragment] that shows a custom list of [Genre], [Artist], or [Album] data. Also allows for
|
||||
|
@ -37,9 +36,7 @@ class LibraryFragment : Fragment() {
|
|||
): View {
|
||||
val binding = FragmentLibraryBinding.inflate(inflater)
|
||||
|
||||
val libraryAdapter = LibraryAdapter(::onItemSelection) { view, data ->
|
||||
ActionMenu(requireCompatActivity(), view, data, ActionMenu.FLAG_NONE)
|
||||
}
|
||||
val libraryAdapter = LibraryAdapter(::onItemSelection) { view, data -> newMenu(view, data) }
|
||||
|
||||
// --- UI SETUP ---
|
||||
|
||||
|
@ -63,8 +60,8 @@ class LibraryFragment : Fragment() {
|
|||
binding.libraryRecycler.apply {
|
||||
adapter = libraryAdapter
|
||||
setHasFixedSize(true)
|
||||
val spans = getSpans()
|
||||
|
||||
val spans = getSpans()
|
||||
if (spans != 1) {
|
||||
layoutManager = GridLayoutManager(requireContext(), spans)
|
||||
}
|
||||
|
|
|
@ -23,10 +23,9 @@ import org.oxycblt.auxio.music.Header
|
|||
import org.oxycblt.auxio.music.Song
|
||||
import org.oxycblt.auxio.playback.PlaybackViewModel
|
||||
import org.oxycblt.auxio.ui.Accent
|
||||
import org.oxycblt.auxio.ui.ActionMenu
|
||||
import org.oxycblt.auxio.ui.fixAnimInfoLeak
|
||||
import org.oxycblt.auxio.ui.getSpans
|
||||
import org.oxycblt.auxio.ui.requireCompatActivity
|
||||
import org.oxycblt.auxio.ui.newMenu
|
||||
import org.oxycblt.auxio.ui.toColor
|
||||
import org.oxycblt.auxio.ui.toStateList
|
||||
|
||||
|
@ -51,10 +50,7 @@ class SearchFragment : Fragment() {
|
|||
// Apply the accents manually. Not going through the mess of converting my app's
|
||||
// styling to Material given all the second-and-third-order effects it has.
|
||||
val accent = Accent.get().color.toColor(requireContext())
|
||||
|
||||
val searchAdapter = SearchAdapter(::onItemSelection) { view, data ->
|
||||
ActionMenu(requireCompatActivity(), view, data, ActionMenu.FLAG_NONE)
|
||||
}
|
||||
val searchAdapter = SearchAdapter(::onItemSelection) { view, data -> newMenu(view, data) }
|
||||
|
||||
// --- UI SETUP --
|
||||
|
||||
|
|
|
@ -18,9 +18,8 @@ import org.oxycblt.auxio.logD
|
|||
import org.oxycblt.auxio.music.MusicStore
|
||||
import org.oxycblt.auxio.playback.PlaybackViewModel
|
||||
import org.oxycblt.auxio.ui.Accent
|
||||
import org.oxycblt.auxio.ui.ActionMenu
|
||||
import org.oxycblt.auxio.ui.getSpans
|
||||
import org.oxycblt.auxio.ui.requireCompatActivity
|
||||
import org.oxycblt.auxio.ui.newMenu
|
||||
import kotlin.math.ceil
|
||||
|
||||
/**
|
||||
|
@ -48,7 +47,7 @@ class SongsFragment : Fragment() {
|
|||
|
||||
val musicStore = MusicStore.getInstance()
|
||||
val songAdapter = SongsAdapter(musicStore.songs, playbackModel::playSong) { view, data ->
|
||||
ActionMenu(requireCompatActivity(), view, data, ActionMenu.FLAG_NONE)
|
||||
newMenu(view, data)
|
||||
}
|
||||
|
||||
// --- UI SETUP ---
|
||||
|
|
|
@ -5,6 +5,7 @@ import androidx.annotation.IdRes
|
|||
import androidx.annotation.MenuRes
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.appcompat.widget.PopupMenu
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import org.oxycblt.auxio.R
|
||||
import org.oxycblt.auxio.detail.DetailViewModel
|
||||
|
@ -16,20 +17,29 @@ import org.oxycblt.auxio.music.Song
|
|||
import org.oxycblt.auxio.playback.PlaybackViewModel
|
||||
import org.oxycblt.auxio.playback.state.PlaybackMode
|
||||
|
||||
/**
|
||||
* Extension method for creating and showing a new [ActionMenu].
|
||||
* @param anchor [View] This should be centered around
|
||||
* @param data [BaseModel] this menu corresponds to
|
||||
* @param flag (Optional, defaults to [ActionMenu.FLAG_NONE]) Any extra flags to accompany the data. See [ActionMenu] for more details
|
||||
*/
|
||||
fun Fragment.newMenu(anchor: View, data: BaseModel, flag: Int = ActionMenu.FLAG_NONE) {
|
||||
ActionMenu(requireCompatActivity(), anchor, data, flag).show()
|
||||
}
|
||||
|
||||
/**
|
||||
* A wrapper around [PopupMenu] that automates the menu creation for nearly every datatype in Auxio.
|
||||
* @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 (Optional, defaults to [FLAG_NONE]) Any extra flags to accompany the data.
|
||||
* See [FLAG_NONE], [FLAG_IN_ALBUM], [FLAG_IN_ARTIST] and [FLAG_IN_GENRE] for more details.
|
||||
* @param flag Any extra flags to accompany the data. See [FLAG_NONE], [FLAG_IN_ALBUM], [FLAG_IN_ARTIST], [FLAG_IN_GENRE] for more detials.
|
||||
* @throws IllegalArgumentException When there is no menu for this specific datatype/flag
|
||||
*/
|
||||
class ActionMenu(
|
||||
activity: AppCompatActivity,
|
||||
anchor: View,
|
||||
private val data: BaseModel,
|
||||
private val flag: Int = FLAG_NONE
|
||||
private val flag: Int
|
||||
) : PopupMenu(activity, anchor) {
|
||||
private val context = activity.applicationContext
|
||||
|
||||
|
@ -54,7 +64,6 @@ class ActionMenu(
|
|||
onMenuClick(it.itemId)
|
||||
true
|
||||
}
|
||||
show()
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -82,7 +82,7 @@
|
|||
android:layout_height="@dimen/size_play_pause_compact"
|
||||
android:layout_marginEnd="@dimen/margin_mid_small"
|
||||
android:background="@drawable/ui_unbounded_ripple"
|
||||
android:contentDescription="@{playbackModel.isPlaying ? @string/description_pause : @string/description_play}"
|
||||
android:contentDescription="@string/description_play_pause"
|
||||
android:onClick="@{() -> playbackModel.invertPlayingStatus()}"
|
||||
android:tint="@color/control_color"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
|
|
|
@ -190,7 +190,7 @@
|
|||
<ImageButton
|
||||
android:id="@+id/playback_play_pause"
|
||||
style="@style/PlayPause"
|
||||
android:contentDescription="@{playbackModel.isPlaying ? @string/description_pause : @string/description_play}"
|
||||
android:contentDescription="@string/description_play_pause"
|
||||
android:onClick="@{() -> playbackModel.invertPlayingStatus()}"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="@+id/playback_song_container_duration"
|
||||
|
|
|
@ -188,7 +188,7 @@
|
|||
<ImageButton
|
||||
android:id="@+id/playback_play_pause"
|
||||
style="@style/PlayPause"
|
||||
android:contentDescription="@{playbackModel.isPlaying ? @string/description_pause : @string/description_play}"
|
||||
android:contentDescription="@string/description_play_pause"
|
||||
android:onClick="@{() -> playbackModel.invertPlayingStatus()}"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="@+id/playback_song_container_duration"
|
||||
|
|
|
@ -175,7 +175,7 @@
|
|||
android:id="@+id/playback_play_pause"
|
||||
style="@style/PlayPause"
|
||||
android:layout_marginBottom="@dimen/margin_medium"
|
||||
android:contentDescription="@{playbackModel.isPlaying ? @string/description_pause : @string/description_play}"
|
||||
android:contentDescription="@string/description_play_pause"
|
||||
android:onClick="@{() -> playbackModel.invertPlayingStatus()}"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="@+id/playback_song_duration"
|
||||
|
|
|
@ -91,7 +91,7 @@
|
|||
android:layout_height="@dimen/size_play_pause_compact"
|
||||
android:layout_marginEnd="@dimen/margin_mid_small"
|
||||
android:background="@drawable/ui_unbounded_ripple"
|
||||
android:contentDescription="@{playbackModel.isPlaying ? @string/description_pause : @string/description_play}"
|
||||
android:contentDescription="@string/description_play_pause"
|
||||
android:onClick="@{() -> playbackModel.invertPlayingStatus()}"
|
||||
android:tint="@color/control_color"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
|
|
|
@ -175,7 +175,7 @@
|
|||
android:id="@+id/playback_play_pause"
|
||||
style="@style/PlayPause"
|
||||
android:layout_marginBottom="@dimen/margin_medium"
|
||||
android:contentDescription="@{playbackModel.isPlaying ? @string/description_pause : @string/description_play}"
|
||||
android:contentDescription="@string/description_play_pause"
|
||||
android:onClick="@{() -> playbackModel.invertPlayingStatus()}"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="@+id/playback_song_duration"
|
||||
|
|
|
@ -104,8 +104,7 @@
|
|||
<string name="description_sort_alpha_up">von Z bis A sortieren</string>
|
||||
<string name="description_track_number">Titel %d</string>
|
||||
|
||||
<string name="description_play">Abspielen</string>
|
||||
<string name="description_pause">Pausieren</string>
|
||||
<string name="description_play_pause">Abspielen/Pausieren</string>
|
||||
<string name="description_skip_prev">Zu letzter Lied springen</string>
|
||||
<string name="description_skip_next">Zu nächster Lied springen</string>
|
||||
<string name="description_shuffle_on">Zufällig anschalten</string>
|
||||
|
|
|
@ -59,8 +59,7 @@
|
|||
<!-- Description Namespace | Accessibility Strings -->
|
||||
<string name="description_track_number">Κομμάτι %d</string>
|
||||
|
||||
<string name="description_play">Αναπαραγωγή</string>
|
||||
<string name="description_pause">Παύση</string>
|
||||
<string name="description_play_pause">Αναπαραγωγή/Παύση</string>
|
||||
|
||||
<string name="description_clear_user_queue">Εκκαθάριση ουράς αναπαραγωγής</string>
|
||||
|
||||
|
|
|
@ -68,8 +68,7 @@
|
|||
<!-- Description Namespace | Accessibility Strings -->
|
||||
<string name="description_track_number">Pista %d</string>
|
||||
|
||||
<string name="description_pause">Pausar</string>
|
||||
<string name="description_play">Reproducir</string>
|
||||
<string name="description_play_pause">Reproducir/Pausar</string>
|
||||
|
||||
<string name="description_clear_user_queue">Vaciar cola de reproducción</string>
|
||||
|
||||
|
|
|
@ -68,8 +68,7 @@
|
|||
<!-- Description Namespace | Accessibility Strings -->
|
||||
<string name="description_track_number">Morceau %d</string>
|
||||
|
||||
<string name="description_play">Lecture</string>
|
||||
<string name="description_pause">Pause</string>
|
||||
<string name="description_play_pause">Lecture/Pause</string>
|
||||
|
||||
<string name="description_clear_user_queue">Effacer la file d\'attente</string>
|
||||
|
||||
|
|
|
@ -57,8 +57,7 @@
|
|||
<string name="error_no_music">कोई संगीत नहीं मिला</string>
|
||||
|
||||
<!-- Description Namespace | Accessibility Strings -->
|
||||
<string name="description_play">चलाएं</string>
|
||||
<string name="description_pause">रोकें</string>
|
||||
<string name="description_play_pause">चलाएं/रोकें</string>
|
||||
|
||||
<string name="description_error">त्रुटी</string>
|
||||
|
||||
|
|
|
@ -68,8 +68,7 @@
|
|||
<!-- Description Namespace | Accessibility Strings -->
|
||||
<string name="description_track_number">Traccia %d</string>
|
||||
|
||||
<string name="description_play">Play</string>
|
||||
<string name="description_pause">Pausa</string>
|
||||
<string name="description_play_pause">Play/Pausa</string>
|
||||
|
||||
<string name="description_clear_user_queue">Svuota coda</string>
|
||||
|
||||
|
|
|
@ -68,8 +68,7 @@
|
|||
<!-- Description Namespace | Accessibility Strings -->
|
||||
<string name="description_track_number">Nummer %d</string>
|
||||
|
||||
<string name="description_play">Afspelen</string>
|
||||
<string name="description_pause">Pauzeren</string>
|
||||
<string name="description_play_pause">Afspelen/Pauzeren</string>
|
||||
|
||||
<string name="description_clear_user_queue">Leeg wachtrij</string>
|
||||
|
||||
|
|
|
@ -67,8 +67,7 @@
|
|||
<!-- Description Namespace | Accessibility Strings -->
|
||||
<string name="description_track_number">Música %d</string>
|
||||
|
||||
<string name="description_play">Reproduzir</string>
|
||||
<string name="description_pause">Pausar</string>
|
||||
<string name="description_play_pause">Reproduzir/Pausar</string>
|
||||
|
||||
<string name="description_clear_user_queue">Limpar fila</string>
|
||||
|
||||
|
|
|
@ -67,8 +67,7 @@
|
|||
<!-- Description Namespace | Accessibility Strings -->
|
||||
<string name="description_track_number">Música %d</string>
|
||||
|
||||
<string name="description_play">Reproduzir</string>
|
||||
<string name="description_pause">Pausar</string>
|
||||
<string name="description_play_pause">Reproduzir/Pausar</string>
|
||||
|
||||
<string name="description_clear_user_queue">Limpar fila</string>
|
||||
|
||||
|
|
|
@ -72,8 +72,7 @@
|
|||
<!-- Description Namespace | Accessibility Strings -->
|
||||
<string name="description_track_number">Melodie %d</string>
|
||||
|
||||
<string name="description_play">Redă</string>
|
||||
<string name="description_pause">Pauză</string>
|
||||
<string name="description_play_pause">Redă/Pauză</string>
|
||||
|
||||
<string name="description_clear_user_queue">Golește lista de redare</string>
|
||||
|
||||
|
|
|
@ -66,8 +66,7 @@
|
|||
<!-- Description Namespace | Accessibility Strings -->
|
||||
<string name="description_track_number">Трек %d</string>
|
||||
|
||||
<string name="description_play">Воспроизвести</string>
|
||||
<string name="description_pause">Пауза</string>
|
||||
<string name="description_play_pause">Воспроизвести/Пауза</string>
|
||||
|
||||
<string name="description_clear_user_queue">Очистить очередь</string>
|
||||
|
||||
|
|
|
@ -1,28 +1,28 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<array name="entires_theme">
|
||||
<string-array name="entires_theme">
|
||||
<item>@string/setting_theme_auto</item>
|
||||
<item>@string/setting_theme_day</item>
|
||||
<item>@string/setting_theme_night</item>
|
||||
</array>
|
||||
</string-array>
|
||||
|
||||
<array name="values_theme">
|
||||
<string-array name="values_theme" translatable="false">
|
||||
<item>AUTO</item>
|
||||
<item>LIGHT</item>
|
||||
<item>DARK</item>
|
||||
</array>
|
||||
</string-array>
|
||||
|
||||
<array name="entries_lib_display">
|
||||
<string-array name="entries_lib_display">
|
||||
<item>@string/label_genres</item>
|
||||
<item>@string/label_artists</item>
|
||||
<item>@string/label_albums</item>
|
||||
</array>
|
||||
</string-array>
|
||||
|
||||
<array name="values_lib_display">
|
||||
<string-array name="values_lib_display" translatable="false">
|
||||
<item>SHOW_GENRES</item>
|
||||
<item>SHOW_ARTISTS</item>
|
||||
<item>SHOW_ALBUMS</item>
|
||||
</array>
|
||||
</string-array>
|
||||
|
||||
<array name="entries_song_playback_mode">
|
||||
<item>@string/label_play_all_songs</item>
|
||||
|
@ -31,22 +31,22 @@
|
|||
<item>@string/label_play_genre</item>
|
||||
</array>
|
||||
|
||||
<array name="values_song_playback_mode">
|
||||
<string-array name="values_song_playback_mode" translatable="false">
|
||||
<item>ALL_SONGS</item>
|
||||
<item>IN_ARTIST</item>
|
||||
<item>IN_ALBUM</item>
|
||||
<item>IN_GENRE</item>
|
||||
</array>
|
||||
</string-array>
|
||||
|
||||
<array name="entries_at_end">
|
||||
<string-array name="entries_at_end">
|
||||
<item>@string/setting_behavior_end_loop_pause</item>
|
||||
<item>@string/setting_behavior_end_loop</item>
|
||||
<item>@string/setting_behavior_end_stop</item>
|
||||
</array>
|
||||
</string-array>
|
||||
|
||||
<array name="values_at_end">
|
||||
<string-array name="values_at_end" translatable="false">
|
||||
<item>LOOP_PAUSE</item>
|
||||
<item>LOOP</item>
|
||||
<item>STOP</item>
|
||||
</array>
|
||||
</string-array>
|
||||
</resources>
|
|
@ -104,8 +104,7 @@
|
|||
<string name="description_sort_alpha_up">Sort from Z to A</string>
|
||||
<string name="description_track_number">Track %d</string>
|
||||
|
||||
<string name="description_play">Play</string>
|
||||
<string name="description_pause">Pause</string>
|
||||
<string name="description_play_pause">Play/Pause</string>
|
||||
<string name="description_skip_next">Skip to next song</string>
|
||||
<string name="description_skip_prev">Skip to last song</string>
|
||||
<string name="description_shuffle_on">Turn shuffle on</string>
|
||||
|
|
|
@ -4,6 +4,8 @@ This document is designed to provide a simple overview of Auxio's architecture a
|
|||
|
||||
#### Package structure overview
|
||||
|
||||
Auxio's package structure is mostly based around the features, and then any sub-features or components involved with that. There are some shared packages however. A diagram of the package structure is shown below:
|
||||
|
||||
```
|
||||
org.oxycblt.auxio # Main UI's and logging utilities
|
||||
├──.coil # Fetchers and utilities for Coil, contains binding adapters than be used in the user interface.
|
||||
|
@ -41,7 +43,7 @@ Ideally, UIs should only be talking to ViewModels, ViewModels should only be tal
|
|||
|
||||
Auxio only has one activity, that being `MainActivity`. When adding a new UI, it should be added as a `Fragment` or a `RecyclerView` item depending on the situation.
|
||||
|
||||
Databinding should *always* be used instead of `findViewById`. `by memberBinding` is used if the binding needs to be a member variable in order to avoid memory leaks.
|
||||
Databinding should *always* be used instead of `findViewById`. Use `by memberBinding` if the binding needs to be a member variable in order to avoid memory leaks.
|
||||
|
||||
Usually, fragment creation is done in `onCreateView`, and organized into three parts:
|
||||
|
||||
|
@ -49,7 +51,7 @@ Usually, fragment creation is done in `onCreateView`, and organized into three p
|
|||
- Set up the UI
|
||||
- Set up LiveData observers
|
||||
|
||||
When creating a ViewHolder for a `RecyclerView`, one should use `BaseHolder` to standardize the binding process and automate some code shared across all ViewHolders.
|
||||
When creating a ViewHolder for a `RecyclerView`, one should use `BaseViewHolder` to standardize the binding process and automate some code shared across all ViewHolders.
|
||||
|
||||
#### Binding Adapters
|
||||
|
||||
|
@ -69,9 +71,7 @@ Auxio's playback system is somewhat unorthodox, as it avoids a lot of the built-
|
|||
PlaybackStateManager───────────────────┘
|
||||
```
|
||||
|
||||
`PlaybackStateManager` is the shared object that contains the master copy of the playback state, doing all operations on it. If you want to add something to the playback system, this is likely where you should add 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` can be used instead, as it exposes stable data and abstracted functions that UI's can use to interact with the playback state.
|
||||
`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` can be used instead, as it exposes stable data and abstracted 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 external 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.
|
||||
|
||||
|
@ -86,6 +86,10 @@ All music objects inherit `BaseModel`, which guarantees that all music has both
|
|||
|
||||
`BaseModel` can be used as an argument type to specify that any music type, while `Parent` can be used as an argument type to only specify music objects that have child items, such as albums or artists.
|
||||
|
||||
### Using menus
|
||||
|
||||
Instead of directly instantiating a menu for an item yourself, you should instead use `ActionMenu` as it will automate the menu creation and click listeners immediately.
|
||||
|
||||
#### Using Settings
|
||||
|
||||
Access to settings should preferably be done with `SettingsManager` as it can be accessed everywhere without a context.
|
||||
|
|
Loading…
Reference in a new issue