Reputation: 163
I'm making a list view with custom rows and custom Adapter. I've attached an OnTouchListener and OnDragListener to each view in the list view.
I'm updating the underlying data if the drop result is true (the view being dragged is dropped within the bounds of the list view)
The ACTION_DRAG_ENDED case fires 4 times for both valid and invalid drops but I don't know why. Can someone please tell me why this is happening?
My code for the listeners is below.
@Override
public View getView(final int position, View convertView, final ViewGroup parent) {
LayoutInflater inflater = LayoutInflater.from(getApplicationContext());
if (convertView == null) {
convertView = inflater.inflate(R.layout.lv_item_stage, parent, false);
}
//setting text/images for the view
convertView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
START_POS = position;
ClipData data = ClipData.newPlainText("", "");
View.DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(view);
view.startDrag(data, shadowBuilder, view, 0);
view.setVisibility(View.GONE);
return true;
} else {
return false;
}
}
});
convertView.setOnDragListener(new View.OnDragListener() {
@Override
public boolean onDrag(final View v, DragEvent event) {
switch (event.getAction()) {
case DragEvent.ACTION_DRAG_ENTERED:
AbsListView.LayoutParams params = new AbsListView.LayoutParams(v.getWidth(), v.getHeight()*2);
if(position > START_POS){
//view dragged downwards
moveData(START_POS, position);
((LinearLayout) v).setGravity(Gravity.TOP);
}
else{
//view dragged upwards
moveData(START_POS, position);
((LinearLayout ) v).setGravity(Gravity.BOTTOM);
}
v.setLayoutParams(params);
START_POS = position;
break;
case DragEvent.ACTION_DRAG_EXITED:
//go straight into ACTION_DROP case (resize view to original size)
case DragEvent.ACTION_DROP:
v.setLayoutParams(new AbsListView.LayoutParams(v.getWidth(), v.getHeight()/2));
break;
case DragEvent.ACTION_DRAG_ENDED:
//update list view if drop valid (inside list view)
if (event.getResult()){
Log.d("listView", "result = TRUE");
updateListView(tempData);
}
else{
Log.d("listView", "result = FALSE");
}
final View droppedView = (View) event.getLocalState();
droppedView.post(new Runnable() {
@Override
public void run() {
droppedView.setVisibility(View.VISIBLE);
}
});
break;
default:
break;
}
return true;
}
});
return convertView;
}
Upvotes: 2
Views: 1189
Reputation: 850
private bool wasShown;
Do false in the ontouch event.
wasShown = false;
Check with if
and set it to true the first time it runs in ACTION_DRAG_ENDED.
if (!wasShown){
wasShown = true;
...
}
Upvotes: 0
Reputation: 11
ACTION_DRAG_ENDED will fire one time for each view that you have attached the drag listener to. The same is true for ACTION_DRAG_STARTED. Therefore, if you attached the onDragListener to 4 views, these events will fire 4 times.
Upvotes: 1