1

ListViewアイテムのリストとして画像を持っているがあります。次に、リストビューでアイテムのドラッグアンドドロップを実行します。そのために、を拡張するクラス「DragNDropListView」を作成し、ListViewこのクラス内のリストビューのonTouch()メソッドをオーバーライドして、ドラッグアンドドロップ操作を実行すると、正常に動作します。

しかし、私の要件は、リストビューに表示されている画像を長押ししてアイテムをドラッグアンドドロップすることです。それで、それをどのように行うことができますか。リストビューのメソッドで行ったのと同じことを行う必要がありonTouch()ますか、それともこのメソッドを変更する必要があります。

これを整理するのを手伝ってください。

私のコードonTouchメソッド

@Override
public boolean onTouchEvent(MotionEvent ev) 
{
    final int action = ev.getAction();
    final int x = (int) ev.getX();
    final int y = (int) ev.getY();  
    
    if (action == MotionEvent.ACTION_DOWN) 
    {
        mDragMode = true;
    }

    if (!mDragMode) 
        return super.onTouchEvent(ev);

    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;
            startDrag(mItemPosition,y);
            drag(0,y);// replace 0 with x if desired
        }   
        break;
        
        case MotionEvent.ACTION_MOVE:
        {
            drag(0,y);// replace 0 with x if desired
        }
        break;
        
        case MotionEvent.ACTION_CANCEL:             
        case MotionEvent.ACTION_UP:
        
        default:
        mDragMode = false;
        mEndPosition = pointToPosition(x,y);
        stopDrag(mStartPosition - getFirstVisiblePosition());
        if (mDropListener != null && mStartPosition != INVALID_POSITION && mEndPosition != INVALID_POSITION) 
             mDropListener.onDrop(mStartPosition, mEndPosition);
        break;
    }
    return true;
}   

// move the drag view
private void drag(int x, int y) 
{
    if (mDragView != null) 
    {
        WindowManager.LayoutParams layoutParams = (WindowManager.LayoutParams) mDragView.getLayoutParams();
        layoutParams.x = x;
        layoutParams.y = y - mDragPointOffset;
        WindowManager mWindowManager = (WindowManager) getContext()
                .getSystemService(Context.WINDOW_SERVICE);
        mWindowManager.updateViewLayout(mDragView, layoutParams);

        if (mDragListener != null)
            mDragListener.onDrag(x, y, null);// change null to "this" when ready to use
    }
}

// enable the drag view for dragging
private void startDrag(int itemIndex, int y) 
{
    stopDrag(itemIndex);

    View item = getChildAt(itemIndex);
    if (item == null) return;
    item.setDrawingCacheEnabled(true);
    if (mDragListener != null)
        mDragListener.onStartDrag(item);
    
    // Create a copy of the drawing cache so that it does not get recycled
    // by the framework when the list tries to clean up memory
    Bitmap bitmap = Bitmap.createBitmap(item.getDrawingCache());
    
    WindowManager.LayoutParams mWindowParams = new WindowManager.LayoutParams();
    mWindowParams.gravity = Gravity.TOP;
    mWindowParams.x = 0;
    mWindowParams.y = y - mDragPointOffset;

    mWindowParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
    mWindowParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
    mWindowParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
            | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
            | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
            | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
            | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
    mWindowParams.format = PixelFormat.TRANSLUCENT;
    mWindowParams.windowAnimations = 0;
    
    Context context = getContext();
    ImageView v = new ImageView(context);
    v.setImageBitmap(bitmap);      

    WindowManager mWindowManager = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
    mWindowManager.addView(v, mWindowParams);
    mDragView = v;
}

// destroy drag view
private void stopDrag(int itemIndex) 
{
    if (mDragView != null) {
        if (mDragListener != null)
            mDragListener.onStopDrag(getChildAt(itemIndex));
        mDragView.setVisibility(GONE);
        WindowManager wm = (WindowManager)getContext().getSystemService(Context.WINDOW_SERVICE);
        wm.removeView(mDragView);
        mDragView.setImageDrawable(null);
        mDragView = null;
    }
}   

リスナーの使用

    ListView listView = getListView();

    if (listView instanceof DragNDropListView) 
    {
        ((DragNDropListView) listView).setDropListener(mDropListener);
        ((DragNDropListView) listView).setRemoveListener(mRemoveListener);
        ((DragNDropListView) listView).setDragListener(mDragListener);
    }

private DropListener mDropListener = new DropListener() 
{
    public void onDrop(int from, int to) 
    {
        ListAdapter adapter = getListAdapter();
        if (adapter instanceof ListViewAdapter) 
        {
            ((ListViewAdapter)adapter).onDrop(from, to);
            getListView().invalidateViews();
        }
    }
};

