Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make a ListView with draggable items?

I was looking for a ListPreference in which the user can change the order of items from a list. The items would be draggable and can be re-ordered by the user.

I saw this in my custom ROM (and I'm almost sure I saw it in Cyanogenmod) for the QuickPanel. Here's a screenshot to get the idea through:

Screenshot of the "widget Button Order" in QuickPanel Settings of Sabotage ROM

I know how I can make custom ListView items and set the icon to indicate that the items are draggable, but I don't know how to make them draggable, and change the order accordingly. As for saving them in the preferences, I found this which could be implemented easily.

PS: I know Cyanogenmod is open-source, but I couldn't find the source for this particular thing :( The closest I could get was this, which should be somewhere near the other screen...

Thanks in advance for any tip about this.

UPDATE: I ended up using the files from the accepted answer, with additions and modifications. I am listing them here for further reference.

  • Use a custom Adapter (ArrayAdapter in my case), to implement the visual feedback that this item is draggable, which is an ImageView near the TextView. This is optional.

  • Set a DragListener and RemoveListener to update the list accordingly. The ListView does not do that automatically. And it depends on the Adapter you are using.

  • There was a line that casted a View to a ViewGroup, it made some errors, so I removed the cast without any issue, it was not needed. (in the onInterceptTouchEvent method).

  • Change mRemoveMode = 1; in the constructor of TouchInterceptor, or one of: FLING = 0; SLIDE = 1; TRASH = 2;. I think for TRASH, a resource should be available too.

I actually took the file not from the answer's link but from the Cyanogenmod one, which I already had, but I guess these files were the same.

These are the actual files in the project (at r12, at the time of writing):

  • The Preference using this ListView
  • The ListActivity with the listeners and the Adapter
  • The actual ListView

I hope it helps somebody else :)

like image 975
jadkik94 Avatar asked Jun 20 '12 16:06

jadkik94


1 Answers

There is no built-in widget to do this, but you may want take a look at the custom implementation used by the AOSP music player to allow for re-ordering of songs in playlists.

TouchInterceptor.java

That's the class which is extending ListView and is responsible for handling all of the MotionEvents and re-ordering its items, as well as detecting swipes for deleting items. You can see it implemented into an activity here in the TrackBrowserActivity.java class.

It has three interfaces you should also be aware of: DragListener, DropListener, and RemoveListener. You can use these interfaces to provide it callbacks to fire for those events, so that you can update changes made to the list order to your SavedPreferences (since the ListView will not handle that for you).

You can easily extend or modify the TouchInterceptor class to add additional functionality since the low-level stuff is all there for you.

like image 118
Victor Avatar answered Sep 28 '22 04:09

Victor