Android OnDragListener - 多次触发ACTION_DRAG_ENDED

时间:2016-04-29 18:58:19

标签: android drag-and-drop ontouchlistener

我正在使用自定义行和自定义适配器创建列表视图。我已将OnTouchListener和OnDragListener附加到列表视图中的每个视图。

如果drop结果为true,我正在更新基础数据(拖动的视图在列表视图的范围内被删除)

对于有效和无效的丢弃,ACTION_DRAG_ENDED案例会触发4次,但我不知道原因。有人可以告诉我为什么会这样吗?

我的听众代码如下。

@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;
        }

2 个答案:

答案 0 :(得分:1)

对于您已将拖动侦听器附加到的每个视图,

ACTION_DRAG_ENDED将触发一次。 ACTION_DRAG_STARTED也是如此。因此,如果将onDragListener附加到4个视图,则这些事件将触发4次。

答案 1 :(得分:0)

private bool wasShown;

在 ontouch 事件中做 false。

wasShown = false;

检查 if 并在 ACTION_DRAG_ENDED 中第一次运行时将其设置为 true。

if (!wasShown){
wasShown = true;
...
}