2012-11-06 33 views
0

我有一個我不知道如何解決的錯誤。重點是我應該爲我的listview實現DragNDrop功能,但我的minSdkVersion =「7」,所以我使用了框架Eric Harlow在Android 4.1上實現DragNDrop時返回錯誤參考視圖

當我使用Android 2.1,2.2,2.3.6至4.0時,所有工作都以正確的方式進行,但是當我在Android 4.1.2上測試我的應用時,我遇到了一個錯誤。問題的核心是:讓我想象我的listview包含4個項目,並且我將4個項目拖到3個位置。

當我這樣做了,我想再拖動4個項目,也許2位置。當我第一次從4位拖到3位時,結果是OK,我的觀點失效了。但是當我第二次拖拽Ndrop 4項目時,發生在我的手指下我有舊的第4個元素(現在它是3個元素),而不是新的。

在我的調查中,當試圖讓視圖對象移動時,我得到了一個錯誤的引用視圖對象View item = getChildAt(itemIndex);,但我不知道爲什麼它在Android 4.1.2早期完美工作,並使用Android 4.1下的bug 0.2。

有人有任何想法如何解決這個錯誤?

在它下面是一個代碼評論:主叫getChildAt(位置)之前)

public class DragNDropListView extends ListView { 

    private static final int OUR_LOCATION_ELEMENT = 1; 
    private static final int MIN_INDEX_ELEM_DONT_TOUCH = 2; 
    boolean mDragMode; 

    int mStartPosition; 
    int mEndPosition; 
    int mDragPointOffset;  //Used to adjust drag view location 

    ImageView mDragView; 

    DropListener mDropListener; 
    RemoveListener mRemoveListener; 
    DragListener mDragListener; 
    UpdateOurLocationListener mOnClickListener; 

    Context context; 

    public DragNDropListView(Context context, AttributeSet attrs) { 
     super(context, attrs); 
     this.context = context; 
    } 

    public void setDropListener(DropListener l) { 
     mDropListener = l; 
    } 

    public void setRemoveListener(RemoveListener l) { 
     mRemoveListener = l; 
    } 

    public void setDragListener(DragListener l) { 
     mDragListener = l; 
    } 

    public void setOnOurLocationListener (UpdateOurLocationListener l) { 
     mOnClickListener = l; 
    } 

    @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 && 
       x > (this.getWidth()-context.getResources().getDimension(R.dimen.image_move_width))&& 
       pointToPosition(x,y) == OUR_LOCATION_ELEMENT) { 
       mOnClickListener.onOurLocationClick(); 
       mDragMode = false; 
     } 

     if (action == MotionEvent.ACTION_DOWN && 
      x > (this.getWidth()-context.getResources().getDimension(R.dimen.image_move_width))&& 
      pointToPosition(x,y)>MIN_INDEX_ELEM_DONT_TOUCH) { 
      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 
         && mEndPosition > MIN_INDEX_ELEM_DONT_TOUCH) { 
        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); 
     Log.e ("startDrag " , "itemIndex = " + itemIndex); 
     View item = getChildAt(itemIndex);        // ??? 
     Log.e ("startDrag - View item " , "item = " + item.toString()); 
     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; 
     } 
    } 

} 

回答

0

爲了解決這個問題,我使用的方法layoutChildren(