拖放仅适用于第一个

时间:2018-11-25 09:50:33

标签: android user-interface

我有一个节点图和一个圆圈,可以使用拖放操作在节点周围移动。但是,在使用节点并移动了圆之后,除非我旋转屏幕并重置所有内容,否则无法再将其移回同一节点。为什么会这样?

第二,从实用的角度来看,每次成功删除后我是否需要重新创建使用过的组件?或者该如何解决此问题?

我正在使用观察对象来更新UI:

private void handleObservedCheckers() {
    mainViewModel.checkerLiveData.observe(this, new Observer<Collection<Checker>>() {
        @Override
        public void onChanged(@Nullable Collection<Checker> checkers) {
            if (checkers == null)
                return;
            Log.d(TAG, checkers.toString());
            for (Checker checker : checkers) {
                CheckerView view = (CheckerView) nodeMap.get(checker.getPosition());
                view.invalidate();
                if (checker.getColor() == Color.RED) {
                    view.paintRed();
                    view.show();
                }
                else if (checker.getColor() == Color.BLUE) {
                    view.paintBlue();
                    view.show();
                } else {
                    view.hide();
                }
                view.draggable = checker.isDraggable();
                //view.invalidate();
            }
        }
    });
}

然后在create上创建视图组件

private View createChecker(int x, int y, int size, Position position) {
    final CheckerView view = new CheckerView(this, x, y, size, position);
    view.show();
    view.draggable = false;
    // Maps the view to the given position
    nodeMap.put(position, view);
    checkerViewList.add(view);
    Log.d(TAG, "created: " + view.toString());

    view.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            if (view.draggable && event.getAction() == MotionEvent.ACTION_DOWN) {
                // Save the position as clip data to be retrieved on drop
                ClipData.Item item = new ClipData.Item("" + view.position);
                ClipData data = new ClipData("", new String[]{ClipDescription.MIMETYPE_TEXT_PLAIN}, item);
                // Start drag
                View.DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(view);
                view.startDragAndDrop(data, shadowBuilder, view, 0);
                return true;
            } else {
                return false;
            }
        }
    });
    view.setOnDragListener(new View.OnDragListener() {
        @Override
        public boolean onDrag(View v, DragEvent event) {
            switch (event.getAction()) {
                case DragEvent.ACTION_DRAG_STARTED:
                    return true;
                case DragEvent.ACTION_DRAG_EXITED:
                    return true;
                case DragEvent.ACTION_DRAG_LOCATION:
                    return true;
                case DragEvent.ACTION_DRAG_ENTERED:
                    return true;
                case DragEvent.ACTION_DROP:
                    Log.w(TAG, "dropped");
                    // get stored position inside clip data if any exists
                    String data = (String) event.getClipData().getItemAt(0).getText();
                    if (!data.equals("")) {
                        mainViewModel.moveChecker(Position.valueOf(data), view.position);
                    } else {
                        mainViewModel.placeChecker(view.position);
                    }

                    return true;
                case DragEvent.ACTION_DRAG_ENDED:
                    return true;
                default:
                    return true;
            }
        }
    });
    return view;
}

我更改为在每个周期重绘,这一次,我不断得到“报告丢弃结果:false”。 (参考:https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/view/ViewRootImpl.java

1 个答案:

答案 0 :(得分:0)

将拖动侦听器附加到与触摸列表器相同的组件上(用于阴影拖动)的问题是,它似乎只能将液滴注册到自身上...