Drag & Rearrange ListView for Xamarin Android / by Pranav Khandelwal

I recently needed to implement a custom ListView component with drag to rearrange functionality for an Android application written in C# using Xamarin.

Video Link: http://vimeo.com/115447413

After doing some research, I came across the DevBytes tutorials on YouTube. If you are doing Android development and haven’t come across these videos yet, I would highly recommend taking a look: https://www.youtube.com/channel/UCVHFbqXqoYvEWM1Ddxl0QDg. They have some really informative and helpful content.

One of the videos walked you through the implementation of a drag to rearrange ListView on Android: https://www.youtube.com/watch?v=_BZIvjMgH-Q. This was exactly what I needed. 

The approach that was taken was that when a long press was detected, we perform the following operations:

  1. We determine the index-position in the List of our touch point.
     
  2. We create a “mock-cell” that would essentially be a screenshot of the long-pressed ListView cell. We add this cell on the screen in the same position and on top of our ListView cell.
     
  3. We set the visibility of the actual ListView cell to invisible. This gives the visual effect of an “empty” spot in the ListView

Then as the finger is panned up and down the screen, the following operations take place:

  1. We update the y-position of the touch-point on our “mock cell” to match the y-position of our pointer finger. This will provide the dragging effect.
     
  2. As our cell position updates, we will check to see if the cell is above or below an adjacent cell. When this condition is true, we will animate a swap by sliding the adjacent cell into its new position. When this animation is complete, we will update the dataset to match what is displayed on screen.

When the pointer finger is released we will animate the “mock-cell”
 back into position and when this animation is complete, we will get rid of our mock-cell and unhide the actual ListView cell.

The original source code is in Java, but porting it to C# was fairly straightforward.  I made a couple changes in the C# implementation:

  1.  Instead of doing the animation of the cells in the PreDraw event on the ViewTreeObserver after the dataset is updated. I do the animation and then change the dataset using an Object Animator object and its AnimationEnd event.
     
  2. I did not implement rearranging while scrolling, but it should be relatively straightforward to port the functionality over from the original tutorial.

How to implement:

  1. Download and include DraggabeListView.cs and IDragagbleListAdapter.cs into your solution.
     
  2.  Implement the custom component in your layout file. The following documentation from the Android Developer portal has an example of how to do this: http://developer.android.com/training/custom-views/create-view.html
     
  3. Create a ListView adapter class that implements the IDraggableListAdapter interface.  The interface includes one method: SwapItems(int from, int to) and one integer property: mMobileCellPosition. 
    SwapItems(int from, int to) is responsible for updating the underlying dataset, the mMobileCellPosition variable, and calling NotifyDataSetChanged() on the adapter. The integer property mMobileCellPosition is responsible for ensuring the correct visibility states for cells. Suggested implementations are included in the code.

Hope this helps anyone else doing Android development using Xamarin. If you have questions or comments to improve the code, do not hesitate to comment or reach out!

Link to code: https://github.com/pnavk/DraggableListView

Thanks for reading!

PK