Added swipe songs

This commit is contained in:
h4h13 2019-12-08 22:08:51 +05:30
parent 7289b271dc
commit d2076fc1d4
5 changed files with 196 additions and 94 deletions

View file

@ -25,11 +25,12 @@ import androidx.annotation.Nullable;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.card.MaterialCardView; import com.google.android.material.card.MaterialCardView;
import com.h6ah4i.android.widget.advrecyclerview.utils.AbstractDraggableSwipeableItemViewHolder;
import code.name.monkey.appthemehelper.util.ATHUtil; import code.name.monkey.appthemehelper.util.ATHUtil;
import code.name.monkey.retromusic.R; import code.name.monkey.retromusic.R;
public class MediaEntryViewHolder extends RecyclerView.ViewHolder implements View.OnLongClickListener, View.OnClickListener { public class MediaEntryViewHolder extends AbstractDraggableSwipeableItemViewHolder implements View.OnLongClickListener, View.OnClickListener {
@Nullable @Nullable
public TextView title; public TextView title;
@ -71,6 +72,8 @@ public class MediaEntryViewHolder extends RecyclerView.ViewHolder implements Vie
@Nullable @Nullable
public ImageView image; public ImageView image;
@Nullable
public View dummyContainer;
public MediaEntryViewHolder(@NonNull View itemView) { public MediaEntryViewHolder(@NonNull View itemView) {
super(itemView); super(itemView);
@ -91,6 +94,7 @@ public class MediaEntryViewHolder extends RecyclerView.ViewHolder implements Vie
recyclerView = itemView.findViewById(R.id.recycler_view); recyclerView = itemView.findViewById(R.id.recycler_view);
mask = itemView.findViewById(R.id.mask); mask = itemView.findViewById(R.id.mask);
playSongs = itemView.findViewById(R.id.playSongs); playSongs = itemView.findViewById(R.id.playSongs);
dummyContainer = itemView.findViewById(R.id.dummy_view);
if (imageContainerCard != null) { if (imageContainerCard != null) {
imageContainerCard.setCardBackgroundColor(ATHUtil.INSTANCE.resolveColor(itemView.getContext(), R.attr.colorSurface)); imageContainerCard.setCardBackgroundColor(ATHUtil.INSTANCE.resolveColor(itemView.getContext(), R.attr.colorSurface));
@ -99,6 +103,11 @@ public class MediaEntryViewHolder extends RecyclerView.ViewHolder implements Vie
itemView.setOnLongClickListener(this); itemView.setOnLongClickListener(this);
} }
@Override
public View getSwipeableContainerView() {
return null;
}
@Override @Override
public boolean onLongClick(View v) { public boolean onLongClick(View v) {
return false; return false;

View file

@ -8,15 +8,24 @@ import android.widget.ImageView
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.helper.MusicPlayerRemote import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.helper.MusicPlayerRemote.isPlaying
import code.name.monkey.retromusic.helper.MusicPlayerRemote.playNextSong
import code.name.monkey.retromusic.helper.MusicPlayerRemote.removeFromQueue
import code.name.monkey.retromusic.model.Song import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.util.MusicUtil import code.name.monkey.retromusic.util.MusicUtil
import code.name.monkey.retromusic.util.ViewUtil import code.name.monkey.retromusic.util.ViewUtil
import com.h6ah4i.android.widget.advrecyclerview.draggable.DraggableItemAdapter import com.h6ah4i.android.widget.advrecyclerview.draggable.DraggableItemAdapter
import com.h6ah4i.android.widget.advrecyclerview.draggable.DraggableItemViewHolder
import com.h6ah4i.android.widget.advrecyclerview.draggable.ItemDraggableRange import com.h6ah4i.android.widget.advrecyclerview.draggable.ItemDraggableRange
import com.h6ah4i.android.widget.advrecyclerview.draggable.annotation.DraggableItemStateFlags import com.h6ah4i.android.widget.advrecyclerview.draggable.annotation.DraggableItemStateFlags
import com.h6ah4i.android.widget.advrecyclerview.swipeable.SwipeableItemAdapter
import com.h6ah4i.android.widget.advrecyclerview.swipeable.SwipeableItemConstants
import com.h6ah4i.android.widget.advrecyclerview.swipeable.action.SwipeResultAction
import com.h6ah4i.android.widget.advrecyclerview.swipeable.action.SwipeResultActionDefault
import com.h6ah4i.android.widget.advrecyclerview.swipeable.action.SwipeResultActionRemoveItem
import com.h6ah4i.android.widget.advrecyclerview.swipeable.annotation.SwipeableItemResults
import java.util.* import java.util.*
class PlayingQueueAdapter( class PlayingQueueAdapter(
activity: AppCompatActivity, activity: AppCompatActivity,
dataSet: ArrayList<Song>, dataSet: ArrayList<Song>,
@ -24,9 +33,10 @@ class PlayingQueueAdapter(
itemLayoutRes: Int itemLayoutRes: Int
) : SongAdapter( ) : SongAdapter(
activity, dataSet, itemLayoutRes, false, null activity, dataSet, itemLayoutRes, false, null
), DraggableItemAdapter<PlayingQueueAdapter.ViewHolder> { ), DraggableItemAdapter<PlayingQueueAdapter.ViewHolder>, SwipeableItemAdapter<PlayingQueueAdapter.ViewHolder> {
private var color = -1 private var color = -1
private var songToRemove: Song? = null
override fun createViewHolder(view: View): SongAdapter.ViewHolder { override fun createViewHolder(view: View): SongAdapter.ViewHolder {
return ViewHolder(view) return ViewHolder(view)
@ -125,7 +135,11 @@ class PlayingQueueAdapter(
notifyDataSetChanged() notifyDataSetChanged()
} }
inner class ViewHolder(itemView: View) : SongAdapter.ViewHolder(itemView), DraggableItemViewHolder { fun setSongToRemove(song: Song) {
songToRemove = song
}
inner class ViewHolder(itemView: View) : SongAdapter.ViewHolder(itemView) {
@DraggableItemStateFlags @DraggableItemStateFlags
private var mDragStateFlags: Int = 0 private var mDragStateFlags: Int = 0
@ -159,6 +173,10 @@ class PlayingQueueAdapter(
override fun setDragStateFlags(@DraggableItemStateFlags flags: Int) { override fun setDragStateFlags(@DraggableItemStateFlags flags: Int) {
mDragStateFlags = flags mDragStateFlags = flags
} }
override fun getSwipeableContainerView(): View? {
return dummyContainer
}
} }
companion object { companion object {
@ -167,4 +185,51 @@ class PlayingQueueAdapter(
private const val CURRENT = 1 private const val CURRENT = 1
private const val UP_NEXT = 2 private const val UP_NEXT = 2
} }
override fun onSwipeItem(holder: ViewHolder?, position: Int, @SwipeableItemResults result: Int): SwipeResultAction {
return if (result === SwipeableItemConstants.RESULT_CANCELED) {
SwipeResultActionDefault()
} else {
SwipedResultActionRemoveItem(this, position, activity)
}
}
override fun onGetSwipeReactionType(holder: ViewHolder?, position: Int, x: Int, y: Int): Int {
return if (onCheckCanStartDrag(holder!!, position, x, y)) {
SwipeableItemConstants.REACTION_CAN_NOT_SWIPE_BOTH_H;
} else {
SwipeableItemConstants.REACTION_CAN_SWIPE_BOTH_H;
}
}
override fun onSwipeItemStarted(p0: ViewHolder?, p1: Int) {
}
override fun onSetSwipeBackground(holder: ViewHolder?, position: Int, result: Int) {
}
internal class SwipedResultActionRemoveItem(private val adapter: PlayingQueueAdapter,
private val position: Int,
private val activity: AppCompatActivity) : SwipeResultActionRemoveItem() {
private var songToRemove: Song? = null
private val isPlaying: Boolean = MusicPlayerRemote.isPlaying
private val songProgressMillis = 0
override fun onPerformAction() {
//currentlyShownSnackbar = null
}
override fun onSlideAnimationEnd() {
//initializeSnackBar(adapter, position, activity, isPlaying)
songToRemove = adapter.dataSet[position]
//If song removed was the playing song, then play the next song
if (isPlaying(songToRemove!!)) {
playNextSong()
}
//Swipe animation is much smoother when we do the heavy lifting after it's completed
adapter.setSongToRemove(songToRemove!!)
removeFromQueue(songToRemove!!)
}
}
} }

View file

@ -23,8 +23,10 @@ import code.name.monkey.retromusic.adapter.song.PlayingQueueAdapter
import code.name.monkey.retromusic.fragments.base.AbsLibraryPagerRecyclerViewFragment import code.name.monkey.retromusic.fragments.base.AbsLibraryPagerRecyclerViewFragment
import code.name.monkey.retromusic.helper.MusicPlayerRemote import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.util.ViewUtil import code.name.monkey.retromusic.util.ViewUtil
import com.h6ah4i.android.widget.advrecyclerview.animator.RefactoredDefaultItemAnimator import com.h6ah4i.android.widget.advrecyclerview.animator.DraggableItemAnimator
import com.h6ah4i.android.widget.advrecyclerview.draggable.RecyclerViewDragDropManager import com.h6ah4i.android.widget.advrecyclerview.draggable.RecyclerViewDragDropManager
import com.h6ah4i.android.widget.advrecyclerview.swipeable.RecyclerViewSwipeManager
import com.h6ah4i.android.widget.advrecyclerview.touchguard.RecyclerViewTouchActionGuardManager
import com.h6ah4i.android.widget.advrecyclerview.utils.WrapperAdapterUtils import com.h6ah4i.android.widget.advrecyclerview.utils.WrapperAdapterUtils
import kotlinx.android.synthetic.main.activity_playing_queue.* import kotlinx.android.synthetic.main.activity_playing_queue.*
@ -33,28 +35,32 @@ import kotlinx.android.synthetic.main.activity_playing_queue.*
*/ */
class PlayingQueueFragment : AbsLibraryPagerRecyclerViewFragment<PlayingQueueAdapter, LinearLayoutManager>() { class PlayingQueueFragment : AbsLibraryPagerRecyclerViewFragment<PlayingQueueAdapter, LinearLayoutManager>() {
private var wrappedAdapter: RecyclerView.Adapter<*>? = null private lateinit var wrappedAdapter: RecyclerView.Adapter<*>
private var recyclerViewDragDropManager: RecyclerViewDragDropManager? = null private var recyclerViewDragDropManager: RecyclerViewDragDropManager? = null
private var recyclerViewSwipeManager: RecyclerViewSwipeManager? = null
private var recyclerViewTouchActionGuardManager: RecyclerViewTouchActionGuardManager? = null
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
setupRecyclerView() setupRecyclerView()
} }
private fun setupRecyclerView() { private fun setupRecyclerView() {
recyclerViewTouchActionGuardManager = RecyclerViewTouchActionGuardManager()
recyclerViewDragDropManager = RecyclerViewDragDropManager() recyclerViewDragDropManager = RecyclerViewDragDropManager()
val animator = RefactoredDefaultItemAnimator() recyclerViewSwipeManager = RecyclerViewSwipeManager()
wrappedAdapter = recyclerViewDragDropManager?.createWrappedAdapter(createAdapter()) val animator = DraggableItemAnimator()
animator.supportsChangeAnimations = false;
wrappedAdapter = recyclerViewDragDropManager?.createWrappedAdapter(adapter!!) as RecyclerView.Adapter<*>
wrappedAdapter = recyclerViewSwipeManager?.createWrappedAdapter(wrappedAdapter) as RecyclerView.Adapter<*>
recyclerView().layoutManager = layoutManager
recyclerView().adapter = wrappedAdapter
recyclerView().itemAnimator = animator
recyclerViewTouchActionGuardManager?.attachRecyclerView(recyclerView)
recyclerViewDragDropManager?.attachRecyclerView(recyclerView)
recyclerViewSwipeManager?.attachRecyclerView(recyclerView)
layoutManager?.scrollToPositionWithOffset(MusicPlayerRemote.position + 1, 0)
recyclerView.apply {
layoutManager = createLayoutManager()
adapter = wrappedAdapter
itemAnimator = animator
recyclerViewDragDropManager?.attachRecyclerView(this)
}
createLayoutManager().scrollToPositionWithOffset(MusicPlayerRemote.position + 1, 0)
ViewUtil.setUpFastScrollRecyclerViewColor(requireContext(), recyclerView) ViewUtil.setUpFastScrollRecyclerViewColor(requireContext(), recyclerView)
} }
@ -66,6 +72,11 @@ class PlayingQueueFragment : AbsLibraryPagerRecyclerViewFragment<PlayingQueueAda
return PlayingQueueAdapter(requireActivity() as AppCompatActivity, MusicPlayerRemote.playingQueue, MusicPlayerRemote.position, R.layout.item_queue) return PlayingQueueAdapter(requireActivity() as AppCompatActivity, MusicPlayerRemote.playingQueue, MusicPlayerRemote.position, R.layout.item_queue)
} }
override fun onServiceConnected() {
super.onServiceConnected()
updateQueue()
}
override fun onQueueChanged() { override fun onQueueChanged() {
super.onQueueChanged() super.onQueueChanged()
updateQueue() updateQueue()
@ -87,7 +98,7 @@ class PlayingQueueFragment : AbsLibraryPagerRecyclerViewFragment<PlayingQueueAda
private fun resetToCurrentPosition() { private fun resetToCurrentPosition() {
recyclerView.stopScroll() recyclerView.stopScroll()
createLayoutManager().scrollToPositionWithOffset(MusicPlayerRemote.position + 1, 0) layoutManager?.scrollToPositionWithOffset(MusicPlayerRemote.position + 1, 0)
} }
override fun onPause() { override fun onPause() {
@ -101,14 +112,16 @@ class PlayingQueueFragment : AbsLibraryPagerRecyclerViewFragment<PlayingQueueAda
override fun onDestroyView() { override fun onDestroyView() {
super.onDestroyView() super.onDestroyView()
if (recyclerViewDragDropManager != null) { if (recyclerViewDragDropManager != null) {
recyclerViewDragDropManager!!.release() recyclerViewDragDropManager?.release()
recyclerViewDragDropManager = null recyclerViewDragDropManager = null
} }
if (wrappedAdapter != null) { if (recyclerViewSwipeManager != null) {
WrapperAdapterUtils.releaseAll(wrappedAdapter) recyclerViewSwipeManager?.release()
wrappedAdapter = null recyclerViewSwipeManager = null
} }
WrapperAdapterUtils.releaseAll(wrappedAdapter)
} }
companion object { companion object {

View file

@ -153,7 +153,11 @@ object MusicPlayerRemote {
} }
return null return null
} }
fun getQueueDurationSongs(): Int {
return if (musicService != null) {
musicService!!.playingQueue.size
} else -1
}
/** /**
* Async * Async
*/ */

View file

@ -1,12 +1,21 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<FrameLayout
android:id="@+id/dummy_view"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="?rectSelector"
android:clickable="true" android:clickable="true"
android:focusable="true" android:focusable="true"
android:foreground="?rectSelector"
android:gravity="center_vertical" android:gravity="center_vertical"
android:minHeight="64dp" android:minHeight="64dp"
android:orientation="horizontal" android:orientation="horizontal"
@ -81,3 +90,5 @@
app:tint="?attr/colorControlNormal" /> app:tint="?attr/colorControlNormal" />
</LinearLayout> </LinearLayout>
</FrameLayout>
</FrameLayout>