您的位置:首页 > 移动开发 > Android开发

可拖拽 GridView

2016-05-06 17:21 477 查看
package com.example.myapp;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.PixelFormat;
import android.os.Handler;
import android.os.Vibrator;
import android.util.AttributeSet;
import android.util.Log;
import android.view.*;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.widget.GridView;
import android.widget.ImageView;

import java.util.LinkedList;
import java.util.List;

/**
* Created by yp-tc-m-2781 on 16/5/3.
*/
public class MyGridView extends GridView {

private final String tag = "#myapp.MyGridView";

private View mStartDragItemView = null;
private ImageView mDragImageView;
private Bitmap mDragBitmap;
private WindowManager mWindowManager;
private WindowManager.LayoutParams mWindowLayoutParams;
private Handler mHandler;
private long dragResponseMS = 800;
private boolean isDrag;
private boolean normalMove;
private int mDownX;
private int mDownY;
private int itemHeight;
private int mDragPosition;
private Vibrator mVibrator;
private int mPoint2ItemLeft;
private int mPoint2ItemTop;
private boolean mAnimationEnd = true;
private int paddingTop;
private int paddingBottom;
int mNumColumns;

public MyGridView(Context context) {
this(context,null);
}

public MyGridView(Context context, AttributeSet attrs) {
this(context, attrs,0);
}

public MyGridView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mVibrator = (Vibrator) getContext().getSystemService(Context.VIBRATOR_SERVICE);
mWindowManager = (WindowManager)getContext().getSystemService(Context.WINDOW_SERVICE);
mHandler = new Handler();
paddingTop = getPaddingTop();
paddingBottom = getPaddingBottom();
}

@Override
public void setNumColumns(int numColumns) {
super.setNumColumns(numColumns);
this.mNumColumns = numColumns;
}

private Runnable mLongClickRunnable = new Runnable() {

@Override
public void run() {
isDrag = true;
mVibrator.vibrate(50);
mStartDragItemView.setVisibility(View.INVISIBLE);
itemHeight = mStartDragItemView.getHeight();
createDragImage(mDragBitmap, mDownX, mDownY);
}
};

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {

switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
normalMove = false;
mDownX = (int)ev.getX();
mDownY = (int)ev.getY();
mDragPosition = pointToPosition(mDownX,mDownY);
if(mDragPosition == INVALID_POSITION)
{
return super.dispatchTouchEvent(ev);
}
mHandler.postDelayed(mLongClickRunnable,dragResponseMS);
mStartDragItemView = getChildAt(mDragPosition - getFirstVisiblePosition());
mStartDragItemView.setDrawingCacheEnabled(true);
mDragBitmap = Bitmap.createBitmap(mStartDragItemView.getDrawingCache());
mStartDragItemView.destroyDrawingCache();
mPoint2ItemTop = mDownY - mStartDragItemView.getTop();
mPoint2ItemLeft = mDownX - mStartDragItemView.getLeft();
break;
case MotionEvent.ACTION_MOVE:
int moveX = (int)ev.getX();
int moveY = (int) ev.getY();
if(!isTouchInItem( moveX, moveY)){
normalMove = true;
mHandler.removeCallbacks(mLongClickRunnable);
}
break;
case MotionEvent.ACTION_UP:
mHandler.removeCallbacks(mLongClickRunnable);
break;
}
return super.dispatchTouchEvent(ev);
}

@Override
public boolean onTouchEvent(MotionEvent ev) {
Log.i(tag,"onTouchEvent");
if(isDrag && mDragImageView != null){
switch(ev.getAction()){
case MotionEvent.ACTION_MOVE:
onDragItem((int)ev.getX(),(int)ev.getY());
break;
case MotionEvent.ACTION_UP:
onStopDrag();
break;
}
return true;
}
return super.onTouchEvent(ev);
}

private void onStopDrag(){
View view = getChildAt(mDragPosition - getFirstVisiblePosition());
if(view != null){
view.setVisibility(View.VISIBLE);
}
removeDragImage();
isDrag = false;
if(onChangeListener != null)
{
onChangeListener.onStop();
}
}

private void createDragImage(Bitmap bitmap, int downX , int downY)
{
mWindowLayoutParams = new WindowManager.LayoutParams();
mWindowLayoutParams.format = PixelFormat.TRANSLUCENT;
mWindowLayoutParams.gravity = Gravity.TOP | Gravity.LEFT;
mWindowLayoutParams.x = downX - mPoint2ItemLeft + getLeft();
mWindowLayoutParams.y = downY - mPoint2ItemTop + getTop();
mWindowLayoutParams.alpha = 0.55f;
mWindowLayoutParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
mWindowLayoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
mWindowLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE ;
mDragImageView = new ImageView(getContext());
mDragImageView.setImageBitmap(bitmap);
mWindowManager.addView(mDragImageView, mWindowLayoutParams);
}

