From a5c6ff1d1d005674a454aadcc82a74d8096c37db Mon Sep 17 00:00:00 2001 From: Karim Abou Zeid Date: Fri, 25 Dec 2015 01:54:41 +0100 Subject: [PATCH] Added better drag and drop support for the playing queue. --- app/build.gradle | 4 ++ .../adapter/song/PlayingQueueAdapter.java | 37 +++++++++++- .../ui/fragments/player/PlayerFragment.java | 60 ++++++++++++------- .../kabouzeid/gramophone/util/ViewUtil.java | 12 ++++ 4 files changed, 90 insertions(+), 23 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 65ca228e..66600b35 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -94,6 +94,10 @@ dependencies { transitive = true; } + compile('com.h6ah4i.android.widget.advrecyclerview:advrecyclerview:0.8.5@aar') { + transitive = true + } + compile('com.afollestad.material-dialogs:core:0.8.5.1@aar') { transitive = true } diff --git a/app/src/main/java/com/kabouzeid/gramophone/adapter/song/PlayingQueueAdapter.java b/app/src/main/java/com/kabouzeid/gramophone/adapter/song/PlayingQueueAdapter.java index 03c85527..5ac3d00a 100644 --- a/app/src/main/java/com/kabouzeid/gramophone/adapter/song/PlayingQueueAdapter.java +++ b/app/src/main/java/com/kabouzeid/gramophone/adapter/song/PlayingQueueAdapter.java @@ -7,17 +7,22 @@ import android.support.v7.app.AppCompatActivity; import android.view.MenuItem; import android.view.View; +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.annotation.DraggableItemStateFlags; import com.kabouzeid.gramophone.R; import com.kabouzeid.gramophone.helper.MusicPlayerRemote; import com.kabouzeid.gramophone.interfaces.CabHolder; import com.kabouzeid.gramophone.model.Song; +import com.kabouzeid.gramophone.util.ViewUtil; import java.util.ArrayList; /** * @author Karim Abou Zeid (kabouzeid) */ -public class PlayingQueueAdapter extends SongAdapter { +public class PlayingQueueAdapter extends SongAdapter implements DraggableItemAdapter { private static final int HISTORY = 0; private static final int CURRENT = 1; @@ -83,7 +88,24 @@ public class PlayingQueueAdapter extends SongAdapter { } } - public class ViewHolder extends SongAdapter.ViewHolder { + @Override + public boolean onCheckCanStartDrag(ViewHolder holder, int position, int x, int y) { + return ViewUtil.hitTest(holder.image, x, y); + } + + @Override + public ItemDraggableRange onGetItemDraggableRange(ViewHolder holder, int position) { + return null; + } + + @Override + public void onMoveItem(int fromPosition, int toPosition) { + MusicPlayerRemote.moveSong(fromPosition, toPosition); + } + + public class ViewHolder extends SongAdapter.ViewHolder implements DraggableItemViewHolder { + @DraggableItemStateFlags + private int mDragStateFlags; public ViewHolder(@NonNull View itemView) { super(itemView); @@ -103,5 +125,16 @@ public class PlayingQueueAdapter extends SongAdapter { } return super.onSongMenuItemClick(item); } + + @Override + public void setDragStateFlags(@DraggableItemStateFlags int flags) { + mDragStateFlags = flags; + } + + @Override + @DraggableItemStateFlags + public int getDragStateFlags() { + return mDragStateFlags; + } } } diff --git a/app/src/main/java/com/kabouzeid/gramophone/ui/fragments/player/PlayerFragment.java b/app/src/main/java/com/kabouzeid/gramophone/ui/fragments/player/PlayerFragment.java index 632c26b8..cff9d21f 100644 --- a/app/src/main/java/com/kabouzeid/gramophone/ui/fragments/player/PlayerFragment.java +++ b/app/src/main/java/com/kabouzeid/gramophone/ui/fragments/player/PlayerFragment.java @@ -19,12 +19,15 @@ import android.widget.ImageView; import android.widget.TextView; import com.afollestad.materialdialogs.internal.ThemeSingleton; +import com.h6ah4i.android.widget.advrecyclerview.animator.GeneralItemAnimator; +import com.h6ah4i.android.widget.advrecyclerview.animator.RefactoredDefaultItemAnimator; +import com.h6ah4i.android.widget.advrecyclerview.draggable.RecyclerViewDragDropManager; +import com.h6ah4i.android.widget.advrecyclerview.utils.WrapperAdapterUtils; import com.kabouzeid.gramophone.R; import com.kabouzeid.gramophone.adapter.base.MediaEntryViewHolder; import com.kabouzeid.gramophone.adapter.song.PlayingQueueAdapter; import com.kabouzeid.gramophone.helper.MusicPlayerRemote; import com.kabouzeid.gramophone.loader.ArtistLoader; -import com.kabouzeid.gramophone.misc.DragSortRecycler; import com.kabouzeid.gramophone.model.Song; import com.kabouzeid.gramophone.ui.activities.base.AbsSlidingMusicPanelActivity; import com.kabouzeid.gramophone.util.ColorUtil; @@ -70,6 +73,9 @@ public class PlayerFragment extends AbsPlayerFragment implements PlayerAlbumCove private PlayingQueueAdapter playingQueueAdapter; + private RecyclerView.Adapter wrappedAdapter; + private RecyclerViewDragDropManager recyclerViewDragDropManager; + private Impl impl; @Override @@ -115,10 +121,33 @@ public class PlayerFragment extends AbsPlayerFragment implements PlayerAlbumCove @Override public void onDestroyView() { + if (recyclerViewDragDropManager != null) { + recyclerViewDragDropManager.release(); + recyclerViewDragDropManager = null; + } + + if (recyclerView != null) { + recyclerView.setItemAnimator(null); + recyclerView.setAdapter(null); + recyclerView = null; + } + + if (wrappedAdapter != null) { + WrapperAdapterUtils.releaseAll(wrappedAdapter); + wrappedAdapter = null; + } + playingQueueAdapter = null; + layoutManager = null; super.onDestroyView(); ButterKnife.unbind(this); } + @Override + public void onPause() { + recyclerViewDragDropManager.cancelDrag(); + super.onPause(); + } + @Override public void onPlayingMetaChanged() { updateIsFavorite(); @@ -170,19 +199,25 @@ public class PlayerFragment extends AbsPlayerFragment implements PlayerAlbumCove } private void setUpRecyclerView() { + recyclerViewDragDropManager = new RecyclerViewDragDropManager(); + final GeneralItemAnimator animator = new RefactoredDefaultItemAnimator(); + playingQueueAdapter = new PlayingQueueAdapter( ((AppCompatActivity) getActivity()), MusicPlayerRemote.getPlayingQueue(), R.layout.item_list, false, null); - recyclerView.setAdapter(playingQueueAdapter); + wrappedAdapter = recyclerViewDragDropManager.createWrappedAdapter(playingQueueAdapter); layoutManager = new LinearLayoutManager(getActivity()); layoutManager.setChildSize((int) (getResources().getDisplayMetrics().density * 72)); - recyclerView.setLayoutManager(layoutManager); - setUpDragSort(); + recyclerView.setLayoutManager(layoutManager); + recyclerView.setAdapter(wrappedAdapter); + recyclerView.setItemAnimator(animator); + + recyclerViewDragDropManager.attachRecyclerView(recyclerView); } @@ -194,23 +229,6 @@ public class PlayerFragment extends AbsPlayerFragment implements PlayerAlbumCove .setTitle(isFavorite ? getString(R.string.action_remove_from_favorites) : getString(R.string.action_add_to_favorites)); } - private void setUpDragSort() { - DragSortRecycler dragSortRecycler = new DragSortRecycler(); - dragSortRecycler.setViewHandleId(R.id.image_container); - dragSortRecycler.setOnItemMovedListener(new DragSortRecycler.OnItemMovedListener() { - @Override - public void onItemMoved(int from, int to) { - if (from == to) return; - MusicPlayerRemote.moveSong(from, to); - } - }); - - recyclerView.addItemDecoration(dragSortRecycler); - recyclerView.addOnItemTouchListener(dragSortRecycler); - recyclerView.addOnScrollListener(dragSortRecycler.getScrollListener()); - recyclerView.setItemAnimator(null); - } - @Override @ColorInt public int getPaletteColor() { diff --git a/app/src/main/java/com/kabouzeid/gramophone/util/ViewUtil.java b/app/src/main/java/com/kabouzeid/gramophone/util/ViewUtil.java index 2dee86df..a8a9e13b 100644 --- a/app/src/main/java/com/kabouzeid/gramophone/util/ViewUtil.java +++ b/app/src/main/java/com/kabouzeid/gramophone/util/ViewUtil.java @@ -10,6 +10,7 @@ import android.os.Build; import android.support.annotation.ColorInt; import android.support.annotation.NonNull; import android.support.annotation.Nullable; +import android.support.v4.view.ViewCompat; import android.support.v7.view.menu.ListMenuItemView; import android.support.v7.view.menu.MenuPopupHelper; import android.support.v7.widget.ActionMenuView; @@ -206,4 +207,15 @@ public class ViewUtil { } }); } + + public static boolean hitTest(View v, int x, int y) { + final int tx = (int) (ViewCompat.getTranslationX(v) + 0.5f); + final int ty = (int) (ViewCompat.getTranslationY(v) + 0.5f); + final int left = v.getLeft() + tx; + final int right = v.getRight() + tx; + final int top = v.getTop() + ty; + final int bottom = v.getBottom() + ty; + + return (x >= left) && (x <= right) && (y >= top) && (y <= bottom); + } } \ No newline at end of file