Prevent search box from scrolling the toolbar
Prevent the search TextView from being able to scroll the toolbar when there are no results.
This commit is contained in:
parent
118172b7c8
commit
6fa698d7eb
4 changed files with 36 additions and 29 deletions
|
@ -6,8 +6,14 @@ import android.util.Log
|
||||||
// Yes, I know timber exists but this does what I need.
|
// Yes, I know timber exists but this does what I need.
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shortcut method for logging a debug statement, handles debug builds and anonymous objects
|
* Shortcut method for logging a non-string [obj] to debug. Should only be used for debug preferably.
|
||||||
* @param msg The message to log
|
*/
|
||||||
|
fun Any.logD(obj: Any) {
|
||||||
|
logD(obj.toString())
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shortcut method for logging [msg] to the debug console., handles debug builds and anonymous objects
|
||||||
*/
|
*/
|
||||||
fun Any.logD(msg: String) {
|
fun Any.logD(msg: String) {
|
||||||
if (BuildConfig.DEBUG) {
|
if (BuildConfig.DEBUG) {
|
||||||
|
@ -16,8 +22,7 @@ fun Any.logD(msg: String) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shortcut method for logging an error. Handles anonymous objects
|
* Shortcut method for logging [msg] as an error to the console. Handles anonymous objects
|
||||||
* @param msg The message to log
|
|
||||||
*/
|
*/
|
||||||
fun Any.logE(msg: String) {
|
fun Any.logE(msg: String) {
|
||||||
Log.e(getName(), msg)
|
Log.e(getName(), msg)
|
||||||
|
|
|
@ -184,24 +184,21 @@ class PlaybackService : Service(), Player.EventListener, PlaybackStateManager.Ca
|
||||||
// --- PLAYER EVENT LISTENER OVERRIDES ---
|
// --- PLAYER EVENT LISTENER OVERRIDES ---
|
||||||
|
|
||||||
override fun onPlaybackStateChanged(state: Int) {
|
override fun onPlaybackStateChanged(state: Int) {
|
||||||
if (state == Player.STATE_ENDED) {
|
when (state) {
|
||||||
playbackManager.next()
|
Player.STATE_READY -> startPollingPosition()
|
||||||
} else if (state == Player.STATE_READY) {
|
Player.STATE_ENDED -> playbackManager.next()
|
||||||
startPollingPosition()
|
else -> {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onMediaItemTransition(mediaItem: MediaItem?, reason: Int) {
|
override fun onMediaItemTransition(mediaItem: MediaItem?, reason: Int) {
|
||||||
// If the song loops while in the LOOP_ONCE mode, then stop looping after that.
|
if (reason == Player.MEDIA_ITEM_TRANSITION_REASON_REPEAT) {
|
||||||
if (reason == Player.MEDIA_ITEM_TRANSITION_REASON_REPEAT &&
|
playbackManager.clearLoopMode()
|
||||||
playbackManager.loopMode == LoopMode.ONCE
|
|
||||||
) {
|
|
||||||
playbackManager.setLoopMode(LoopMode.NONE)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onPlayerError(error: ExoPlaybackException) {
|
override fun onPlayerError(error: ExoPlaybackException) {
|
||||||
// If there's any issue, just go to the next song.
|
// If there's any issue, just go to the next song. I don't really care.
|
||||||
playbackManager.next()
|
playbackManager.next()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -184,7 +184,7 @@ class PlaybackStateManager private constructor() {
|
||||||
|
|
||||||
mMode = mode
|
mMode = mode
|
||||||
|
|
||||||
resetLoopMode()
|
clearLoopMode()
|
||||||
updatePlayback(song)
|
updatePlayback(song)
|
||||||
setShuffling(settingsManager.keepShuffle && mIsShuffling, keepSong = true)
|
setShuffling(settingsManager.keepShuffle && mIsShuffling, keepSong = true)
|
||||||
}
|
}
|
||||||
|
@ -215,7 +215,7 @@ class PlaybackStateManager private constructor() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
resetLoopMode()
|
clearLoopMode()
|
||||||
setShuffling(shuffled, keepSong = false)
|
setShuffling(shuffled, keepSong = false)
|
||||||
updatePlayback(mQueue[0])
|
updatePlayback(mQueue[0])
|
||||||
}
|
}
|
||||||
|
@ -241,7 +241,7 @@ class PlaybackStateManager private constructor() {
|
||||||
* Go to the next song, along with doing all the checks that entails.
|
* Go to the next song, along with doing all the checks that entails.
|
||||||
*/
|
*/
|
||||||
fun next() {
|
fun next() {
|
||||||
resetLoopMode()
|
clearLoopMode()
|
||||||
|
|
||||||
// If there's anything in the user queue, go to the first song in there instead
|
// If there's anything in the user queue, go to the first song in there instead
|
||||||
// of incrementing the index.
|
// of incrementing the index.
|
||||||
|
@ -283,7 +283,7 @@ class PlaybackStateManager private constructor() {
|
||||||
mIndex = mIndex.dec()
|
mIndex = mIndex.dec()
|
||||||
}
|
}
|
||||||
|
|
||||||
resetLoopMode()
|
clearLoopMode()
|
||||||
|
|
||||||
updatePlayback(mQueue[mIndex])
|
updatePlayback(mQueue[mIndex])
|
||||||
|
|
||||||
|
@ -583,7 +583,7 @@ class PlaybackStateManager private constructor() {
|
||||||
* Reset the current [LoopMode], if needed.
|
* Reset the current [LoopMode], if needed.
|
||||||
* Use this instead of duplicating the code manually.
|
* Use this instead of duplicating the code manually.
|
||||||
*/
|
*/
|
||||||
private fun resetLoopMode() {
|
fun clearLoopMode() {
|
||||||
// Reset the loop mode from ONCE if needed.
|
// Reset the loop mode from ONCE if needed.
|
||||||
if (mLoopMode == LoopMode.ONCE) {
|
if (mLoopMode == LoopMode.ONCE) {
|
||||||
mLoopMode = LoopMode.NONE
|
mLoopMode = LoopMode.NONE
|
||||||
|
@ -691,7 +691,6 @@ class PlaybackStateManager private constructor() {
|
||||||
private fun unpackFromPlaybackState(playbackState: PlaybackState) {
|
private fun unpackFromPlaybackState(playbackState: PlaybackState) {
|
||||||
// Turn the simplified information from PlaybackState into values that can be used
|
// Turn the simplified information from PlaybackState into values that can be used
|
||||||
mSong = musicStore.songs.find { it.name == playbackState.songName }
|
mSong = musicStore.songs.find { it.name == playbackState.songName }
|
||||||
mPosition = playbackState.position
|
|
||||||
mParent = musicStore.parents.find { it.name == playbackState.parentName }
|
mParent = musicStore.parents.find { it.name == playbackState.parentName }
|
||||||
mMode = PlaybackMode.fromInt(playbackState.mode) ?: PlaybackMode.ALL_SONGS
|
mMode = PlaybackMode.fromInt(playbackState.mode) ?: PlaybackMode.ALL_SONGS
|
||||||
mLoopMode = LoopMode.fromInt(playbackState.loopMode) ?: LoopMode.NONE
|
mLoopMode = LoopMode.fromInt(playbackState.loopMode) ?: LoopMode.NONE
|
||||||
|
@ -699,9 +698,7 @@ class PlaybackStateManager private constructor() {
|
||||||
mIsInUserQueue = playbackState.inUserQueue
|
mIsInUserQueue = playbackState.inUserQueue
|
||||||
mIndex = playbackState.index
|
mIndex = playbackState.index
|
||||||
|
|
||||||
callbacks.forEach {
|
seekTo(playbackState.position)
|
||||||
it.onSeek(mPosition)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -11,6 +11,7 @@ import androidx.fragment.app.activityViewModels
|
||||||
import androidx.fragment.app.viewModels
|
import androidx.fragment.app.viewModels
|
||||||
import androidx.navigation.fragment.findNavController
|
import androidx.navigation.fragment.findNavController
|
||||||
import androidx.recyclerview.widget.GridLayoutManager
|
import androidx.recyclerview.widget.GridLayoutManager
|
||||||
|
import com.google.android.material.appbar.AppBarLayout
|
||||||
import org.oxycblt.auxio.R
|
import org.oxycblt.auxio.R
|
||||||
import org.oxycblt.auxio.databinding.FragmentSearchBinding
|
import org.oxycblt.auxio.databinding.FragmentSearchBinding
|
||||||
import org.oxycblt.auxio.detail.DetailViewModel
|
import org.oxycblt.auxio.detail.DetailViewModel
|
||||||
|
@ -51,6 +52,8 @@ class SearchFragment : Fragment() {
|
||||||
// styling to Material given all the second-and-third-order effects it has.
|
// styling to Material given all the second-and-third-order effects it has.
|
||||||
val accent = Accent.get().color.toColor(requireContext())
|
val accent = Accent.get().color.toColor(requireContext())
|
||||||
val searchAdapter = SearchAdapter(::onItemSelection) { view, data -> newMenu(view, data) }
|
val searchAdapter = SearchAdapter(::onItemSelection) { view, data -> newMenu(view, data) }
|
||||||
|
val toolbarParams = binding.searchToolbar.layoutParams as AppBarLayout.LayoutParams
|
||||||
|
val defaultParams = toolbarParams.scrollFlags
|
||||||
|
|
||||||
// --- UI SETUP --
|
// --- UI SETUP --
|
||||||
|
|
||||||
|
@ -99,10 +102,14 @@ class SearchFragment : Fragment() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (it.isEmpty()) {
|
if (it.isEmpty()) {
|
||||||
|
// If the data is empty, then the ability for the toolbar to collapse
|
||||||
|
// on scroll should be disabled.
|
||||||
binding.searchAppbar.setExpanded(true)
|
binding.searchAppbar.setExpanded(true)
|
||||||
binding.searchRecycler.visibility = View.GONE
|
binding.searchRecycler.visibility = View.GONE
|
||||||
|
toolbarParams.scrollFlags = AppBarLayout.LayoutParams.SCROLL_FLAG_NO_SCROLL
|
||||||
} else {
|
} else {
|
||||||
binding.searchRecycler.visibility = View.VISIBLE
|
binding.searchRecycler.visibility = View.VISIBLE
|
||||||
|
toolbarParams.scrollFlags = defaultParams
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,18 +132,18 @@ class SearchFragment : Fragment() {
|
||||||
return binding.root
|
return binding.root
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroyView() {
|
|
||||||
super.onDestroyView()
|
|
||||||
|
|
||||||
fixAnimInfoLeak()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
|
|
||||||
searchModel.updateNavigationStatus(false)
|
searchModel.updateNavigationStatus(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onDestroyView() {
|
||||||
|
super.onDestroyView()
|
||||||
|
|
||||||
|
fixAnimInfoLeak()
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Navigate to an item, or play it, depending on what the given item is.
|
* Navigate to an item, or play it, depending on what the given item is.
|
||||||
* @param baseModel The data the action should be done with
|
* @param baseModel The data the action should be done with
|
||||||
|
@ -148,6 +155,7 @@ class SearchFragment : Fragment() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get rid of the keyboard
|
||||||
requireView().rootView.clearFocus()
|
requireView().rootView.clearFocus()
|
||||||
|
|
||||||
if (!searchModel.isNavigating) {
|
if (!searchModel.isNavigating) {
|
||||||
|
|
Loading…
Reference in a new issue