android - 将 Listview 项目拖放到另一个项目中

标签 android android-listview drag-and-drop

我有一个包含不同项目类型的 ListView :标题、文件夹和文件,如下所示:

enter image description here

现在我想实现拖动文件项并将其放入文件夹项并获取源位置和目标位置。我不想像某些拖动排序 ListView 库那样在拖动时更改目标位置(重新排列)。

有什么建议可以入手吗?

最佳答案

ListView 切换到 RecyclerView 将使事情变得容易得多。

您可以在 Styling Android 上找到整篇文章和整个代码 here.

此代码使用 OnItemTouchListener 来检测何时应拖动项目。 RecyclerView 上方有一个 ImageView,其中包含正在移动的项目的图像以廉价地为其设置动画。

OnItemTouckListener(DragController.java):

public class DragController implements RecyclerView.OnItemTouchListener {
    private RecyclerView recyclerView;
    private ImageView overlay;
    private final GestureDetectorCompat gestureDetector;

    private boolean isDragging = false;

    public DragController(RecyclerView recyclerView, ImageView overlay) {
        this.recyclerView = recyclerView;
        this.overlay = overlay;
        GestureDetector.SimpleOnGestureListener longClickGestureListener = new GestureDetector.SimpleOnGestureListener() {
            @Override
            public void onLongPress(MotionEvent e) {
                super.onLongPress(e);
                isDragging = true;
                dragStart(e.getX(), e.getY());
            }
        };
        this.gestureDetector = new GestureDetectorCompat(recyclerView.getContext(), longClickGestureListener);
    }

    @Override
    public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
        if (isDragging) {
            return true;
        }
        gestureDetector.onTouchEvent(e);
        return false;
    }

    @Override
    public void onTouchEvent(RecyclerView rv, MotionEvent e) {
        int x = (int) e.getX();
        int y = (int) e.getY();
        View view = recyclerView.findChildViewUnder(x, y);
        if (e.getAction() == MotionEvent.ACTION_UP) {
            dragEnd(view);
            isDragging = false;
        } else {
            drag(y, view);
        }
    }

开始和结束拖动(DragController.java):

private boolean isFirst = true;
private static final int ANIMATION_DURATION = 100;
private int draggingItem = -1;
private float startY = 0f;
private Rect startBounds = null;

private void dragStart(float x, float y) {
    View draggingView = recyclerView.findChildViewUnder(x, y);
    View first = recyclerView.getChildAt(0);
    isFirst = draggingView == first;
    startY = (y - draggingView.getTop());
    paintViewToOverlay(draggingView);
    overlay.setTranslationY(y - startY);
    draggingView.setVisibility(View.INVISIBLE);
    draggingItem = recyclerView.indexOfChild(draggingView);
    startBounds = new Rect(draggingView.getLeft(), draggingView.getTop(), draggingView.getRight(), draggingView.getBottom());
}

private void drag(int y, View view) {
    overlay.setTranslationY(y - startY);
}

private void dragEnd(View view) {
    overlay.setImageBitmap(null);
    view.setVisibility(View.VISIBLE);
    view.setTranslationY(overlay.getTranslationY() - view.getTop());
    view.animate().translationY(0f).setDuration(ANIMATION_DURATION).start();
}

private void paintViewToOverlay(View view) {
    Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(bitmap);
    view.draw(canvas);
    overlay.setImageBitmap(bitmap);
    overlay.setTop(0);
}

代码是Mark Allison on StylingAndroid.写的

编辑:

But I don't know how to get the position of item when dragging is end

答案位于part 7在 Styling Android 上。

View view = recyclerView.findChildViewUnder(0, y);

And how can I disable drag on Folder and Header item? Just allow dragging File item?

您可以通过使用多个 ViewType(文件、文件夹和标题)来做到这一点。然后你可以使用getItemViewTypeDragController 中只为文件开始移动。

关于android - 将 Listview 项目拖放到另一个项目中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34382177/

相关文章:

java - eclipse 看不到我的 lenovo S650 手机

java - listView结果检索并等待用户输入

android - 有没有办法从主要 Activity 中隐藏特定的 ListView 项目?

android - React-Native 为什么动画不是线性的并且来自发布的地方?

android - 在 ListView 中实现滑动

android - 用于聊天应用程序的 RecyclerView 与 ListView

android - Kotlin 中的 EvictingQueue

java - Android XML内部存储

android - 单击按钮后,EditText 框内容进入 Android 上的 ListView

android - 3.0 中的拖放