DragGridViewEx.java文件:
  
package com.smiling.draggridview;/* * onInterceptTouchEvent() -> onItemLongClick() -> onTouchEvent()->ACTION_MOVE->ACTION_UP; *  * */import android.content.Context;import android.graphics.Bitmap;import android.graphics.Color;import android.util.AttributeSet;import android.view.Gravity;import android.view.MotionEvent;import android.view.View;import android.view.ViewGroup;import android.view.WindowManager;import android.widget.AdapterView;import android.widget.GridView;import android.widget.ImageView;
  
//以下为自定义GridView控件;public class DragGridViewEx extends GridView{private WindowManager windowManager;// windows窗口控制类private WindowManager.LayoutParams windowParams;// 用于控制拖拽项的显示的参数private ImageView dragImageView;// 被拖拽的项(item),其实就是一个ImageView\private View  itemView=null;private Bitmap bm;private ImageView imageView;private View dragger;private int dragSrcPosition;// 手指拖动项在列表中的原始位置private int dragPosition;// 手指点击准备拖动的时候,当前拖动项在列表中的位置.private int dragPointX;private int dragPointY;// 在当前数据项中的位置private int dragOffsetX;private int dragOffsetY;// 当前视图和屏幕的距离(这里只使用了y方向上)private int upScrollBounce;// 拖动的时候,开始向上滚动的边界private int downScrollBounce;// 拖动的时候,开始向下滚动的边界private int tempChangeId;private boolean isDoTouch = false;private boolean hasAdd=false;//=========================================================================================================public DragGridViewEx(Context context) {super(context);// TODO 自动生成的构造函数存根}public DragGridViewEx(Context context, AttributeSet attrs) {super(context, attrs);// TODO 自动生成的构造函数存根}public DragGridViewEx(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);// TODO 自动生成的构造函数存根}//==========================================================================================================public void setDoTouch(boolean b){this.isDoTouch=b;this.hasAdd=false;}@Overridepublic boolean onInterceptTouchEvent(MotionEvent ev) { {if (ev.getAction() == MotionEvent.ACTION_DOWN) {{int x = (int) ev.getX();int y = (int) ev.getY();this.tempChangeId=dragSrcPosition = dragPosition = pointToPosition(x, y);System.out.println("getY()="+y+","+"dragPosition="+dragPosition);System.out.println("getFirstVisiblePosition()="+getFirstVisiblePosition());// 无效不进行处理if (dragPosition == AdapterView.INVALID_POSITION) {return super.onInterceptTouchEvent(ev);}// 获取当前位置的视图(可见状态)itemView = getChildAt(dragPosition-getFirstVisiblePosition());dragPointX = x - itemView.getLeft();dragPointY = y - itemView.getTop();   //不可见的项不算;dragOffsetX = (int) (ev.getRawX() - x);dragOffsetY = (int) (ev.getRawY() - y);//每个项中可能有其他的文字之类的东西,所以要获取 R.id.drag_gridview_image;dragger = itemView.findViewById(R.id.drag_gridview_image);if (dragger != null &&dragPointX>dragger.getLeft()            &&dragPointX<dragger.getRight()            &&dragPointY>dragger.getTop()            &&dragPointY<dragger.getBottom()) {upScrollBounce = getHeight() / 4;      // 取得向上滚动的边际,大概为该控件的1/3downScrollBounce = getHeight() * 3 / 4;// 取得向下滚动的边际,大概为该控件的2/3System.out.println("Here....");itemView.setDrawingCacheEnabled(true);// 开启cache.        bm= Bitmap.createBitmap(itemView.getDrawingCache());// 根据cache创建一个新的bitmap对象.startDrag(bm, x, y);// 初始化影像;}}}}return super.onInterceptTouchEvent(ev);}private void startDrag(Bitmap bm, int x, int y) {// stopDrag();/*** * 初始化window. */windowParams = new WindowManager.LayoutParams();windowParams.gravity = Gravity.TOP| Gravity.LEFT;windowParams.x = x - dragPointX + dragOffsetX;windowParams.y = y - dragPointY + dragOffsetY;    //getTop()+dragOffset;windowParams.width = WindowManager.LayoutParams.WRAP_CONTENT;windowParams.height = WindowManager.LayoutParams.WRAP_CONTENT;windowParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE// 不需获取焦点| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE// 不需接受触摸事件| WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON// 保持设备常开,并保持亮度不变。| WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;// 窗口占满整个屏幕,忽略周围的装饰边框(例如状态栏)。此窗口需考虑到装饰边框的内容。windowParams.windowAnimations = 0;imageView = new ImageView(getContext());imageView.setImageBitmap(bm);windowManager = (WindowManager) getContext().getSystemService("window");//windowManager.addView(imageView, windowParams);  //注意不在这里添加;dragImageView = imageView;}//===========================================================================================================/** * 触摸事件处理 */@Overridepublic boolean onTouchEvent(MotionEvent ev) {// item的view不为空,且获取的dragPosition有效if (dragImageView!=null&&dragPosition != INVALID_POSITION && isDoTouch==true) {if(!this.hasAdd){windowManager.addView(imageView, windowParams);this.hasAdd=true;}int action = ev.getAction();switch (action) {case MotionEvent.ACTION_UP:System.out.println("ACTION_UP");if(!this.dragger.isShown()){this.dragger.setVisibility(View.VISIBLE);System.out.println("VISIBLE");}int upX = (int) ev.getX();int upY = (int) ev.getY();stopDrag();onDrop(upX,upY);isDoTouch=false;  //若没有这个,就不会触发onItemClick事件了hasAdd=false;break;case MotionEvent.ACTION_MOVE://System.out.println("ACTION_MOVE");if(this.dragger.isShown()){this.dragger.setVisibility(View.INVISIBLE);}int moveX = (int)ev.getX();int moveY = (int) ev.getY();onDrag(moveX,moveY);break;case MotionEvent.ACTION_DOWN:             //longClick之后不会执行;System.out.println("ACTION_DOWN");int downX = (int)ev.getX();int downY = (int) ev.getY();break;default:break;}return true; }return super.onTouchEvent(ev);}//=======================================================================================================public void onDrag(int x, int y) {if (dragImageView != null) {windowParams.alpha = 0.7f;// 透明度windowParams.x = x - dragPointX + dragOffsetX;windowParams.y = y - dragPointY + dragOffsetY;// 移动y值.//记得要加上dragOffset,windowManager计算的是整个屏幕.(标题栏和状态栏都要算上)windowManager.updateViewLayout(dragImageView, windowParams);// 时时移动.}int tempPosition = pointToPosition(x, y);if (tempPosition != INVALID_POSITION) {dragPosition = tempPosition;}onChange(x,y);// 滚动          if (y < upScrollBounce || y > downScrollBounce) {              // 使用setSelection来实现滚动              setSelection(dragPosition);          }  }public void onChange(int x,int y){if(dragPosition<getAdapter().getCount()){DragGVAdapter adapter = (DragGVAdapter)getAdapter();if(this.tempChangeId!=this.dragPosition){adapter.update(tempChangeId,dragPosition);this.tempChangeId=this.dragPosition;}}int tempPosition=pointToPosition(x,y);if(tempPosition!=INVALID_POSITION){this.dragPosition=tempPosition;}}public void stopDrag() {if (dragImageView != null) {windowManager.removeView(dragImageView);dragImageView = null;}}public void onDrop(int x,int y) {// 数据交换if (dragPosition < getAdapter().getCount()) {DragGVAdapter adapter = (DragGVAdapter)getAdapter();adapter.lastUpdate();}}}

