調用:
public class AniGridViewActivity extends Activity { /** GridView. */ private DragGrid gridView; TranslateAnimation left, right; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); com.cn.theodore.util.Configure.init(this); gridView = (DragGrid) findViewById(R.id.gridview); ArrayList<String> l = new ArrayList<String>(); for (int i = 0; i < 8; i++) { l.add("" + i); } DateAdapter adapter = new DateAdapter(AniGridViewActivity.this, l); gridView.setAdapter(adapter); }}
重寫的GridView:
public class DragGrid extends GridView { private int dragPosition; private int dropPosition; private int holdPosition; private int startPosition; private int specialPosition = -1; private int leftBottomPosition = -1; private int nColumns = 3; private int nRows; private int Remainder; private int itemTotalCount; private int halfItemWidth; private ImageView dragImageView = null; private ViewGroup dragItemView = null; private WindowManager windowManager = null; private WindowManager.LayoutParams windowParams = null; private int mLastX,xtox; private int mLastY,ytoy; private int specialItemY; private int leftBtmItemY; private String LastAnimationID; private boolean isCountXY = false; private boolean isMoving = false; public DragGrid(Context context, AttributeSet attrs) { super(context, attrs); } public DragGrid(Context context) { super(context); } boolean flag = false; public void setLongFlag(boolean temp) { flag = temp; } public boolean setOnItemLongClickListener(final MotionEvent ev) { this.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() { @Override public boolean onItemLongClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) { int x = (int) ev.getX(); int y = (int) ev.getY(); mLastX=x; mLastY=y; startPosition = dragPosition = dropPosition = arg2; if (dragPosition == AdapterView.INVALID_POSITION) { } ViewGroup itemView = (ViewGroup) getChildAt(dragPosition - getFirstVisiblePosition()); if(!isCountXY){ halfItemWidth = itemView.getWidth()/2; int rows; itemTotalCount = getCount(); rows = itemTotalCount/nColumns; Remainder = itemTotalCount%nColumns; nRows = Remainder == 0 ? rows : rows + 1; specialPosition = itemTotalCount - 1 - Remainder; if(Remainder!=1) leftBottomPosition = nColumns*(nRows-1); if(Remainder == 0 || nRows == 1) specialPosition = -1; isCountXY = true; } if(specialPosition != dragPosition && dragPosition != -1){ specialItemY = getChildAt(specialPosition).getTop(); }else{ specialItemY = -1; } if(leftBottomPosition != dragPosition && dragPosition != -1){ leftBtmItemY = getChildAt(leftBottomPosition).getTop(); }else{ leftBtmItemY = -1; } dragItemView = itemView; itemView.destroyDrawingCache(); itemView.setDrawingCacheEnabled(true); itemView.setDrawingCacheBackgroundColor(0x000000); Bitmap bm = Bitmap.createBitmap(itemView.getDrawingCache(true)); Bitmap bitmap = Bitmap.createBitmap(bm, 8, 8, bm.getWidth()-8, bm.getHeight()-8); startDrag(bitmap, x, y); hideDropItem(); itemView.setVisibility(View.INVISIBLE); isMoving = false; return false; }; }); return super.onInterceptTouchEvent(ev); } public void GetItemShadow(int x,int y){ } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { if (ev.getAction() == MotionEvent.ACTION_DOWN) { return setOnItemLongClickListener(ev); } return super.onInterceptTouchEvent(ev); } @Override public boolean onTouchEvent(MotionEvent ev) { if (dragImageView != null && dragPosition != AdapterView.INVALID_POSITION) { int x = (int) ev.getX(); int y = (int) ev.getY(); switch (ev.getAction()) { case MotionEvent.ACTION_MOVE: if(!isCountXY) { xtox = x-mLastX; ytoy = y-mLastY; isCountXY= true; } onDrag(x, y); if(!isMoving ) OnMove(x,y); break; case MotionEvent.ACTION_UP: stopDrag(); onDrop(x, y); break; } } return super.onTouchEvent(ev); } private void startDrag(Bitmap bm, int x, int y) { stopDrag(); windowParams = new WindowManager.LayoutParams(); windowParams.gravity = Gravity.TOP | Gravity.LEFT; windowParams.x = dragItemView.getLeft() + 8; windowParams.y = dragItemView.getTop()+(int)(45*Configure.screenDensity); windowParams.height = WindowManager.LayoutParams.WRAP_CONTENT; windowParams.width = WindowManager.LayoutParams.WRAP_CONTENT; windowParams.alpha = 0.8f; ImageView iv = new ImageView(getContext()); iv.setImageBitmap(bm); windowManager = (WindowManager) getContext().getSystemService( Context.WINDOW_SERVICE); windowManager.addView(iv, windowParams); dragImageView = iv; } public void OnMove(int x, int y){ int TempPosition = pointToPosition(x,y); int sOffsetY = specialItemY == -1 ? y - mLastY : y - specialItemY - halfItemWidth; int lOffsetY = leftBtmItemY == -1 ? y - mLastY : y - leftBtmItemY - halfItemWidth; if(TempPosition != AdapterView.INVALID_POSITION && TempPosition != dragPosition){ dropPosition = TempPosition; }else if(specialPosition != -1 && dragPosition == specialPosition && sOffsetY >= halfItemWidth){ dropPosition = (itemTotalCount - 1); }else if(leftBottomPosition != -1 && dragPosition == leftBottomPosition && lOffsetY >= halfItemWidth){ dropPosition = (itemTotalCount - 1); } if(dragPosition != startPosition) dragPosition = startPosition; int MoveNum = dropPosition - dragPosition; if(dragPosition != startPosition && dragPosition == dropPosition) MoveNum = 0; if(MoveNum != 0){ int itemMoveNum = Math.abs(MoveNum); float Xoffset,Yoffset; for (int i = 0;i < itemMoveNum;i++){ if(MoveNum > 0){ holdPosition = dragPosition + 1; Xoffset = (dragPosition/nColumns == holdPosition/nColumns) ? (-1) : (nColumns -1); Yoffset = (dragPosition/nColumns == holdPosition/nColumns) ? 0 : (-1); }else{ holdPosition = dragPosition - 1; Xoffset = (dragPosition/nColumns == holdPosition/nColumns) ? 1 : (-(nColumns-1)); Yoffset = (dragPosition/nColumns == holdPosition/nColumns) ? 0 : 1; } ViewGroup moveView = (ViewGroup)getChildAt(holdPosition); Animation animation = getMoveAnimation(Xoffset,Yoffset); moveView.startAnimation(animation); dragPosition = holdPosition; if(dragPosition == dropPosition) LastAnimationID = animation.toString(); final DateAdapter adapter = (DateAdapter)this.getAdapter(); animation.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) { // TODO Auto-generated method stub isMoving = true; } @Override public void onAnimationRepeat(Animation animation) { // TODO Auto-generated method stub } @Override public void onAnimationEnd(Animation animation) { // TODO Auto-generated method stub String animaionID = animation.toString(); if(animaionID.equalsIgnoreCase(LastAnimationID)){ adapter.exchange(startPosition, dropPosition); startPosition = dropPosition; isMoving = false; } } }); } } } private void onDrop(int x,int y){ final DateAdapter adapter = (DateAdapter) this.getAdapter(); adapter.showDropItem(true); adapter.notifyDataSetChanged(); } private void onDrag(int x, int y) { if (dragImageView != null) { windowParams.alpha = 0.8f; windowParams.x = (x-mLastX-xtox)+dragItemView.getLeft()+8;// windowParams.y = (y-mLastY-ytoy)+dragItemView.getTop()+(int)(45*Configure.screenDensity); windowParams.y = y; windowManager.updateViewLayout(dragImageView, windowParams); } } private void stopDrag() { if (dragImageView != null) { windowManager.removeView(dragImageView); dragImageView = null; } } private void hideDropItem(){ final DateAdapter adapter = (DateAdapter)this.getAdapter(); adapter.showDropItem(false); } public Animation getMoveAnimation(float x,float y){ TranslateAnimation go = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, x, Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, y); go.setFillAfter(true); go.setDuration(300); return go; }}
GridView使用的Adapter:
public class DateAdapter extends BaseAdapter { private Context context; private List<String> lstDate; private TextView txtAge; private int holdPosition; private boolean isChanged = false; private boolean ShowItem = false; public DateAdapter(Context mContext, List<String> list) { this.context = mContext; lstDate = list; } @Override public int getCount() { return lstDate.size(); } @Override public Object getItem(int position) { return lstDate.get(position); } @Override public long getItemId(int position) { return position; } public void exchange(int startPosition, int endPosition) { System.out.println(startPosition + "--" + endPosition); holdPosition = endPosition; Object startObject = getItem(startPosition); System.out.println(startPosition + "========" + endPosition); Log.d("ON","startPostion ==== " + startPosition ); Log.d("ON","endPosition ==== " + endPosition ); if(startPosition < endPosition){ lstDate.add(endPosition + 1, (String) startObject); lstDate.remove(startPosition); }else{ lstDate.add(endPosition,(String)startObject); lstDate.remove(startPosition + 1); } isChanged = true; notifyDataSetChanged(); } public void showDropItem(boolean showItem){ this.ShowItem = showItem; } @Override public View getView(int position, View convertView, ViewGroup parent) { convertView = LayoutInflater.from(context).inflate(R.layout.item, null); txtAge = (TextView) convertView.findViewById(R.id.txt_userAge); txtAge.setText("Item" + lstDate.get(position)); if (isChanged){ if (position == holdPosition){ if(!ShowItem){ convertView.setVisibility(View.INVISIBLE); } } } return convertView; }}
Configure:
public class Configure { public static int screenHeight=0; public static int screenWidth=0; public static float screenDensity=0; public static void init(Activity context) { if(screenDensity==0||screenWidth==0||screenHeight==0){ DisplayMetrics dm = new DisplayMetrics(); context.getWindowManager().getDefaultDisplay().getMetrics(dm); Configure.screenDensity = dm.density; Configure.screenHeight = dm.heightPixels; Configure.screenWidth = dm.widthPixels; } }}
main.xml:
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:gravity="center" android:background="@drawable/notesbackground" > <com.cn.theodore.util.DragGrid android:id="@+id/gridview" android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="center" android:numColumns="3" android:scrollbars="vertical" android:stretchMode="columnWidth" android:verticalSpacing="25dp" > </com.cn.theodore.util.DragGrid> <!-- android:listSelector="@android:color/transparent"--></RelativeLayout>