diff options
6 files changed, 121 insertions, 106 deletions
diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/MainActivity.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/MainActivity.java index c401fb314..06d67c291 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/MainActivity.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/MainActivity.java @@ -76,42 +76,8 @@ public class MainActivity extends DrawerActivity { //TODO limit this call only to lower API levels like KitKat because they crash without AppCompatDelegate.setCompatVectorFromResourcesEnabled(true); - //TODO replace nulls new CrossTabDragAndDrop(this).register(viewPager); -// viewPager.setOnDragListener((View v, DragEvent dragEvent) -> { -// Log.d("Deck", "Drag: "+ dragEvent.getAction()); -// if(dragEvent.getAction() == 4) -// Log.d("Deck", dragEvent.getAction() + ""); -// -// View view = (View) dragEvent.getLocalState(); -// RecyclerView owner = (RecyclerView) view.getParent(); -// CardAdapter cardAdapter = (CardAdapter) owner.getAdapter(); -// -// switch(dragEvent.getAction()) { -// case DragEvent.ACTION_DRAG_LOCATION: -// Point size = new Point(); -// getWindowManager().getDefaultDisplay().getSize(size); -// if(dragEvent.getX() <= 20) { -// Log.d("Deck", dragEvent.getAction() + " moved left"); -// viewPager.setCurrentItem(viewPager.getCurrentItem() - 1); -// } else if(dragEvent.getX() >= size.x - 20) { -// viewPager.setCurrentItem(viewPager.getCurrentItem() + 1); -// Log.d("Deck", dragEvent.getAction() + " moved right"); -// } -// int viewUnderPosition = owner.getChildAdapterPosition(owner.findChildViewUnder(dragEvent.getX(), dragEvent.getY())); -// if(viewUnderPosition != -1) { -// Log.d("Deck", dragEvent.getAction() + " moved something..."); -// cardAdapter.moveItem(owner.getChildLayoutPosition(view), viewUnderPosition); -// } -// break; -// case DragEvent.ACTION_DROP: -// view.setVisibility(View.VISIBLE); -// break; -// } -// return true; -// }); - fab.setOnClickListener((View view) -> { Intent intent = new Intent(this, EditActivity.class); intent.putExtra(BUNDLE_KEY_ACCOUNT_ID, account.getId()); diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/CardAdapter.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/CardAdapter.java index 0fee17f7b..1efec341c 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/CardAdapter.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/CardAdapter.java @@ -31,7 +31,7 @@ import com.nextcloud.android.sso.exceptions.NoCurrentAccountSelectedException; import com.nextcloud.android.sso.helper.SingleAccountHelper; import com.nextcloud.android.sso.model.SingleSignOnAccount; -import java.util.ArrayList; +import java.util.LinkedList; import java.util.List; import butterknife.BindView; @@ -43,6 +43,7 @@ import it.niedermann.nextcloud.deck.model.Label; import it.niedermann.nextcloud.deck.model.User; import it.niedermann.nextcloud.deck.model.full.FullCard; import it.niedermann.nextcloud.deck.ui.EditActivity; +import it.niedermann.nextcloud.deck.ui.helper.dnd.DraggedCardLocalState; import it.niedermann.nextcloud.deck.util.ColorUtil; import it.niedermann.nextcloud.deck.util.DateUtil; import it.niedermann.nextcloud.deck.util.DimensionUtil; @@ -61,7 +62,7 @@ public class CardAdapter extends RecyclerView.Adapter<CardAdapter.CardViewHolder public static final int MAX_AVATAR_COUNT = 3; private Context context; - private List<FullCard> cardList = new ArrayList<>(); + private List<FullCard> cardList = new LinkedList<>(); private SingleSignOnAccount account; private long boardId; @@ -109,7 +110,7 @@ public class CardAdapter extends RecyclerView.Adapter<CardAdapter.CardViewHolder // Starts the drag draggedView.startDrag(dragData, // the data to be dragged new View.DragShadowBuilder(draggedView), // the drag shadow builder - draggedView, // no need to use local data + new DraggedCardLocalState(card, viewHolder.card, this, position), // no need to use local data 0 // flags (not currently used, set to 0) ); viewHolder.card.setVisibility(View.INVISIBLE); diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/helper/dnd/CrossTabDragAndDrop.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/helper/dnd/CrossTabDragAndDrop.java index 595278253..23d0dba2d 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/helper/dnd/CrossTabDragAndDrop.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/helper/dnd/CrossTabDragAndDrop.java @@ -10,11 +10,8 @@ import androidx.cardview.widget.CardView; import androidx.recyclerview.widget.RecyclerView; import androidx.viewpager.widget.ViewPager; -import java.util.Objects; - import it.niedermann.nextcloud.deck.DeckLog; import it.niedermann.nextcloud.deck.R; -import it.niedermann.nextcloud.deck.model.full.FullCard; import it.niedermann.nextcloud.deck.ui.card.CardAdapter; import it.niedermann.nextcloud.deck.ui.stack.StackAdapter; @@ -34,21 +31,21 @@ public class CrossTabDragAndDrop { public void register(final ViewPager viewPager) { viewPager.setOnDragListener((View v, DragEvent dragEvent) -> { + DraggedCardLocalState draggedCardLocalState = (DraggedCardLocalState) dragEvent.getLocalState(); + CardView cardView = draggedCardLocalState.getDraggedView(); switch (dragEvent.getAction()) { case DragEvent.ACTION_DRAG_STARTED: { - CardView cardView = (CardView) dragEvent.getLocalState(); cardView.setVisibility(View.INVISIBLE); + draggedCardLocalState.setRecyclerView(((StackAdapter) viewPager.getAdapter()).getItem(viewPager.getCurrentItem()).getRecyclerView()); break; } case DragEvent.ACTION_DRAG_LOCATION: { - RecyclerView currentRecyclerView = getCurrentRecyclerView(viewPager); - CardView cardView = findInvisibleCardView(currentRecyclerView); - CardAdapter cardAdapter = (CardAdapter) currentRecyclerView.getAdapter(); + RecyclerView currentRecyclerView = draggedCardLocalState.getRecyclerView(); + CardAdapter cardAdapter = draggedCardLocalState.getCardAdapter(); Point size = new Point(); activity.getWindowManager().getDefaultDisplay().getSize(size); - FullCard itemToMove = null; long now = System.currentTimeMillis(); if (lastSwap + msToReact < now) { // don't change Tabs so fast! int oldTabPosition = viewPager.getCurrentItem(); @@ -65,35 +62,29 @@ public class CrossTabDragAndDrop { shouldSwitchTab = false; } - if (shouldSwitchTab && isMovePossible(viewPager, newTabPosition) && cardView != null) { - itemToMove = removeItemAndReturnPayload(currentRecyclerView, cardView, cardAdapter); - moveCardToTab(viewPager, itemToMove, now, newTabPosition); + if (shouldSwitchTab && isMovePossible(viewPager, newTabPosition)) { + removeItem(currentRecyclerView, cardView, cardAdapter); + moveCardToTab(viewPager, draggedCardLocalState, now, newTabPosition); return true; } } //push around the other cards - - CardView newCardViewToSearch = findInvisibleCardView(currentRecyclerView); -// DeckLog.log("dnd card count:" + ((CardAdapter) currentRecyclerView.getAdapter()).getCardList().size()); - - if (newCardViewToSearch == null) { -// DeckLog.log("dnd skipping"); - return true; - } View viewUnder = currentRecyclerView.findChildViewUnder(dragEvent.getX(), dragEvent.getY()); if (viewUnder != null) { - int viewUnderPosition = currentRecyclerView.getChildAdapterPosition(viewUnder); - if (viewUnderPosition != -1) { - Objects.requireNonNull(cardAdapter).moveItem(currentRecyclerView.getChildLayoutPosition(newCardViewToSearch), viewUnderPosition); + int toPositon = currentRecyclerView.getChildAdapterPosition(viewUnder); + if (toPositon != -1) { + int fromPosition = currentRecyclerView.getChildAdapterPosition(cardView); + if (fromPosition != -1) { + cardAdapter.moveItem(fromPosition, toPositon); + draggedCardLocalState.setPositionInCardAdapter(toPositon); + } } } break; } case DragEvent.ACTION_DROP: { - RecyclerView currentRecyclerView = getCurrentRecyclerView(viewPager); - CardView cardView = findInvisibleCardView(currentRecyclerView); cardView.setVisibility(View.VISIBLE); break; } @@ -102,40 +93,35 @@ public class CrossTabDragAndDrop { }); } - private void moveCardToTab(ViewPager viewPager, FullCard itemToMove, long now, int newPosition) { + private void moveCardToTab(ViewPager viewPager, final DraggedCardLocalState draggedCardLocalState, long now, int newPosition) { viewPager.setCurrentItem(newPosition); + draggedCardLocalState.onTabChanged(viewPager, newPosition); - final RecyclerView recyclerView = getCurrentRecyclerView(viewPager); - CardAdapter cardAdapter = (CardAdapter) recyclerView.getAdapter(); + final RecyclerView recyclerView = draggedCardLocalState.getRecyclerView(); + CardAdapter cardAdapter = draggedCardLocalState.getCardAdapter(); //insert card in new tab View firstVisibleView = recyclerView.getChildAt(0); - int positionToInsert = firstVisibleView == null ? 0 : recyclerView.getChildAdapterPosition(firstVisibleView); + int positionToInsert = firstVisibleView == null ? 0 : recyclerView.getChildAdapterPosition(firstVisibleView)+1; -// //already present? -// for (int i = 0; i < cardAdapter.getItemCount(); i++) { -// FullCard fullCard = cardAdapter.getItem(i); -// if (itemToMove.getCard().getLocalId().equals(fullCard.getCard().getLocalId())){ -// cardAdapter.removeItem(i); -// DeckLog.log("dnd removed afterwards"); -// } -// } + cardAdapter.addItem(draggedCardLocalState.getDraggedCard(), positionToInsert); - - cardAdapter.addItem(itemToMove, positionToInsert); - - recyclerView.addOnChildAttachStateChangeListener(new RecyclerView.OnChildAttachStateChangeListener() { + RecyclerView.OnChildAttachStateChangeListener onChildAttachStateChangeListener = new RecyclerView.OnChildAttachStateChangeListener() { @Override public void onChildViewAttachedToWindow(@NonNull View view) { recyclerView.removeOnChildAttachStateChangeListener(this); + draggedCardLocalState.setInsertedListener(null); CardView cardView = (CardView) view; cardView.setVisibility(View.INVISIBLE); + draggedCardLocalState.setDraggedView(cardView); DeckLog.log("dnd there it is! pos: " + positionToInsert); } @Override public void onChildViewDetachedFromWindow(@NonNull View view) {/* do nothing */} - }); + }; + draggedCardLocalState.setInsertedListener(onChildAttachStateChangeListener); + recyclerView.addOnChildAttachStateChangeListener(onChildAttachStateChangeListener); cardAdapter.notifyItemInserted(positionToInsert); cardAdapter.notifyItemChanged(positionToInsert); @@ -147,31 +133,13 @@ public class CrossTabDragAndDrop { return newPosition < viewPager.getAdapter().getCount() && newPosition >= 0; } - private static CardView findInvisibleCardView(RecyclerView recyclerView) { -// DeckLog.log("dnd number entries: "+recyclerView.getChildCount()); - for (int i = 0; i < recyclerView.getChildCount(); i++) { - View view = recyclerView.getChildAt(i); - - if (view.findViewById(R.id.card).getVisibility() == View.INVISIBLE) { - return (CardView) view; - } - } - return null; - } - - private static RecyclerView getCurrentRecyclerView(ViewPager viewPager) { - return ((StackAdapter) viewPager.getAdapter()).getItem(viewPager.getCurrentItem()).getRecyclerView(); - } - - private static FullCard removeItemAndReturnPayload(RecyclerView currentRecyclerView, CardView cardView, CardAdapter cardAdapter) { - + private static void removeItem(RecyclerView currentRecyclerView, CardView cardView, CardAdapter cardAdapter) { int oldCardPosition = currentRecyclerView.getChildAdapterPosition(cardView); DeckLog.log("DnD: removing! pos: " + oldCardPosition + " | " + cardView); - FullCard itemToMove = cardAdapter.getItem(oldCardPosition); - - cardAdapter.removeItem(oldCardPosition); - DeckLog.log("DnD: removed " + itemToMove); - return itemToMove; + if (oldCardPosition != -1){ + cardAdapter.removeItem(oldCardPosition); + DeckLog.log("DnD: removed"); + } else DeckLog.log("DnD: wasnt present to remove"); } } diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/helper/dnd/DraggedCardLocalState.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/helper/dnd/DraggedCardLocalState.java new file mode 100644 index 000000000..155a9ea5e --- /dev/null +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/helper/dnd/DraggedCardLocalState.java @@ -0,0 +1,82 @@ +package it.niedermann.nextcloud.deck.ui.helper.dnd; + +import androidx.cardview.widget.CardView; +import androidx.recyclerview.widget.RecyclerView; +import androidx.viewpager.widget.ViewPager; + +import it.niedermann.nextcloud.deck.model.full.FullCard; +import it.niedermann.nextcloud.deck.ui.card.CardAdapter; +import it.niedermann.nextcloud.deck.ui.stack.StackAdapter; + +public class DraggedCardLocalState { + private FullCard draggedCard; + private CardView draggedView; + private CardAdapter cardAdapter; + private int positionInCardAdapter; + private RecyclerView.OnChildAttachStateChangeListener insertedListener = null; + private RecyclerView recyclerView = null; + + public DraggedCardLocalState(FullCard draggedCard, CardView draggedView, CardAdapter cardAdapter, int positionInCardAdapter) { + this.draggedCard = draggedCard; + this.draggedView = draggedView; + this.cardAdapter = cardAdapter; + this.positionInCardAdapter = positionInCardAdapter; + } + + public FullCard getDraggedCard() { + return draggedCard; + } + + public void setDraggedCard(FullCard draggedCard) { + this.draggedCard = draggedCard; + } + + public CardView getDraggedView() { + return draggedView; + } + + public void setDraggedView(CardView draggedView) { + this.draggedView = draggedView; + } + + public CardAdapter getCardAdapter() { + return cardAdapter; + } + + public void setCardAdapter(CardAdapter cardAdapter) { + this.cardAdapter = cardAdapter; + } + + public int getPositionInCardAdapter() { + return positionInCardAdapter; + } + + public void setPositionInCardAdapter(int positionInCardAdapter) { + this.positionInCardAdapter = positionInCardAdapter; + } + + public RecyclerView.OnChildAttachStateChangeListener getInsertedListener() { + return insertedListener; + } + + public void setInsertedListener(RecyclerView.OnChildAttachStateChangeListener insertedListener) { + this.insertedListener = insertedListener; + } + + public RecyclerView getRecyclerView() { + return recyclerView; + } + + public void setRecyclerView(RecyclerView recyclerView) { + this.recyclerView = recyclerView; + } + + public void onTabChanged(ViewPager viewPager, int newTabPosition){ + if (insertedListener != null) { + recyclerView.removeOnChildAttachStateChangeListener(insertedListener); + insertedListener = null; + } + this.recyclerView = ((StackAdapter) viewPager.getAdapter()).getItem(newTabPosition).getRecyclerView(); + this.cardAdapter = (CardAdapter) recyclerView.getAdapter(); + } +} diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/stack/StackFragment.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/stack/StackFragment.java index 4496ae50f..6aa6ae12e 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/stack/StackFragment.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/stack/StackFragment.java @@ -8,7 +8,6 @@ import android.view.ViewGroup; import androidx.annotation.NonNull; import androidx.fragment.app.Fragment; -import androidx.recyclerview.widget.ItemTouchHelper; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; @@ -25,7 +24,6 @@ import it.niedermann.nextcloud.deck.model.full.FullCard; import it.niedermann.nextcloud.deck.model.full.FullStack; import it.niedermann.nextcloud.deck.persistence.sync.SyncManager; import it.niedermann.nextcloud.deck.ui.card.CardAdapter; -import it.niedermann.nextcloud.deck.ui.card.CardItemTouchHelper; public class StackFragment extends Fragment { @@ -122,8 +120,8 @@ public class StackFragment extends Fragment { adapter = new CardAdapter(boardId); recyclerView.setAdapter(adapter); recyclerView.setLayoutManager(new LinearLayoutManager(getContext())); - ItemTouchHelper touchHelper = new CardItemTouchHelper(adapter); - touchHelper.attachToRecyclerView(recyclerView); +// ItemTouchHelper touchHelper = new CardItemTouchHelper(adapter); +// touchHelper.attachToRecyclerView(recyclerView); } private void runOnUiThread(Runnable r) { diff --git a/app/src/main/res/values/customization.xml b/app/src/main/res/values/customization.xml index 270ad3fa2..c471fcaeb 100644 --- a/app/src/main/res/values/customization.xml +++ b/app/src/main/res/values/customization.xml @@ -5,7 +5,7 @@ <!-- How many characters of the labels are displayed at the card list view --> <integer name="max_labels_chars">2</integer> <!-- How many microseconds should be waited before switching to another tab when dragging cards --> - <integer name="drag_n_drop_ms_to_react">500</integer> + <integer name="drag_n_drop_ms_to_react">700</integer> <!-- How many dp from border should one be away before switching to another tab when dragging cards --> <integer name="drag_n_drop_dp_to_react">20</integer> </resources>
\ No newline at end of file |