private RemoveListener mRemoveListener = new RemoveListener() 
{
    public void onRemove(int which) 
    {
        ListAdapter adapter = getListAdapter();
        if (adapter instanceof ListViewAdapter) {
            ((ListViewAdapter)adapter).onRemove(which);
            getListView().invalidateViews();
        }
    }
};


private DragListener mDragListener = new DragListener() 
{
    public void onDrag(int x, int y, ListView listView)
    {
    }

    public void onStartDrag(View itemView) 
    {
        itemView.setVisibility(View.INVISIBLE);
        ImageView iv = (ImageView)itemView.findViewById(R.id.image);
        if (iv != null) iv.setVisibility(View.VISIBLE);
    }

    public void onStopDrag(View itemView) 
    {
        itemView.setVisibility(View.VISIBLE);
        ImageView iv = (ImageView)itemView.findViewById(R.id.image);
        if (iv != null) iv.setVisibility(View.VISIBLE);
    }
    
};
4

2 に答える 2

2

はい、リストビューのリスナーを使用するだけです-

public interface DropListener {

/**
 * Called when an item is to be dropped.
 * @param from - index item started at.
 * @param to - index to place item at.
 */
    void onDrop(int from, int to);
}

この例を見てみてください。

于 2012-05-24T10:56:43.053 に答える
0
@Override
public boolean onTouchEvent(MotionEvent event) {
    return touchHandler(event);
}

private boolean touchHandler(final MotionEvent event) {
    final int action = event.getAction();
    final int x = (int) event.getX();
    final int y = (int) event.getY();
    if (prevY < 0) {
        prevY = y;
    }
    Log.d(TAG, "Motion event " + event.getAction());
    int flatPosition = pointToPosition(x, y);
    dragRatio = getHeight() / screenHeight;
    long packagedPosition = getExpandableListPosition(flatPosition);

    if (action == MotionEvent.ACTION_DOWN
            && getPackedPositionType(packagedPosition) == 1) {
        if (dragOnLongPress) {
            if (pressedItem) {
                mDragMode = true;
                pressedItem = false;
            } else {
                pressedItem = true;
                Runnable r = new Runnable() {
                    @Override
                    public void run() {
                        // y coordinate is changing for no reason ??
                        event.setLocation(x, y);
                        touchHandler(event);
                    }
                };
                handler.postDelayed(r, 200);
                return true;
            }
        } else if (x < dragOffset) {
            mDragMode = true;
        }
    }

    if (!mDragMode) {
        /** when user action on other areas */
        if ((pressedItem && Math.abs(prevY - y) > 30)
                || event.getAction() != MotionEvent.ACTION_MOVE) {
            pressedItem = false;
            handler.removeCallbacksAndMessages(null);
        }
        return super.onTouchEvent(event);
    }
    switch (action) {
    case MotionEvent.ACTION_DOWN:
        mStartFlatPosition = flatPosition;
        mStartPosition[0] = getPackedPositionGroup(packagedPosition);
        mStartPosition[1] = getPackedPositionChild(packagedPosition);
        if (packagedPosition != PACKED_POSITION_VALUE_NULL) {

            int mItemPosition = flatPosition - getFirstVisiblePosition();
            mDragPointOffset = y - getChildAt(mItemPosition).getTop();
            mDragPointOffset -= ((int) event.getRawY()) - y;
            startDrag(mItemPosition, y);
            if (listeners != null) {
                listeners.onPick(mStartPosition);
            }
            drag(x, y);
        }
        break;
    case MotionEvent.ACTION_MOVE:
        int speed = (int) ((y - prevY) * dragRatio);
        if (getLastVisiblePosition() < getCount() && speed > 0) {
            smoothScrollBy(speed, 1);
        }
        if (getFirstVisiblePosition() > 0 && speed < 0) {
            smoothScrollBy(speed, 1);
        }
        drag(x, y);// replace 0 with x if desired
        if (listeners != null) {
            listeners.onDrag(x, y);
        }
        break;
    case MotionEvent.ACTION_CANCEL:
    case MotionEvent.ACTION_UP:
    default:

        mDragMode = false;
        if (getPackedPositionType(packagedPosition) == 0) {
            mEndPosition[0] = getPackedPositionGroup(packagedPosition);
            mEndPosition[1] = 0;
        } else {
            mEndPosition[0] = getPackedPositionGroup(packagedPosition);
            mEndPosition[1] = getPackedPositionChild(packagedPosition);
        }

        stopDrag(mStartFlatPosition);
        if (packagedPosition != PACKED_POSITION_VALUE_NULL) {
            if (adapter != null) {
                adapter.onDrop(mStartPosition, mEndPosition);
            }
            if (listeners != null) {
                listeners.onDrop(mStartPosition, mEndPosition);
            }
        }
        break;
    }
    prevY = y;
    return true;
}

ここで長押ししてドラッグアンドドロップで展開可能なリストビューを確認します。これを変更して、リストビューに実装できます。

于 2014-08-17T18:30:56.887 に答える