I am continually surprised by the fact that the things I need for my application do not exist in android. This time I needed a drag and drop list. I have been unsuccessful in finding a simple, working drag and drop list that I can extend. I have seen numerous places that reference android's music app as a starting place. The main classes of importance from the music app were TouchInterceptor and TrackBrowserActivity. Many of the examples that I have seen struggled to use it well and most ended up having serious problems as a result. I would rate the TouchInterceptor code with a rating of "F" because it is not simple and it is not easily extendable. Check out this article for a way to rate code. It left a good impression on me.
This experience is about my efforts to build a simplified drag and drop list. I hope time will prove that it is easy to extend as well. The first task was to get a copy of TouchInterceptor and TrackBrowserActivity running in a simplified project. This took time because of all the dependencies and interconnections between these two classes and the rest of the app. As I look back on the matter the only real benefit this provided me with was a better understanding of how not to make TouchInterceptor work. After I had a runnable project, I attempted to modify the drag animation from an expanding/contracting items on drag to one that rearranged items in place. I was almost finished with this change when I ran into a technical issue that I didn't want to spend time to fix. I then discovered that the Launcher app provided a better drag and drop example because it was simplified compared to some of the complex interactions in the music app. Using both the music app and the launcher app as a reference I wrote a simplified drag and drop project. You can find the project here.
I wanted to provide methods that allowed modifying/customizing the view of the item being dragged, but not fall into the same complex interactions of the music app. I chose to use the DragListener with the intended purpose of handling view changes. In the sample project, I made the item's view invisible to show where the drag view came from, and I changed the background color to show that a drag view is different from the rest of the item views. It is important to revert any changes to the item view because it will be recycled back into the list view for item views.
This project code is simply to share a simple working drag and drop list since I was unable to find one elsewhere on the web. If you add any extensions to this simple project I would like to hear about it in the comments.
Nice example. Thanks.
ReplyDeleteI love u for this!
ReplyDeleteGlad you like it!
ReplyDeleteThis is excellent, far easier to understand than TouchInterceptor. Is this released under any particular license? I'd like to use it in a commercial/closed-source project. Thanks!
ReplyDelete@Jeffrey I have not specified a license in the source code yet. Use it in accordance with Apache 2.0 Thanks for the reminder for me to specify the license.
ReplyDeleteHey I got some checkboxes on the view i'm dragging/dropping.
ReplyDeleteOn drop they aren't chackable anymore, I have to hide them (scroll) to re enable them.
I tried invalidateviews on the list, notifyDatasetChanged/Invalidate on the atapter, it's the same, any idea ?
@VV I am having trouble reproducing your issue. I just took the sample code and modified the dragitem.xml to be a checkbox. Then I rearranged the items and checked all the check boxes. No problems. If you are still having an issue with this could you explain the steps to trigger it.
ReplyDeleteThank you for your example, great help! but I don't know is anyone get the problem when clicking the items too quick? I got an exception when I was dragging and dropping the items repeatedly in a very short time, like 0.1 second. so i need to prevent the double clicks in DragNDropListView:
ReplyDelete...
private static long lastTouchTime = -1;
...
public boolean onTouchEvent(MotionEvent ev) {
...
if (action == MotionEvent.ACTION_DOWN && x < this.getWidth()/4) {
mDragMode = true;
// check is double clicked within 2 seconds
if (System.currentTimeMillis() - lastTouchTime < 2000) {
mDragMode = false;
}
}
...
private void stopDrag(int itemIndex) {
...
// save the last touch time
lastTouchTime = System.currentTimeMillis();
}
...
it seems can solve the exception, but i'm not sure is only my simulator or phone problem... hope can help if others have that problem
I saw this issue when I created my Drag and Drop List. It was an unfortunate carryover from the music app in the android repository. I like your code snippet. Thanks for sharing it.
ReplyDeleteExcellent example! Thanks for sharing this! :)
ReplyDeleteI too added a checkbox to the dragitem.xml:
ReplyDeleteIf I check the first item in the list and then move it to be second item in list, then for me the 10th item in the list is checked and the check is missing from the item I checked (hope that makes sense). If I move it back again, it is check as it should be. I guess this is something to do with the way ListViews reuse views... not figured it out, but thought I'd mention it here until I have! Maybe you have a solution?!
Also, can I make the entire ListView entry make the item movable? Currently it is only the left of the ListView item (Image in your sample) but if I move the image to the right, then it no logner works and I have to use first part of text to move item entry. Can't see where to sort this one....
Otherwise, as I said above, excellent example! :D
@Neil Deadman Thanks for the easy steps to follow. Now that I see the checkbox issue I have an idea. Try modifing the DragNDropAdapter. It is currently designed specifically for dragitem.xml to be a TextView. You will probably need to modify ViewHolder and possible mContents to be able to hold the text content and the checked state. Be sure to set/update the text content and checked state in the Adapter's getView(). Hope this is descriptive enough to figure out the rest of the details.
ReplyDeleteAs for your second question look in DragNDropListView's onTouchEvent(MotionEvent). You could change the line of code that reads
if (action == MotionEvent.ACTION_DOWN && x < this.getWidth()/4)
{
mDragMode = true;
}
to something simpler like
if (action == MotionEvent.ACTION_DOWN)
{
mDragMode = true;
}
Nice Example, Thanks
ReplyDeleteIf you go crazy draging the rows around you can make the example crash at line 88 in DragNDropListView.java with the following error:
ReplyDelete12-29 14:21:33.793: ERROR/AndroidRuntime(11715): at com.ericharlow.DragNDrop.DragNDropListView.drag(DragNDropListView.java:88)
Nothing a try/catch can not fix :)
Almost forgot - Great example!! Will use this as base for my own drag'n drop stuff. However as this is list views I would recommend that the x parameter is ignored so the list rows are only dragged up/down and do not follow the hand around the screen.
ReplyDeleteGreat work!
ReplyDeleteI was trying to add this as a custom preference but I can't get the Drag/Drop Listeners to work.
Any ideas?
Thanks a lot.
@CS Shenouda I have never tried to add Drag and Drop as a custom preference. I do like the concept. Are you getting a repeatable error or crash? How could I repeat it?
ReplyDeleteNo error.
ReplyDeleteI extend ListPreference.
In onPrepareDialogBuilder I do this:
DragAdapter = new DragNDropAdapter(getContext(), new int[]{R.layout.dragitem}, new int[]{R.id.TextView01}, entries);
builder.setAdapter(DragAdapter, new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int which)
{
}
});
I just don't know how to add the drag/drop/remove listeners in the ListPreference.
At the moment I solved it by just launching it as an activity from my preference screen.
Still for the sake of reusability it would be great to make a custom ListPreference :)
This is neat - it helped me get past a problem I wasn't able to figure out from the Android music app source. One quick question -- I am unable to drag/drop past the current view (i.e. if I have 20 rows, but only 5 rows visible, I can't drag row 0 past the 5th row). Any ideas why that would be? Essentially, the ListView in the background isn't scrolling.
ReplyDelete@Viraj Mody The reason drag and scroll doesn't work is because that code was striped out of this example.The music app has this code that you could add back in and adapt as needed.
ReplyDelete@Eric Harlow Thanks - I did. Made a couple of other changes too:
ReplyDelete- limited drag to y-axis only
- implemented ability to delete row by swiping left (not using Gestures). Did this by allowing movement along x-axis only for the dragging row, and computing if the touch-up occurred in the last 3/4 of the row.
@Eric Harlow Thanks for your reply. I've implemented the changes to allow dragging from anywhere, and also to only move along the y-axis (as other posters commented). I'm still having problems figuring out how to retain the state of the checkbox.
ReplyDeleteI made my own class to use instead of String in:
mContent = ArrayList (old)
mContent = ArrayList (Mine)
When I drop a dragged row, the onDrop method gets the row I'm moving, but inspecting the values, the checkbox state is still false.
I assume that when I check the checkbox, the value held in my class for that entry in the ArrayList is not being updated.
My problem is how to do this?
I'm by no means an experienced developer, so I hope you are able to assist me!
Thanks!
@Viraj Mody
ReplyDeleteCould you possibly post your modified version of the code? I am trying to do both of those things in my app, and seeing your solution would be much easier than trying to figure it out on my own...I don't have much experience with touch events.
@Neil Deadman Originally I had tried to put everything related to drag views into the DragListener, but in your case this doesn't work as well. A better solution for your case is to create an onClickListener and attach it to all of the CheckBoxes. One way to accomplish this would be to add the below member variable to DragNDropListActivity.
ReplyDeleteprivate OnClickListener checkBoxListener = new OnClickListener() {
public void onClick(View v) {
View view = (View)v.getParent();
int index = getListView().indexOfChild(view);
ListAdapter adapter = getListAdapter();
CheckBox checkBox = (CheckBox)view.findViewById(R.id.CheckBox01);
((DragNDropAdapter)adapter).updateItem(checkBox.isChecked(), index);
}
};
Note my onClick() assumes dragitem.xml is a LinearLayout with a CheckBox as a child. Add the onClickListener as a parameter to DragNDropAdapter's constructor. Also add the following bold lines in DragNDropAdapter's getView().
// Creates a ViewHolder and store references to the two children views
// we want to bind data to.
holder = new ViewHolder();
holder.text = (CheckBox) convertView.findViewById(mIds[0]);
holder.text.setOnClickListener(mCheckBoxListener);
mCheckBoxListener is just a member variable in DragNDropAdapter that stores the onClickListener from the parameter in the constructor.
// Bind the data efficiently with the holder.
ViewContent content = mContent.get(position);
holder.text.setText(content.text);
holder.text.setChecked(content.isChecked);
ContentView is just a class that holds the text and a checked state for a CheckBox. Sounds like you already have an equivalent class. The last thing you should need in DragNDropAdapter is
public void updateItem(boolean isChecked, int index) {
mContent.get(index).isChecked = isChecked;
}
and you should be good to go. I can email you the entire project if you run into trouble. Best of luck!
Thanks for this great example. I'm trying to modify this so that a user can edit the list by clicking on the items and selecting options through dialogs. So I've been able to get a concept working, except that the ListView will not update. If I step through the debugger, the item changes in the array and the dialog correctly gets the right item, but change does not show in the list on the screen. I believe that I need the notifyDataSetChanged() method, but I cannot figure out what to attach it to and where to do it. Can you help?
ReplyDeleteBelow is my modified code in DragNDropListActivity for onCreate() and the additional dialog (hopefully it's readable):
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mListContent.add("static1");
mListContent.add("static2");
mListContent.add("static3");
mListContent.add("static4");
setContentView(R.layout.dragndroplistview);
ArrayList content = new ArrayList(mListContent.size());
for (int i=0; i < mListContent.size(); i++) {
content.add(mListContent.get(i));
}
setListAdapter(new DragNDropAdapter(this, new int[]{R.layout.dragitem2}, new int[]{R.id.TextView01}, content));
ListView listView = getListView();
listView.setClickable(true);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView a, View v, int position, long id) {
tempselect = Long.toString(id);
selecteditem = Integer.parseInt(tempselect);
showDialog(1);
}
});
if (listView instanceof DragNDropListView) {
((DragNDropListView) listView).setDropListener(mDropListener);
((DragNDropListView) listView).setRemoveListener(mRemoveListener);
((DragNDropListView) listView).setDragListener(mDragListener);
}
}
public Dialog onCreateDialog(int id) {
switch (id) {
case 1:
tempstat = "changed";
mListContent.set(selecteditem, tempstat);
AlertDialog.Builder adb = new AlertDialog.Builder(this);
adb.setTitle("LVSelectedItemExample");
adb.setMessage("Selected Item is = " + selecteditem);
adb.setPositiveButton("Ok", null);
adb.show();
}
return null;
}
Never mind. I figured it out. I was only updating the array and not the content of the listview. Also figured out where to call notifyDataSetChanged(). I can post code if someone else is trying to do this.
ReplyDeleteHi Everyone, i'm just new to android. i been searching a grid layout that can drag and drop the item. It seems that Eric have the right one that i been looking for, but the problem is that it display in list can you gave me an example of displaying it in a gridview. thanks...
ReplyDeleteHi Jainey, I'm also looking for a grid layout that can drag and drop items. Have you find a solution in the meantime?
DeleteThanks
ReplyDeleteEric Harlow
How could I use this to extend what simple cursor adapter does? Right now i'm trying to replicate what simple cursor adapter does inside of DragNDropAdapter on top of the drag n drop function but that uses ViewBinder while yours is view holder.
ReplyDeleteI'm looking how I can make drag n drop using entries from a database and using a cursor rather than just static text. Any suggestions?
Does anyone already tried to update it so that it automatically creates a gap between 2 items while moving (like in the current music application)?
ReplyDeleteFor me it is a bit confusing where to drop the item now.
@Eric Harlow Sorry for disturbing for asking such a chilly matter, would you please give an example which support drag, scroll and drop in list view, i am a novice developer i try to modify music app but is not work but i understood your example. Thanks in advanced.
ReplyDeleteThis does not seem to work that well in a layout where the ListView (DragNDropListView) does not fill the whole display. For example i you have some other elements on the top of the display and this list should be shown beneath.
ReplyDeleteHas anyone experienced the same problem and have a solution?
This is great! Thanks!!
ReplyDeleteI've got this up and running in my app. Ideally, my app will allow users to choose items from different lists to decorate a background image.
Any way to drag items *out* of a list back to a previous view/screen?
Essentially I want the progression to be:
screen1>click menu>click button to show list of items>item appears back on screen1
Sorry if I'm not asking this right.
its really gr8 solution...
ReplyDeletethanks
Zahid Naqvi
zahidalinaqvi@gmail.com
This comment has been removed by the author.
ReplyDeletethanks.
ReplyDeleteCan anybody that has implemented the drag and scroll into this example post the source. I took it from the music app and the scrolling is workling, but if I try to drag an item and drop it to a position that was previously off the screen it crashes. So obviously I messed up somewhere and I cannot figure it out.
ReplyDeleteAlso when it creates the blank space to show where I was dragging from... it repeats that blank space every six items.
Building on Logan's change to allow onItemClick, I wanted to allow onItemClick, and also allow the user to start the drag from anywhere on the item, since using the icon is not always intuitive. Just a minor change to DragNDropListView's onTouchEvent (below) to hold off on setting the dragmode until the user has dragged the item far enough to know it's not just a click (which will almost always yield some move's as well). It would probably look better if you fine-tune the start condition a bit, right now it's looking for your finger to move onto an adjacent item.
ReplyDelete@Override
public boolean onTouchEvent(MotionEvent ev) {
final int action = ev.getAction();
final int x = (int) ev.getX();
final int y = (int) ev.getY();
switch (action) {
case MotionEvent.ACTION_DOWN:
mStartPosition = pointToPosition(x,y);
if (mStartPosition != INVALID_POSITION) {
int mItemPosition = mStartPosition - getFirstVisiblePosition();
mDragPointOffset = y - getChildAt(mItemPosition).getTop();
mDragPointOffset -= ((int)ev.getRawY()) - y;
}
break;
case MotionEvent.ACTION_MOVE:
int currentPosition = pointToPosition(x,y);
if (!mDragMode && (currentPosition != mStartPosition)){
mDragMode = true;
startDrag(mStartPosition - getFirstVisiblePosition(),y);
}
if (mDragMode)
drag(0,y);// replace 0 with x if desired
break;
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
default:
if (mDragMode){
mDragMode = false;
mEndPosition = pointToPosition(x,y);
stopDrag(mStartPosition - getFirstVisiblePosition());
if (mDropListener != null && mStartPosition != INVALID_POSITION && mEndPosition != INVALID_POSITION)
mDropListener.onDrop(mStartPosition, mEndPosition);
}
break;
}
if (!mDragMode)
return super.onTouchEvent(ev);
return true;
}
Thank you for the example, very demonstrative and understandable.
ReplyDelete@KZD76 Thank you I hope to have some time to create some more little projects like this.
ReplyDelete@Eric Harlow
ReplyDeleteHello Eric! I made some changes in your code (deleting from list, monitoring change event). Where can I publish it for you (if interested)?
@KZD76
ReplyDeleteI just pushed a repository on github that I hope to use when I start blogging again. If you can put it there. I will definitely look it over. TICEWidgets
@Eric Harlow Hi! I just sent you a pull message.
ReplyDeleteNice and easy way to drag and drop in list view.
ReplyDeleteCan you please suggest a way to scroll the list while dragging an item.
Thanks,
T
@Viraj Mody
ReplyDeleteCould you please post your modified version of the code? I am trying to do scrolling of list while dragging an item...I don't have much experience with touch events.
First off, this code is super helpful! I am in the process of writing my first app, so this question may be a little silly. I am loading the content of the list, then allowing the user modify the order, and then updating the list. When I come back to the same page on my app, I know see the list displayed twice: first in the new order and then in the original order. I am guessing that I need to clear the list view some how or possibly make use of onPause or onResume.
ReplyDeleteThe flow goes:
Main Page: Press -> "EditLineup"
-- Display DragNDropPage with starting lineup --
DragNDrop: Modify Lineup, then press "Save"
-- Display Main Page --
Main Page: Press -> "EditLineup"
-- Display DragNDropPage with new lineup and starting lineup --
Any help you could provide would be very helpful.
-----------------
Code snipit:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.dragndroplistview);
setListAdapter(new DragNDropAdapter(this, new int[]{R.layout.dragitem}, new int[]{R.id.TextView01},
Lineup.getPlayersNumbersAndNames()));
listView = getListView();
if (listView instanceof DragNDropListView) {
((DragNDropListView) listView).setDropListener(mDropListener);
((DragNDropListView) listView).setRemoveListener(mRemoveListener);
((DragNDropListView) listView).setDragListener(mDragListener);
}
Button save = (Button) findViewById(R.id.dragNdropList_save);
save.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
//Loop over all of the items in the list
// and save the current order of the list back into the Lineup
List tempLineup = new ArrayList(listView.getCount());
for(int i = 0; i < listView.getCount(); i++) {
tempLineup.add(listView.getItemAtPosition(i).toString());
}
Lineup.updateLineup(tempLineup);
//Go back to home screen
Intent myIntent = new Intent(v.getContext(), SBScorekeeperMain.class);
startActivityForResult(myIntent, 0);
}
});
}
Nevermind, I found that there is a bug somewhere in my updateLineup function such that it is storing the names twice.
ReplyDeletePhenomonal work! I have been searching around for a good drag and drop listview to use and you have the best model yet! Everyone elses I have tried has been buggy as hell
ReplyDeleteSuperb example! Keep up the good work. Thanks !!!
ReplyDeletethanks..
ReplyDeleteReally great work. What would be a great extension to this would be to use an ExpandableListView and be able to re-arrange the sub items. Does that sound doable?
ReplyDeleteSam
Thanks, it's one of the best tutorial.
ReplyDeletei like this site tutorials very much.
but can u confirm me how to handle this one by using extends Activity .
@Naveen I am not entirely sure what you are asking. Are you saying that you don't want to use the DragNDropListActivity class instead you want to have a DragNDropActivity class that is just an Activity not a ListActivity. Does my older article Experience - Configuring Android ListView help?
ReplyDeleteThis comment has been removed by the author.
ReplyDeleteHow can I change background color used during dragging?
ReplyDeleteI'm tryng to work this with more views. You drag an list item, and drop on a textview! any good idea of how to make this task?
ReplyDeleteThanks a lot, excellent example, helped me very much. But I still have a question: it is possible to create two lists in such a way that I can drag and drop between those lists using your code?
ReplyDeleteThanks.
Thank you for the useful example code, Eric. I've refactored it into a simpler form and templated it for arbitrary row data types. You will find here: http://www.superliminal.com/sources/SortableList.zip Just sub-class from the SortableListActivity class and implement the simple abstract methods. There's also a simple example class for String data.
ReplyDelete-Melinda Green
melinda@superliminal.com
Thank you, Mr Eric Harlow.
ReplyDelete@cutelyaware I looked at your modifications. I like the templated adapter. I don't know why I don't use something like that more often. Also thanks for the attribution in the source code. I appreciate that.
ReplyDeleteHi eric ,,
ReplyDeletei Am facing problem when i add a lot of items in listview and then when i try to rearrange i am not able to drag and drop to the items which are below
Melinda and Eric, thanks for great code.
ReplyDeleteI've added two features to make the list real usable for drag'n'drop. The code is here: http://thomas.ahle.dk/SortedList.tar.gz
I've implemented a "drop here" token, to make it more clear where you are going to drop, fixed a couple of bugs, and made it possible to drag to the bottom of the list to scroll it.
I hope it is as useful to you, as your work was to me.
Eric, perhaps you should post an update to the top of your site, so people coming in from StackOverflow or similar won't miss the updated solutions.
@Thomas DA
ReplyDeleteHi Thomas,
There is a problem with the link, would you mind fixing it?
@Thomas DA I am willing to post links in the article. And I enjoy the comments with code contributions. I tried to follow your link but got a 404 error. If you could repost it or email it to me. I will try to post it.
ReplyDeleteI've completed the code to drag and drop, with the 'Scrolling' ability:
ReplyDeletedownload the 'DragNDropListView' class to replace in the project, here:
http://www.filehosting.org/file/details/258354/DragNDropListView.java
@jano59
ReplyDeletei forgot:
to use the 'smoothScrollToPosition() ' function, you have to set the Android Properties of your project to Android 2.2
see:
http://imageshack.us/photo/my-images/690/android22.png/
@jano59
ReplyDeleteGreat! But it "Force Closes" when you try to drop an item in a position that you have reached through scrolling.
The fix:
private void startDrag(int itemIndex, int y) {
stopDrag(itemIndex);
View item = getChildAt(itemIndex);
draggedView = item;
[...]
private void stopDrag(int itemIndex) {
if (mDragView != null) {
if (mDragListener != null) {
Log.e("INDEX: " + itemIndex);
mDragListener.onStopDrag(draggedView);
[...]
Thank you all for your code, it's being very useful to me.
@jano59
ReplyDeleteWhen I replace the DragNDropListView with the one in http://www.filehosting.org/file/details/258354/DragNDropListView.java,
drop doesn't change anything anymore.
The list is still the same.
Do I miss something?
@Atomic
ReplyDeleteI've checked it again and it works on my NexusOne and the eclipse'avd, without any fix.
Proposing the upload of only one class is surely a mistake, i've surely modified more than that...i can't remember.
here is the entire project with the scrolling ability:
http://www.filehosting.org/file/details/261962/DragNDrop.rar
Atomic, in your project, does your adapter 'addItem()' via a doInBackground(String... params)
ReplyDeletein a AsyncTask thread?
if you use multi-thread process like this to publish a progress bar, for exemple, be aware to 'notifyDataSetChanged' by a Handler defined in your main ListActivity process in the function 'public void insertItem(int to, Object o)'...
@jano59
ReplyDeleteI haven't integrated it yet and test only with the example Activity provided.
This comment has been removed by the author.
ReplyDeletehere, the version of an automatic update when moving an item, with the scrolling ability.
ReplyDeletehttp://www.filehosting.org/file/details/263887/DragNDrop.rar
Ps: there is the '.apk' file in the bin folder if you just want to give a glance...
@Logan
ReplyDeleteHello, could you please post your example somewhere for the notifyDataSetChanged() please ? Thanks :)
This comment has been removed by the author.
ReplyDeleteThis comment has been removed by the author.
ReplyDelete@jano59
ReplyDeleteNo thanks... That's done ! I've changed ArrayList to ArrayAdapter and all worked fine :)
I've extended this custom DragAndDropListView to a custom DragAndDrop ExpendableListView.
ReplyDeleteIt tried to stay as close as possible to the former code.
I've just introduced my own way to use a holder in the BaseExpandableListAdapter since i've had to use two differents customViews,one for a group items, and one for child items.
Note that you have to expand yourself a non expanded group before dropping a child inside.
Note also that the code is not optimized to keep it a little more readable.
Download here:
https://sites.google.com/site/pharmaciefleury/folder/expDragAndDropP.1.0.rar
https://drive.google.com/file/d/0Bzadogwcq6SSNGMzYjYwZmYtNjYxYi00OWM0LTg1NmUtMDc0Y2U1ZDRlYjA2/view?usp=sharing
DeleteVery nice tutorial , I tried to make it work for preferences activity but I have and I have problems with cast exception please help me with this http://stackoverflow.com/questions/7582040/casting-issue-with-listview
ReplyDelete@jano59
ReplyDeleteI downloaded your example. Good! It works.
I found a small bug that if app would crash if the start drag point is coincidentally on the line between items. The fix is pretty simple.
Just disable mDragMode if position is invalid.
switch (action) {
case MotionEvent.ACTION_DOWN:
mStartPosition = pointToPosition(x,y);
if (mStartPosition != INVALID_POSITION) {
.......
}else
mDragMode=false;
@Tim Wu
ReplyDeletethx, one less bug.
Ready to download at:
https://sites.google.com/site/pharmaciefleury/folder/expDragAndDropP.1.1.rar
Thanks a lot for an easy, well explained, and working code !
ReplyDelete@jano59
ReplyDeleteThe link seems to be broken, do you have another link to get the code from?
Thanks in advance!!
Hi,
ReplyDeleteis there any chance that you publish the sources under a GPL license?
@Alb my code is licensed under the Apache License. Is there a particular reason why you would need GPL over Apache?
ReplyDelete@Eric Harlow
ReplyDeleteApache 2 and GPL 2 are not compatible [1]. As you are the owner of the sources you can distribute then under a dual license (for example), so anybody using a GPL2 license can import your code.
It will be great for me :) (and sure for others)
What do you think?
[1] http://www.gnu.org/licenses/license-list.html#apache2
@Alb
ReplyDeleteI was just trying to understand why you needed the GPL license. I think I figured it out with the Apache 2.0 and GPL 2.0 incompatibilities.
Yes, I am willing to dual license this code. Although I think I will do it on a per case instance. My email is eric dot b dot harlow at gmail let me know where to send a GPL 2.0 licensed copy of the same code that is linked to this article.
Hope this is helpful.
@jano59
ReplyDeleteI've added a feature to the simple (non-expandable) list that you posted a while back: The ability to enable or disable dragging.
I've made the following changes to DragNDropListView:
Add these lines anywhere:
boolean mDraggingAllowed = true;
public void setDraggingAllowed(boolean draggingAllowed) {
this.mDraggingAllowed = draggingAllowed;
}
public boolean isDraggingAllowed() {
return this.mDraggingAllowed;
}
Change the following lines in onTouchEvent:
if (action == MotionEvent.ACTION_DOWN && x < this.getWidth()/4) {
mDragMode = true;
}
to:
if (action == MotionEvent.ACTION_DOWN && x < this.getWidth()/4 && mDraggingAllowed) {
mDragMode = true;
}
Sorry about just posting the changes; I don't have a server on which to put the full source.
Thanks, everybody, for the good work. This has been a huge help to my project team.
G8 Tutorial ,
ReplyDeletePlease confirm me one think here , when we have lot of items in a list-view dragging top item to bottom then scroll-view not working or when dragging bottom to top then same cases dragging works but scrolling not work of that list adapter how to scroll that one , if one screen size item available then no issue, but more than one page data items then scroll not works give me way to handle that issue.
Please someone reply me , when dragging item then i want my scrollview work...How to handle that cases here
ReplyDelete@Greg
ReplyDeleteHello Greg,
ReplyDeletePlease help me,
I am facing same issue , i want to scroll list when dragging and dropping item on list here scroll not work please guide line me how to handle scroll here
i don't understand: there is a link of a version with the scrolling ability, among the posts upside.
ReplyDeleteIt works (i tried it with 250 items).
Try it:
http://www.filehosting.org/file/details/263887/DragNDrop.rar
Hello Greg,
ReplyDeleteThanks very much for sharing link.
I have downloaded this rar file and play app in mobile same issue here suppose i have 10 items in a list, i want darg 10 th item on position of 1st item dragging works but scroll to move bottom to top is not working dragging time same for Top to bottom dragging scroll not works so facing issue for replace that particular item on that index .
How to resolve that issue , i want when dragging and dropping item then same scroll move with that item movement .
Regards
Naveen Kumar
Hello Greg,
ReplyDeleteThanks very much it's working for 2.2 or 2.2+ version but
Here with 2.1 emulator version this method smoothScrollToPosition not working, when i am using emulator version 2.2 then it's work fine, Please confirm me how to resolve this issue:
Regards,
Naveen
Hello Greg,
ReplyDeleteWhen i am using this code
private void scrollList(int y) {
resetScrollBounds(y);
int height = getHeight();
int speed = 0;
if (y > mLowerBound) {
// scroll the list up a bit
speed = y > (height + mLowerBound) / 2 ? 16 : 4;
} else if (y < mUpperBound) {
// scroll the list down a bit
speed = y < mUpperBound / 2 ? -16 : -4;
}
if (speed != 0) {
int ref = pointToPosition(0, height / 2);
if (ref == AdapterView.INVALID_POSITION) {
//we hit a divider or an invisible view, check somewhere else
ref = pointToPosition(0, height / 2 + getDividerHeight() + 64);
}
View v = getChildAt(ref - getFirstVisiblePosition());
if (v != null) {
int pos = v.getTop();
setSelectionFromTop(ref, pos - speed);
}
}
}
private void resetScrollBounds(int y) {
int height = getHeight();
if (y >= height / 3) {
mUpperBound = height / 3;
}
if (y <= height * 2 / 3) {
mLowerBound = height * 2 / 3;
}
}
and calling on
case MotionEvent.ACTION_MOVE:
drag(0,y);// replace 0 with x if desired
//=================
scrollList(y);
//================
break;
then scroll works sometime but some time getting blank item and exceptions , Please help me or give me guide line how to run shared code for all emulator
Regards,
Naveen Shrivastva
Here
ReplyDeletecase MotionEvent.ACTION_MOVE:
drag(0,y);// replace 0 with x if desired
int mCurrentPosition=pointToPosition(x,y);
mDragListener.onDrag(x, y, this); //for convenience
if(mCurrentPosition>0){
///////////////////SCROLLING AREA
if((mCurrentPosition==getFirstVisiblePosition())){
try{this.smoothScrollToPosition (mCurrentPosition-1);
mDragListener.onStopDrag(getChildAt(mItemPosition)); }catch(Exception e){};}
if(mCurrentPosition==getLastVisiblePosition()&&(mCurrentPosition<this.getCount())){
try{this.smoothScrollToPosition (mCurrentPosition+1);
mDragListener.onStopDrag(getChildAt(mItemPosition));}catch(Exception e){};}
/////////////////////SLIDING AREA
if(mCurrentPosition!=mItemPosition){
mDropListener.onDrop( mStartPosition,mCurrentPosition);
mDragListener.onStopDrag(getChildAt(mItemPosition));
mItemPosition=mCurrentPosition;mStartPosition=mItemPosition;}
}
break;
Here 2.2 lower emulator is not able to recolonization for this.smoothScrollToPosition(pos)---method
How to resolve this issue on lower version android emulator
@Naveen Shrivastva
ReplyDeletefor android 1.5 may be this works: i don't know i can't bear waiting the launch in the AVD simulator (15minutes).
i removed the 'smoothScrollToPosition' function, and create a listener to use the 'setSelection' function.
try it...
DragAndDropWithScrollingAbilityInAndroid 1.5
Hello Greg,
ReplyDeleteThanks very much by heart..
changing method "this.smoothScrollToPosition(pos) to
setSelection(Pos) " now it's working fine, now i am able to drag and drop on any emulator version .
Regards,
Naveen Kumar
@Naveen Shrivastva
ReplyDeleteI'm not Greg.
:)
hi, all
ReplyDeletei have 2 activity.
(1)in activity A onCreate(), i fill all the data to ArrayList AL1, then inflate each item in the ArrayList into the screen.
(2) when i click a button on activity A, it goes to Activity B, in B i use exactly the same ArrayList in A to inflate ListView, then i drag and drop the ListView item in B to rearrange the order.
(3) now i want click a button in B to send back the "changed order" to A and display on the screen. how can i do it? thanks in advance.
jano59, hi can you upload again your DragAndDropWithScrollingAbilityInAndroid.rar, i need to download it.
ReplyDeletehello...I am adding two DragNDropListView list views in ma example when i try to do that nothing is displayed the list view becomes blank.Can you please help me out on this?can i add two instance of DragNDropListView in a same activity?
ReplyDeleteaniket, i think that this bug is healthy for you, let me explain.
ReplyDeleteFirst if you look at the object 'DragNDropListView' you can see that this a selfish one, justified here by the purpose of the example, to simplify things.
for instance, look at is xml declaration id:
android:id="@+id/android:list"
it monopolizes a non replicable id,because it is a ListActivity at the start, that uses this listview. So if you use a xml way to instantiate your multiple DragNDropListViews => bugs somewhere in your road...
Second, how will you DragNDrop with an object that manages just its own at the drop time...
you have to start from an Activity class, use a Inflater to inflates a sort of MainLayout, use a Inflater to inflates your two or three or more ListViews and append them to it, and manage your OnDrag or OnMove event at the level of this Layout level.
if it is healthy, it is because this selfishness will block when you'll want to drag from one listView and drop in the another, i think, in any case...sorry...
you need to manage the event at this upper level, the same level that avoids this bug of instantiations, in fact.
Maybe i'm wrong, i'm just a hobbyist, and i'm very often wrong...
one more thing... when you'll want to drag from one listView and drop in the another...
don't forget that:you'll need a function that verify where you drop, there is no available function in android, that looks for you what is below your moving itemView, to tell you which ListView is your destination ListView... To do that, take the position (x,y) and compare it to the coordinates top, bottom, left, right of the visible rect of each ListViews. So list them first, and verify that at each onMove events.
Does anyone have a copy of the method implementation, from Jano59's smooth scrolling example:
ReplyDeletesmoothScrollToPosition(mCurrentPosition-1); // android 2.2
I've downloaded the version for 1.5, and it has calls to the method commented out, and I'm trying to make the code smart enough to call the smooth scrolling if the API level is high enough, but I don't have the method implementation, and neither does Jano59.
PS, in the original sample, Eric is saving the DrawingCacheBackgroundColor in the onStartDrag method, and setting the list item's background color to this in the onStopDrag. The default color for a list item's view is Transparent, if you set the color to something other than that, it will prevent the list item from showing the Selected, Focused and Pressed states. In onStopDrag, just set the view's background color to Color.TRANSPARENT
Cheers!
found a copy on an another PC, this morning:
ReplyDeletehttp://www.filehosting.org/file/details/299207/DragAndDropWithScrollingAbilityInAndroid_1.5.rar
Hi Eric,
ReplyDeleteThanks for the article and simplified drag-n-drop utility!
I have customized it such that user can provide the dragger element, for more info and updated source checkout -
http://shravanmahankali.wordpress.com/2012/01/12/android-drag-n-drop-list-view/
Has android's drag and drop framework completely replaced the need for this article? Thoughts?
ReplyDeletei have got the code from here
ReplyDeletehttp://ericharlow.blogspot.com/2010/10/experience-android-drag-and-drop-list.html
it's very useful to me , but i have questions, how do i restore the new listview?
i mean first the listview is like this
a
b
c
after drag and drop
c
b
a
but if i quit this app and then start it later , it will still be -> a b c
i have some idea to use sql to save the listview id , so i can create table
with id 1 2 3 which with content a b c in database , and then call to listview , so i can use the above code to drag , after i drag listview become c b a ,but how to save the new sequences in database like id 1 2 3 with c b a ?
thanks for replying
You said "but if i quit this app and then start it later , it will still be -> a b c".
DeleteThis leads me to believe your adapter is not being updated. I assume you update the views in a DragListener. I update the adapter backing the list in a DropListener. My adapter is a CursorAdapter and is backed by a SQL database, so it is possible to do what you are thinking. Hope it turns out well, and Best of Luck.
@Eric As you mentioned it uses Apache 2.0 licensing. I tried to learn if i can use the code under Apache 2.0 in commerical product but i'm not sure about this. Can you please guide about this?
ReplyDeleteI am working on application for client. Application is planed to be published on android market where user can purchase.
Yes, Apache 2.0 licensing can be used within a commercial product, after all, android is licensed under Apache 2.0. Any attribution in the application would be greatly appreciated but isn't a requirement of the licensing.
DeleteThank you very much Eric for taking time to explain this.
ReplyDeletei have the same problem as SnowBear, Cant get the example to rember the new list position on exit.
ReplyDelete//--CP--
a
b
c
after drag and drop
c
b
a
but if i quit this app and then start it later , it will still be -> a b c
//--CP--
I belive i have to do somthing like this in the DragNDropListActivity.java?
private DropListener mDropListener =
new DropListener() {
public void onDrop(int from, int to) {
ListAdapter adapter = getListAdapter();
if (adapter instanceof DragNDropAdapter) {
((DragNDropAdapter)adapter).onDrop(from, to);
getListView().invalidateViews();
//Saving dragNDropList
mNewPositions = new String[adapter.getCount()]; //Initialize your new items storage
for(int i=0; i < adapter.getCount(); i++) {
//Implement here your logic for save positions
mNewPositions[i] = adapter.getItem(i).toString();
}
}
}
};
Can someone help me getting this to work?
WOW what an incredible post!
ReplyDeleteAs a new android programmer I can't answer you if the new android's framework has fixed this problem but your code works so who cares!
Working with your code makes me 3 questions:
-Is it possible to know how it was fixed the bug that said Viraj Mody? Because I tried all links posted but almost all has been deleted :(.
-Also I would like to know if you know how to change style to the textview only for some rows. I was thinking in having to diferents layer row but the result isn't correct...
-Finally, If add the drag option for all row as greg said android doens't roll the list. How can I implement both things?
Well thanks again. Because I have asked a lot of questions I let you a modification for your list providing from the list that I was using:
http://techdroid.kbeanie.com/2009/07/custom-listview-for-android.html
I have added an imagebutton in the row called pr1 for deleting the row just as the list before I was using.
For doing that in DragNDropAdapter.java in getview I've added:
(...)
holder.text = (TextView) convertView.findViewById(mIds[0]);
holder.del = (ImageButton) convertView.findViewById(R.id.pr1);
(...)
holder.text.setText(mContent.get(position));
holder.del.setFocusableInTouchMode(false);
holder.del.setFocusable(false);
holder.del.setOnClickListener(this);
holder.del.setTag(mContent.get(position));
Class viewholder now it's:
static class ViewHolder {
TextView text;
ImageButton del;
}
also add this new method:
@Override
public void onClick(View view) {
mContent.remove(view.getTag());
notifyDataSetChanged();
}
and implement OnClickListener to the baseadaptor.
Question 1:
ReplyDeleteJano59 files but is not as smooth as would like to be and margins are wrong.
Question 3:
private static long lastTouchTime = -1;
and inside onTouchEvent replace:
if (action == MotionEvent.ACTION_DOWN) {
if (System.currentTimeMillis() - lastTouchTime < 750) {
mDragMode = true;
}
lastTouchTime = System.currentTimeMillis();
}
you cheated (a little). instead of using x < this.getWidth()/4, it would be better to do x < ImageView01.getRightEdge(); (when handling the touch event, and my function call may be off a little from the actual function's name)
ReplyDeletethis makes sure that the user actually dragged the button, not some area on the left fourth of the screen.
Great example though, this helped a lot.
Awesome work! I have a question though. In my ListActivity, I am trying to use the registerForContextMenu(listview) and I have a method
ReplyDelete@Override
public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.ContextMenuInfo menuInfo) {
AdapterView.AdapterContextMenuInfo info = null;
try {
info = (AdapterView.AdapterContextMenuInfo) menuInfo;
int position = info.position;
@SuppressWarnings("unchecked")
ArrayAdapter adapter = (ArrayAdapter)getListAdapter();
selectedPageName = adapter.getItem(position);
menu.add(ContextMenu.NONE, ContextMenu.NONE, ContextMenu.NONE, "Delete");
} catch (ClassCastException e) {
Log.e(MY_DEBUG_TAG, "bad menuInfo", e);
return;
}
}
But the context menu doesn't come up. I am using the same code on other ListActities I have and it works on those, so I am wondering if there is something unique about this list such that context menus won't work???
I was able to get around this problem by implementing the onCreateContextMenu and onClickMenuItem methods for each row view as follows:
Delete// Register context menu handling here because registerForContextMenu doesn't seem to work at the
// ListView level with the DragNDrop implementation
textView.setOnCreateContextMenuListener(new OnCreateContextMenuListener() {
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
activity.onCreateContextMenu(menu, v, menuInfo) {
menu.add(0, v.getId(), 0, "Delete");
menu.getItem(0).setOnMenuItemClickListener(new OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
delete(position);
notifyDataSetChanged();
return true;
}
});
}
});
I mean I added this code inside the getView(...) method of the list adapter.
DeleteHello,
ReplyDeleteI'm using this code for my listView (which is composed of an EditText and a Checkbox) and for some reason, I'm not able to get the ACTION_DOWN event.
While debugging, I do get 2 ACTION_MOVE events followed by an ACTION_UP event (when my finger scrolls a bit down on an item) but the ACTION_DOWN event isn't registered.
Can someone think of a reason for this to happen?
* Thanks a lot for posting this code. It's a great help.
A much more likely case is your EditText which is a TextView is consuming the event in it's onKeyDown() and returning true to stop it from propagating up to your listView.
DeleteThis may be a long shot, but here is an idea. In your AndroidManifest.xml Do you happen to set a min sdk and/or target sdk like this . I wrote this back when android 1.6 was the most popular sdk and I had difficulties handling differences btw pre and post 2.0 version of the sdk.
ReplyDeleteuses-sdk android:targetSdkVersion="8" android:minSdkVersion="8"
DeleteYes, I am using SDK 13:
Deleteuses-sdk android:minSdkVersion="13" /
Do you think I can still use your library in this case?
I don't see any reason why it shouldn't work with SDK 13 although I have never tested it myself. I am still guessing a ui component is consuming your ACTION_DOWN event.
DeleteI do have an OnKeyListener defined for my EditText but it always returns false for ACTION_DOWN events:
DeleteviewHolder.text.setOnKeyListener(new OnKeyListener() {
public boolean onKey(View v, int keyCode, KeyEvent keyEvent) {
EditText et = (EditText) viewHolder.text;
TodoListItem item = (TodoListItem) viewHolder.text.getTag();
if (keyEvent.getAction() == KeyEvent.ACTION_DOWN) {
return false;
}
int index = todoList.indexOf(item);
int cursor = et.getSelectionStart();
String curItemStr = et.getText().toString();
switch (keyCode) {
case KeyEvent.KEYCODE_ENTER:
if (cursor != curItemStr.length()) {
item.setString(
et.getText().toString()
.substring(0, cursor - 1), 0);
}
insert(new TodoListItem(et.getText().toString()
.substring(cursor, curItemStr.length()), false,
curTask.getId()), index + 1);
tasksLayout.refreshTasksViews();
return true;
case KeyEvent.KEYCODE_DEL:
if (curItemStr.isEmpty()) {
remove(item);
if (index != 0) {
EditText etUpper = (EditText) getView(index - 1,
null, null).findViewById(R.id.editText);
etUpper.requestFocus();
etUpper.setInputType(0);
}
tasksLayout.refreshTasksViews();
if (todoList.size() == 0) {
emptyListTextView.setVisibility(View.VISIBLE);
}
return true;
}
break;
default:
break;
}
return false;
}
});
Hi again,
DeleteAfter getting a hint from NeTeInStEiN in StackOverflow (link below), I managed to get it to work.
What needed to be done is to implement the onInterceptTouchEvent() to return super.onInterceptTouchEvent().
http://stackoverflow.com/questions/9773855/android-listview-ontouchevent-doesnt-give-action-down/10006097#10006097
Thank you! Got it going with little fuss (the manifest omission wasn't a problem). Good work--can't wait to dive into the code.
ReplyDeleteAnother question,
ReplyDeleteNow I can dragNdrop, but the dragView isn't shown on the list, but rather on another part of the screen (left from the listView). It seems the y coordinates are right but the x coordinates are all shifted.
Any idea why this might happen?
Thanks a lot,
Yoel
Nice post!
ReplyDeleteCould someone to post a new link to download DragAndDropWithScrollingAbilityInAndroid_1.5.rar?
Thanks.
You legend. Thanks!
ReplyDeleteHi Eric. This is some great stuff, and obviously has helped a ton o people. Unfortunately, I learned of your project too late into my own implementation of a drag-sort ListView. I handle some features that yours doesn't, so I'm thinking collaboration possibilities. I'd love for you to try mine out: https://github.com/bauerca/drag-sort-listview. There are a bunch of demos that can be up and running quite quickly.
ReplyDeleteI do not think the Android Drag/Drop framework usurps a good Drag/Drop ListView (DDLV) implementation because the framework does not alleviate the complicated (in my experience) logic in a DDLV. That said, a new/updated DDLV should probably use the framework for some key features like drawing the floating/dragging View and grabbing drag events. The difficulties within onDrag callbacks in the framework will be the same as they are in the onTouchEvent method we use :)
Hi folks,
ReplyDeleteIs there a new method with Android Drag/Drop framework to implement a Draggable List view (for reordering of items within the list) or is it best to keep the implementation the author provides?
Just wanted to thank you! Your example helped me learn quite a bit. I was able to extend your design for my needs.
ReplyDeleteThanks again.
This comment has been removed by the author.
ReplyDeleteThis comment has been removed by the author.
ReplyDeleteThis comment has been removed by the author.
ReplyDeleteDoes anyone have a working download link for the implementation that supports scrolling? filehosting links die way too fast. None of the links is working.
ReplyDeleteThanks
This is great example thank you for sharing, but I want the listview in the sections (like to add headers in betn) and dont want one sections List Item to be dragged to other sections. How Would I achieve this functionality by using this code? Anyone please help me.
ReplyDeleteThank you.
Can Anybody please solve my above problem??
ReplyDeleteAlso there is a bug in the code, When I drag drop items contineously the list item which was dragged get disappered suddenly. What could be the problem??
ReplyDeletelinks:
ReplyDeletehttps://sites.google.com/site/pharmaciefleury/folder/DragAndDropWithScrollingAbilityInAndroid_1.5.rar
and
https://sites.google.com/site/pharmaciefleury/folder/DragNDropWithScrollingAbility.rar
Maybe it still interests someone...
but i've seen some news recently on the site android developers:
public final boolean startDrag (ClipData data, View.DragShadowBuilder shadowBuilder, Object myLocalState, int flags)
Since: API Level 11
and this:
http://developer.android.com/guide/topics/ui/drag-drop.html
Hi! Your project is very useful and I want to thank you. Here is an example of what I've done but on Android: http://jqueryui.com/sortable/
ReplyDeleteMy source code works right if you're scrolling, so I want to share with all of you - here's the link: http://www.4shared.com/zip/sRdXNRfr/SortableListView.html
It's just the ListView class; If you have any questions, please ask! onChangePosition() function have to refresh the listview but before that you need to call something like that:
public boolean dragAndDropPositionsChange(int startPos, int endPos){
if(startPos < 0 || endPos < 0){
return false;
}
Cursor cursor = getSituationsBetweenPositions(startPos, endPos);
if(startPos < endPos){
changePosition(cursor, -1);
cursor.moveToLast();
}else if(startPos > endPos){
changePosition(cursor, 1);
cursor.moveToFirst();
}
long sitId = cursor.getLong(cursor.getColumnIndex(TABLE_SITUATION.ID));
ContentValues value = new ContentValues();
value.put(TABLE_SITUATION.POSITION, endPos);
db.update(TABLE_SITUATION.SQL_TABLE_NAME, value, TABLE_SITUATION.ID
+ "=" + sitId, null);
cursor.close();
return true;
}
to work properly: you need to change positions of the 2 rows. In my case I use custom SimpleCursorAdapter, so I work with cursor. If you don't work with cursor in your adapter, it should be much easier!
You need to add this after you create bitmap with the drawingcache in startDrag() method:
ReplyDeleteitem.destroyDrawingCache();
If you don't have this in your code, next time when you drag from the same row when you dragged first, you'll see the last bitmap instead of the bitmap of the current row in your listview.
This comment has been removed by the author.
ReplyDeleteHi, guys! Thanks to Eric for his great job, but I`ve got one bug...
ReplyDeleteIf I dragged and dropped listview item (for example, from position 4 to position 3) and after that I try drag new listview item at position 4, but in startDrag I`ve got an old reference to view (when call View item = getChildAt(itemIndex);) and I`m dragging an old view (early it was at 4 position, now it is on 3 position). Maybe somebody could help me to fix this bug?
It is only reproduced on Android 4.1 or higher...
Alex Zezekalo:
ReplyDeletei think it's a common bug for those who doesn't care about listeners created in the main activity thread. Be aware to work only whith listeners, and particuliary those created in the main activity thread since only this one holds all up-to-date variables...
if it doesn't solve your problem, it is a good advise anyway ;)
Thank you for this code, it works great! Does anyone know if the new order can be stored once the user goes back from the screen to another screen? So if it starts as Value1,Value2,Value3 and the user changes to Value2,Value1,Value3 I would store this value? Thanks.
ReplyDeleteEric, this is a wonderful example and I thank you for it, but what I would really like is someone to explain it to me, how the various classes fit together. I'm a beginner android/java programmer and it's hard in the beginning to think in java. Maybe you don't have the time but maybe one of your readers will take it on. I am not complaining but it would have been nice if there were more comments in the code.
ReplyDeleteCheers,
Jacques
Etes-vous Français, Mr CHAURETTE?
DeleteThis comment has been removed by the author.
ReplyDeleteGreat job Eric
ReplyDeleteI had some problem with preview image, after moving an item i got image of previous item in that place.
Fixed setting
item.setDrawingCacheEnabled(false);
after getting the bitmap in startDrag
Now i have problem with checkboxes, i think you have a fully functional example, can you post it
Good example.How do i incorporate with this list into custom list?
ReplyDeleteHelped a lot! Weird we need this constructs still in 2013, but here we are. ^^
ReplyDeleteThank you very much!
Great tutorial for drag and drop & most important thing very quick support.
ReplyDeleteThanks, all of this group membership.
Here i found a bug, what if i need to insert my list view in a scrollview inside a linearlayout with other Ui controlls.
ReplyDeleteIt will no longer move!!
Also if i use this by setting the background of my whole list item, it is(the dragger) not getting the touch.
DeleteHi @Eric Harlow,
ReplyDeleteThe application works simply superb.. I am currently on a project where I have to implement this functionality and when exit it should save the order by which I have changed....in the earlier version of the project my friend we able to move the text and save it with the help of a button , but now we want to implement the drag and drop... It would be a great if u help me..
Hi @Eric Harlow,
ReplyDeleteThanks for your post, it is very useful.But when i set target SdkVersion upper 8 in Menifest.xml then a great problem arise.currently i am using DragNDrop list under a Fragment and Google API 4.1.2, target SdkVersion 8 and it works properly.
The problem is that in SdkVersion upper 8, when i drag any value and drop to another position, system replace it properly but when i longpressed or drag on the new replaced value then the item show the previous value instead of the replaced new one.after some drag and drop actions, when i dragged any value it always show the previous value but if i drop item then it shows the exact value.
pls reply your concern about it.
ReplyDeleteGreat example and discussion thread.
ReplyDeleteWhat is easy way to keep the order persistent? E.g. User changes order of list by dragging, exits and re-starts the application. He should not see the list in new order.
Sorry for the type - *He should now see the list displayed as per new order.
DeleteHi Eric,
ReplyDeleteI have a great inspiration from your project and want to port your project to Xamarin Android. I'm asking if you don't mind, may I put my project on github (of course I will indicate the origin project and idea is from you)?
Thanks!
Jesse
Greate job and very useful example !
ReplyDeleteI have the same problem here as helal khan:
When I dragged & dropped an item to a new position, it was replaced properly. But after that, when I tried to drag that item again, the previous item in that position was shown. This problem could be recovered if I put the App into background and then put it back again.
After some searchings, it seems that the views were not invalidated until the List Acvitiy paused (i.e. put into background). Does anyone have ideals on how to solve this problem ?
This problem occurs when running the App in my Galaxy phone, but no problem in Emulator.
Thank you very much !
=> I Am Arash ! not ازش
ReplyDelete@EricHarlow
I found a problem in your code that i will be thankful if you help me to solve it.
imagine i change the position of "item 7" and "item 6" by Drag n Drop . now when i select "item 6" (which is last item now) to change its position again, its name changes to "item 7" !!
I am really confused and any I will appreciate any help. thanks
Hi Eric,
ReplyDeleteGreat work rocks........I t will helped me a lot for my project.
Hi,
ReplyDeleteI required one weird thing. i.e. I don't want to support/do sorting of first 3 items, it that possible by this listview ?
How scroll listview?
ReplyDeleteNice example but only the text becomes a little bit blurry while you drag the items around. If you drop the items the text changes back to normal. How to fix this? I also don't like the use of generated colors!!
ReplyDeleteReally nice example. Nicely written as well.
ReplyDeleteHi, thanks for this project, it did help me out!
ReplyDeleteHowever, I noticed a minor bug - while dragging the item around, if it hasn't been invalidated before getting the drawing cache, it sometimes keeps and old cache (I guess it depends on the refresh rate of the app or the events, or whatever). I fixed it by just adding
item.invalidate();
on line 123 of DragNDropListView.java, just before enabling the drawing cache.
Besides, like other comments say, I didn't find the drop very intuitive regarding the destination position of the item, but I didn't go into preview while dragging or anything as complicated. Instead I just use the corners of the dragView as Y coordinate for the mEndPosition. I use the upper corner when moving down and the lower corner when moving up. This way the item is positioned between the two existing items behind
I can post a bit of code if anyone is interested.
This is a really helpful piece of code you put out for others to learn from and make use of. Thanks
ReplyDeleteI have added it as a preferences activity and my next attempt is to get text and image for each row. My questions is which way would be better to add the two parts, as sending two separate lists into the DragNDrop activity, or sending a HashMap arrayList to the activity. Either way I will need to make some changes to the DragNDrop code to get it is handle the two parts, but which one will be easier or work better. I have made an attempt at the HashMap method with two Strings (will change to image after I get it to work) but the list just has false for both text items in that attempt. Not sure where the problem is because I see the list has been passed in correctly and both parts of each item are there, they just don't make it into the dragitem elements.
Thanks
This comment has been removed by the author.
ReplyDeleteIt is really a great work and the way in which u r sharing the knowledge is excellent.Thanks for helping me to understand basic concepts. As a beginner in android programming your post help me a lot.Thanks for your informative article.
ReplyDeleteAndroid Training in velachery | Android Training institute in chennai
Very innovative information
ReplyDeleteHadoop Training in Bangalore
Hadoop Training in kalyan Nagar
python Training in Bangalore
amazon quickbooks integration
ReplyDeleteVery Nice!!! Blog!!!
ReplyDeleteIEEE 2019 IOT Projects
IEEE 2019 ME Projects
IEEE 2019 MTech Projects
IEEE 2019 Robotics Projects
IEEE 2019 Electrical Projects
Final Year Project Training Institutes for B.E / B.Tech Engineering students in your area, find the Best Project Centers in Chennai, IEEE 2019 to 2020.
ReplyDeletevlsi projects in chennai
gsm and gps projects in chennai
vlsi mini projects in chennai, vlsi mini project centers in chennai, vlsi mini project centres in chennai
UV Gullas Medical College is the World's Premier Research Institution Since 1919 in Philippines.
ReplyDeleteUV Gullas College of Medicine
We provide the best projects for all students.
ReplyDeleteCSE, ECE, Engineering and Diploama Projects in Chennai
1croreprojects offers the best 2019 robotics projects chennai for final year students.
ReplyDeleteVisit :-
https://meprojectschennai.co.in
Phone : +91 97518 00789 / +91 77081 50152
ms project centers in chennai, ms projects chennai 2018-2019 in PDF format was created and prepared for 1crore project. MCA, ms project centers in chennai, IEEE project in chennai, India. Engineering students, MCA, MSC.
ReplyDeleteSnapdeal Winner List 2020 here came up with an Offer where you can win Snapdeal prize list by just playing a game & win prizes.
ReplyDeleteSnapdeal winner name also check the Snapdeal lucky draw
Snapdeal Winner List 2020 here came up with an Offer where you can win Snapdeal prize list by just playing a game & win prizes.
ReplyDeleteSnapdeal winner name also check the Snapdeal lucky draw
thanks for sharing this nice infoamtion..i really enjoyed to read your information.learn bench india is the best project center in chennai..
ReplyDeleteto know more about this best project center in chennai
best final year project center in chennai
best final year ieee project center in chennai
best embedded project center in chennai
It is amazing and wonderful to visit your site.Thanks for sharing this information,this is useful to me...
ReplyDeletehttp://chennaitraining.in/salesforce-admin-training-in-chennai/
http://chennaitraining.in/scrum-master-training-in-chennai/
http://chennaitraining.in/seo-training-in-chennai/
http://chennaitraining.in/tally-training-in-chennai/
http://chennaitraining.in/splunk-training-in-chennai/
http://chennaitraining.in/servicenow-training-in-chennai/
Amazing post, Thank you for presenting a wide variety of information that is very interesting to see in this artikle.
ReplyDeleteHome elevators Melbourne
Home lifts
Nice Blog..Appreciate your efforts in writing this ...
ReplyDeleteArtificial Intelligence Training in Chennai
Best Artificial Intelligence Training in Chennai BITA Academy
artificial Intelligence certification training in chennai
artificial Intelligence training institutes in chennai
artificial Intelligence course in chennai
artificial Intelligence training course in chennai
artificial Intelligence course in chennai with placement
artificial Intelligence course fees in chennai
AI Training in Chennai
artificial Intelligence training in omr
artificial Intelligence training in velachery
Best artificial Intelligence course fees in chennai
artificial Intelligence course in omr
artificial Intelligence course in velachery
Best artificial Intelligence course in chennai
Amazing post, Thank you for presenting a wide variety of information that is very interesting to see in this article. Visit our website
ReplyDeleteHome elevators UAE
Home elevators Malaysia
Home lifts Melbourne
Home lifts
Amazing post, Thank you for presenting a wide variety of information that is very interesting to see in this article. automatic gates
ReplyDeletevacuum elevators
It was wondering if I could use this write-up on my other website, I will link it back to your website though.Great Thanks
ReplyDeleteOracle Training | Online Course | Certification in chennai | Oracle Training | Online Course | Certification in bangalore | Oracle Training | Online Course | Certification in hyderabad | Oracle Training | Online Course | Certification in pune | Oracle Training | Online Course | Certification in coimbatore
Nice Blog..Thanks for sharing..
ReplyDeleteBig Data Training in Chennai
Big Data Course in Chennai
Big Data Analytics Training and Placement
Big Data Training Online
Big Data Training in Velachery
Big Data Analytics Training in Chennai
iOS Training in chennai
iOS app development course
iOS course syllabus in BITA Academy
mobile app Training in chennai
Thanks for the article. Its very useful. Keep sharing. AWS training in chennai | AWS online course | AWS course online
ReplyDeletebangalore to chennai cab
ReplyDeletehyderabad to bangalore cab
bangalore to hyderabad cab
kochi to chennai cab
Mobile app development company in UK , thanks for the content
ReplyDeleteAccurate share market tips covering NSE, BSE and MCX. Stock market traders dealing in Indian share market can get Equity tips, future trading tips, nifty tips, options tips and commodity tips from sharetipsinfo for huge returns. Sharetipsinfo assures high returns on low investments.
ReplyDeleteThanks for sharing this.It is a best post.project centers in chennai|project centers in vadapalani
ReplyDelete