private boolean isTouchInItem(int x, int y){
if(isDrag || normalMove)
{
return true;
}
int disX = Math.abs(x - mDownX);
int disY = Math.abs(y - mDownY);
if(disX > 1 || disY > 1)
{
return false;
}
return true;
}

private void removeDragImage(){
if(mDragImageView != null){
mWindowManager.removeView(mDragImageView);
mDragImageView = null;
}
}

private void onDragItem(int moveX, int moveY){
mWindowLayoutParams.x = (moveX - mPoint2ItemLeft + getLeft());
mWindowLayoutParams.y = (moveY - mPoint2ItemTop + getTop());
int trans = itemHeight/4;
if((getBottom()-mWindowLayoutParams.y - paddingBottom) <= (itemHeight+trans))
{
smoothScrollBy(itemHeight,1500);
}
else if((mWindowLayoutParams.y - trans) <= (getTop() + paddingTop))
{
smoothScrollBy(-itemHeight,1500);
}
else
{
smoothScrollBy(0,0);
}
mWindowManager.updateViewLayout(mDragImageView, mWindowLayoutParams);
final int newPosition = pointToPosition(moveX,moveY);
if(newPosition != mDragPosition && newPosition != INVALID_POSITION && mAnimationEnd)
{
if(onChangeListener != null) {
onChangeListener.onChange(mDragPosition, newPosition);
}
final ViewTreeObserver observer = getViewTreeObserver();
observer.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
observer.removeOnPreDrawListener(this);
animateReorder(mDragPosition, newPosition);
mDragPosition = newPosition;
return true;
}
} );
}
}

private void animateReorder(final int oldPosition, final int newPosition) {
boolean isForward = newPosition > oldPosition;
List<Animator> resultList = new LinkedList<Animator>();
if (isForward) {
for (int pos = oldPosition; pos < newPosition; pos++) {
View view = getChildAt(pos - getFirstVisiblePosition());
if ((pos + 1) % mNumColumns == 0) {
resultList.add(createTranslationAnimations(view,
- (view.getWidth() ) * (mNumColumns - 1), 0,
view.getHeight() , 0));
} else {
resultList.add(createTranslationAnimations(view,
view.getWidth() , 0, 0, 0));
}
}
} else {
for (int pos = oldPosition; pos > newPosition; pos--) {
View view = getChildAt(pos - getFirstVisiblePosition());
if ((pos) % mNumColumns == 0) {
resultList.add(createTranslationAnimations(view,
(view.getWidth() ) * (mNumColumns - 1), 0,
-view.getHeight() , 0));
} else {
resultList.add(createTranslationAnimations(view,
-view.getWidth() , 0, 0, 0));
}
}
}

AnimatorSet resultSet = new AnimatorSet();
resultSet.playTogether(resultList);
resultSet.setDuration(300);
resultSet.setInterpolator(new AccelerateDecelerateInterpolator());
resultSet.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
mAnimationEnd = false;
}

@Override
public void onAnimationEnd(Animator animation) {
mAnimationEnd = true;
}
});
resultSet.start();
}

private AnimatorSet createTranslationAnimations(View view, float startX,
float endX, float startY, float endY) {
ObjectAnimator animX = ObjectAnimator.ofFloat(view, "translationX",
startX, endX);
ObjectAnimator animY = ObjectAnimator.ofFloat(view, "translationY",
startY, endY);
AnimatorSet animSetXY = new AnimatorSet();
animSetXY.playTogether(animX, animY);
return animSetXY;
}

private OnChangeListener onChangeListener;

public void setOnChangeListener(OnChangeListener onChangeListener) {
this.onChangeListener = onChangeListener;
}

interface OnChangeListener
{
void onChange(int drayPosition,int swapPosition);
void onStop();
}

//    @Override
//    public void onChange(int drayPosition, int swapPosition) {
//        mHidePosition = swapPosition;
//        Integer integer = list.get(drayPosition);
//        list.remove(drayPosition);
//        list.add(swapPosition,integer);
//        notifyDataSetChanged();
//    }
//
//    @Override
//    public void onStop() {
//        mHidePosition = -1;
//    }
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android gridview