# drag-sort-listview **Repository Path**: fly0116/drag-sort-listview ## Basic Information - **Project Name**: drag-sort-listview - **Description**: Android ListView with drag and drop reordering. - **Primary Language**: Java - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2016-01-27 - **Last Updated**: 2020-12-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README DragSortListView ================ This is an extension of the Android ListView that enables drag-and-drop re-sorting of list items. The code is based on the [TouchInterceptor](https://github.com/android/platform_packages_apps_music/blob/master/src/com/android/music/TouchInterceptor.java) (TI) from the Google Music app (silly if it weren't!); therefore, the essential behavior is the same---list item heights and visibilities are adjusted to create an empty slot that tracks the item being dragged. User-provided Listener objects are informed of drag and drop events; these Listeners perform the actual reorderings within the user's [ListAdapter](http://developer.android.com/reference/android/widget/ListAdapter.html). While using the TI in an app of mine, I noticed the following behaviors that I thought needed polishing (in order of importance): 1. Scrolling while dragging is erratic. A scroll is initiated in the TI only when a MOVE event is detected. I don't think this is a user-expected behavior. 2. List item View heights must be homogeneous and pre-specified. 3. Shuffling of list items is buggy for some drag movements (e.g. shuffle occurs only after large overlap of floating View with visible list items, last/first item in list does not shuffle, etc.). 4. The list view sometimes jumps unexpectedly when dropping the floating View. 5. Region for item drag initiation is hard-coded in the TI. 6. Floating View is not bounded to ListView (maybe not such an issue, mostly aesthetic). The above shortcomings caused a major reworking of the TI implementation details, resulting in DragSortListView (DSLV). I see a lot of potential in a clean drag-sort list; any app with a user-created list (e.g. "favorites") should benefit. 1. Scrolling while dragging is now intuitive and easily customizable. 2. Arbitrary item heights are supported. 3. Dragging/Dropping/Drag-scrolling are mostly clean. 4. (see 3) 5. Drag initiation is customizable at the per-item level. 6. Bounds on floating View (big whoop?) I hope you find it useful! And please, help me improve the thing! Usage ----- The best place to learn DSLV semantics is in the `demo/` directory. So, as a first step, I recommend building the examples, playing with them, and then exploring `demo/src/` and `demo/res/` for the details. That said, the following is a brief overview of DSLV usage. The DSLV can be declared in an XML layout file just like the ListView. Here is the example [from the demo](https://github.com/bauerca/drag-sort-listview/blob/master/demo/res/layout/dslv_main.xml) that shows all available attributes. The attributes are * `collapsed_height`: (dimension) Height of placeholder at original drag position. * `drag_scroll_start`: (float) Start of drag-scroll regions (defined by a fraction of the total DSLV height). * `max_drag_scroll_speed`: (float) Maximum drag-scroll speed for default linear drag-scroll profile. Units of pixels/millisecond. * `float_background_color`: (color) Background color of floating View. * `remove_mode`: (enum) One of "none" "fling", "slide", "slideRight", "slideLeft". This is inherited from the TI and may change. * `track_drag_scroll`: (bool) Debugging option; explained below. Drag-sorting in the DSLV is enabled when: 1. A `DragSortListView.DragListener` or `DragSortListView.DropListener` is registered with the DSLV instance and 2. A child View of the list item to be dragged has an `android:id` named `drag`. If you have ever used the TI, the Drag and Drop Listeners should be familiar. Otherwise, there is limited documentation in the DSLV. You can check it out with Javadoc by navigating to `/path/to/drag-sort-listview/src/` and typing javadoc com.mobeta.android.dslv * I imagine most use cases will require only a DropListener to perform the ListAdapter reordering. To register, simply pass it to `DragSortListView.setDropListener()`. To illustrate the second requirement, the following is an example XML layout file for a ListView item and can be found [in the demo project](https://github.com/bauerca/drag-sort-listview/blob/master/demo/res/layout/jazz_artist_list_item.xml): Okay, so all of the above is just fluff except for the line android:id="@id/drag" which tells DSLV which child View is responsible for initiating the item drag. You will notice that `@id` is used rather than `@+id`. This is because the demo project references the DSLV as an external Android library, in which the id named `drag` is already defined. In fact, when used as a standalone library, the DSLV cannot access ids defined by the dependent app. Okay, maybe not all fluff; the above layout file is an example of how DSLV can handle arbitrary list item heights! Notice that the enclosing LinearLayout uses `"wrap_content"` as its layout_height. This means the height of the list item is determined by how much text is in there. Check out the demo! Another way to use the DSLV is by copying the DragSortListView.java file directly into your project. In this case, you must also: 1. Use `android:id="@+id/drag"` (notice the +) in your list item layout file OR copy `res/values/ids.xml` to your project and use `@id/drag`. 2. Change the package name declaration line at the top of DragSortListView.java to your package name. 3. Copy `res/values/dslv_attrs.xml` to your project 4. In the XML layout file that declares the DSLV, make sure to use your package name (as opposed to `com.mobeta.android.(demo)dslv` in the example above) Installation ------------ Download and install the [Android sdk](http://developer.android.com/sdk/index.html). Clone/Download/Fork the repo through GitHub or via (read-only) git clone https://github.com/bauerca/drag-sort-listview.git Navigate to drag-sort-listview/ and type (assuming /path/to/android_sdk/tools is in your PATH) android update project --path ./ --subprojects Then, navigate to drag-sort-listview/demo/, build, and try out the examples. Debugging --------- If you have python and [matplotlib](http://matplotlib.sourceforge.net/) installed, you can use the script dslv.py to debug drag scroll behavior (a drag scroll occurs when a list item is dragged to the edge of the ListView, causing a scroll). This script is found in the project tools/ directory. To enable, just set the `dslv:track_drag_scroll` attribute to `"true"` in XML. While drag scrolling on your emulator or device, this tracking causes the DSLV to periodically dump its state to a file called dslv_state.txt in the device/emulator /sdcard/ directory. Navigate to the location of dslv.py, and do adb [-e|-d|-s device] pull /sdcard/dslv_state.txt then simply run python dslv.py An image should appear that represents the DSLV in the final recorded state. Right and left keys allow stepping through the recorded drag scroll frame-by-frame. This tool has been very useful for debugging jumpy drag scroll behavior.