DragGVAdapter.java文件:

package com.smiling.draggridview;import java.util.ArrayList;import android.content.Context;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.ImageView;public class DragGVAdapter extends BaseAdapter{private Context context;private ArrayList<Integer> arrayDrawables;private boolean isHide=false;private int endPosition=-1;public DragGVAdapter(Context c,ArrayList<Integer> pics){this.context=c;this.arrayDrawables=pics;}@Overridepublic int getCount() {// TODO 自动生成的方法存根return this.arrayDrawables.size();}@Overridepublic Object getItem(int arg0) {// TODO 自动生成的方法存根return null;}@Overridepublic long getItemId(int arg0) {// TODO 自动生成的方法存根return arg0;}@Overridepublic View getView(int position, View v, ViewGroup vg) {// TODO 自动生成的方法存根LayoutInflater inflater=LayoutInflater.from(context);v=inflater.inflate(R.layout.drag_gridview_item,null);System.out.println("POSITION="+position);   //连续输出两次POSITION=0;if(position!=endPosition){ImageView imageview=(ImageView)v.findViewById(R.id.drag_gridview_image);imageview.setImageResource(this.arrayDrawables.get(position));imageview.setScaleType(ImageView.ScaleType.FIT_XY);}else if(position==endPosition){ImageView imageview=(ImageView)v.findViewById(R.id.drag_gridview_image);imageview.setImageResource(this.arrayDrawables.get(position));imageview.setScaleType(ImageView.ScaleType.FIT_XY);imageview.setVisibility(View.INVISIBLE);}return v;}public void update(int start, int down) {this.endPosition=down;System.out.println("END="+endPosition);int drawable_id = arrayDrawables.get(start);arrayDrawables.remove(start); arrayDrawables.add(down, drawable_id); notifyDataSetChanged(); }public void lastUpdate(){this.endPosition=-1;notifyDataSetChanged(); }}

这里需要注意几点,首先是方法的执行顺序,是先onInterceptTouchEvent(),然后是onItemLongClick(),接着onTouchEvent(),ACTION_MOVE->ACTION_UP;注意映像应该在onTouchEvent方法中添加,而不能在onInterceptTouchEvent()方法中添加,否则GridView上下滑动也会出现映像。

Sumsang S4实测截图如下:



更多相关文章

  1. Java如何操作Android的adb shell 之 我自己在程序中的使用方法
  2. 『ANDROID』Android中的onWindowFocusChanged()方法详解
  3. android图片拖动
  4. android 键盘关闭/显示
  5. Android(安卓)改变View位置 setLeft、etRight、setTop、setBotto
  6. Android(安卓)控件界面转成Bitmap
  7. android:程序中安装APK方法
  8. 浅谈Java中Collections.sort对List排序的两种方法
  9. Python list sort方法的具体使用

随机推荐

  1. Android穿山甲SDK激励视频
  2. Android 应用开发支持不同的语言国际化操
  3. 【原创】Android 引用第三方库文件大全
  4. Android Studio 使用 Gradle 打包 Jar
  5. Android ListView异步加载图片乱序问题,原
  6. Android性能测试用例
  7. Android开发之实现图片自动滚动显示标签
  8. android SD卡学习3-读写文件
  9. Ormlite 介绍 一
  10. Android常用开发工具的用法