question

njsokalski avatar image
0 Votes"
njsokalski asked RobCaplan edited

Reordering A RecyclerView Using Drag & Drop

I have a Xamarin.Android app containing a RecyclerView in which I want to allow the user to reorder the items using Drag & Drop. I know the basics of Drag & Drop using the StartDragAndDrop method & Drag event. I call StartDragAndDrop from the LongClick event of the item I want to move. However, here are some of the things I am having trouble figuring out how to do:

  1. Determine the Source of the event during the Entered & Exited DragAction. Because ClipData is only available during the Drop DragAction, I was unable to use that. I need this information during Entered & Exited because I want to visually shift the other items so the user can see where this item will be placed.

  2. Customizing the DragShadowBuilder. I need to do this because I want the Drag Shadow to be opaque, so that the user appears to be dragging the actual item.

  3. Restricting the drag motion to vertical. Because the items are being reordered (as opposed to other scenarios where items may get dragged to different boxes or areas), I do not what the items being moved horizontally. I am not sure what the best way to do this is, although the two ideas crossing my mind were dynamically changing the layout margins of the item or dynamically modifying the Shadow Metrics of the Drag Shadow.

Are there any good examples of ways to reorder a RecyclerView? What is the best way to access drag source data in the Entered & Exited DragAction(s)? Are there any good examples of a custom DragShadowBuilder (the documentation did not give any good examples)? Are there any easy ways to restrict dragging to vertical? Thanks.

dotnet-xamarin
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

1 Answer

LeonLu-MSFT avatar image
0 Votes"
LeonLu-MSFT answered LeonLu-MSFT edited

Hello,​

Welcome to our Microsoft Q&A platform!

A

re there any easy ways to restrict dragging to vertical?

If you use RecyclerView in Xamarin.Android, you can achieve an interface ItemTouchHelper.Callback , it comes from AndroidX.RecyclerView.Widget. If we want to restrict dragging to vertical. Override the GetMovementFlags method, add move restriction by const int dragFlags = ItemTouchHelper.Up | ItemTouchHelper.Down; and set ItemTouchHelper.ActionStateIdle, then return it by MakeMovementFlags method.

public class SimpleItemTouchHelperCallback : ItemTouchHelper.Callback
    {
        private readonly ITemTouchHelperAdapter _mAdapter;

        public SimpleItemTouchHelperCallback(ITemTouchHelperAdapter adapter)
        {
            _mAdapter = adapter;
        }

        public override int GetMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder)
        {
            const int dragFlags = ItemTouchHelper.Up | ItemTouchHelper.Down;
            const int swipeFlags = ItemTouchHelper.ActionStateIdle;
            return MakeMovementFlags(dragFlags, swipeFlags);
        }

        public override bool OnMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target)
        {
            if (viewHolder.ItemViewType != target.ItemViewType)
            {
                return false;
            }

            // Notify the adapter of the move
            _mAdapter.OnItemMove(viewHolder.AdapterPosition, target.AdapterPosition);
            return true;
        }

        public override void OnSwiped(RecyclerView.ViewHolder viewHolder, int direction)
        {
            // Notify the adapter of the dismissal
            _mAdapter.OnItemDismiss(viewHolder.AdapterPosition);
        }
    }



Are there any good examples of ways to reorder a RecyclerView?

If you want to this, please Google: ReOrder the list items by drag and drop in xamarin android using RecyclerView


Please note: If you want to make above simple work in androidX, please create a new project by VS, then copy the code to this new project.

Best Regards,

Leon Lu



If the response is helpful, please click "Accept Answer" and upvote it.

Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


· 1
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Thank you for your help, it was a life saver! I was unaware of ItemTouchHelper, but after doing some searching, I have (most) of my question fixed. Here are a few of the things that will hopefully save some frustration:

Using ItemTouchHelper.SimpleCallback allows direction to be specified in the constructor instead of GetMovementFlags.

The Callback is added as follows (I previously didn't know how to add it, so hopefully this is direct enough for anyone else):

 new ItemTouchHelper(new VerticalSimpleCallback(ItemTouchHelper.Up | ItemTouchHelper.Down, ItemTouchHelper.ActionStateIdle)).AttachToRecyclerView(this.rvPlayerNamesInput);

I may have just been missing something else, but calling StartDragAndDrop (which I hopefully won't need now) seemed to be preventing the OnMove method from being called, but that could have been me

This is my first RecyclerView with dragging, but knowing about ItemTouchHelper is something I am very glad I found out about! Thanks again!

0 Votes 0 ·