package com.openims.view.chat.widget; import android.content.Context; import android.graphics.Bitmap; import android.graphics.PixelFormat; import android.util.AttributeSet; import android.util.Log; import android.view.Gravity; import android.view.MotionEvent; import android.view.View; import android.view.ViewParent; import android.view.WindowManager; import android.widget.AbsListView; import android.widget.ExpandableListView; import android.widget.ImageView; import android.widget.AbsListView.OnScrollListener; import com.openims.utility.LogUtil; import com.openims.widgets.DragDropListener; public class FriendGroupListView extends ExpandableListView { private static final String TAG = LogUtil .makeLogTag(FriendGroupListView.class); private static final String PRE = "FriendGroupListView--"; private boolean mDragMode; private int mStartPosition; private int mEndPosition; private int mDragPointOffsetY; //Used to adjust drag view location private int mDragPointOffsetX; static Integer ntime = 0; private ImageView mDragView; private boolean mEditable = false; private DragDropListener mDragListener; public FriendGroupListView(Context context) { this(context, null); } public FriendGroupListView(Context context, AttributeSet attrs) { this(context, attrs, com.android.internal.R.attr.expandableListViewStyle); } public FriendGroupListView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public void setDragListener(DragDropListener l) { mDragListener = l; } public void setEditable(boolean isEdit){ mEditable = isEdit; } @Override public boolean onTouchEvent(MotionEvent ev) { // TODO no need this function now if(true/*mEditable == false*/){ return super.onTouchEvent(ev); } final int action = ev.getAction(); final int x = (int) ev.getX(); final int y = (int) ev.getY(); Log.i(TAG, PRE + "X=" +x + " rawX=" +ev.getRawX()); Log.i(TAG, PRE + "Y=" +y + " rawY=" +ev.getRawY()); if (action == MotionEvent.ACTION_DOWN && x < this.getWidth()/4) { mDragMode = true; } if (!mDragMode) return super.onTouchEvent(ev); switch (action) { case MotionEvent.ACTION_DOWN: mStartPosition = pointToPosition(x,y); if (mStartPosition != INVALID_POSITION) { long pos = this.getExpandableListPosition(mStartPosition); int childPos = getPackedPositionChild(pos); int groupPos = getPackedPositionGroup(pos); // except group int mItemPosition = mStartPosition - getFirstVisiblePosition(); View itemView = getChildAt(mItemPosition); if(childPos == -1){ mDragMode = false; return super.onTouchEvent(ev); } mDragPointOffsetY = y - getChildAt(mItemPosition).getTop(); mDragPointOffsetY -= ((int)ev.getRawY()) - y; //mDragPointOffsetX = x - getChildAt(mItemPosition).getLeft(); //mDragPointOffsetX -= ((int)ev.getRawX()) - x; mDragPointOffsetX = ((int)ev.getRawX()) - x; startDrag(mItemPosition,y); //drag(mStartPosition,0,y);// replace 0 with x if desired } break; case MotionEvent.ACTION_MOVE: int npos = pointToPosition(x,y); int nFirst = getFirstVisiblePosition(); if (npos != INVALID_POSITION) { drag(npos,0,y,getChildAt(npos - nFirst));// replace 0 with x if desired if(ntime > 30){ ntime = 0; Log.i(TAG,PRE + "npos=" +npos + " nFirst=" + nFirst); if(npos - nFirst <= 2){ this.setSelection(nFirst-1); }else if(getLastVisiblePosition() - npos <= 2){ this.setSelection(nFirst+1); } } ntime++; } break; case MotionEvent.ACTION_CANCEL: case MotionEvent.ACTION_UP: default: mDragMode = false; mEndPosition = pointToPosition(x,y); stopDrag(mEndPosition - getFirstVisiblePosition()); break; } return true; } // move the drag view private void drag(int nposition, int x, int y,View viewItem) { if (mDragView != null) { WindowManager.LayoutParams layoutParams = (WindowManager.LayoutParams) mDragView.getLayoutParams(); layoutParams.x = mDragPointOffsetX; layoutParams.y = y - mDragPointOffsetY; WindowManager mWindowManager = (WindowManager) getContext() .getSystemService(Context.WINDOW_SERVICE); mWindowManager.updateViewLayout(mDragView, layoutParams); if (mDragListener != null) mDragListener.onDrag(nposition, viewItem);// 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(mStartPosition,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 | Gravity.LEFT; mWindowParams.x = mDragPointOffsetX; mWindowParams.y = y - mDragPointOffsetY; 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(mEndPosition,getChildAt(itemIndex)); mDragView.setVisibility(GONE); WindowManager wm = (WindowManager)getContext().getSystemService(Context.WINDOW_SERVICE); wm.removeView(mDragView); mDragView.setImageDrawable(null); mDragView = null; } } }