调用:
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>