http://blog.youkuaiyun.com/ialienworld/article/details/11607009
http://blog.youkuaiyun.com/ialienworld/article/details/11607009
http://blog.youkuaiyun.com/ialienworld/article/details/11607009
http://blog.youkuaiyun.com/ialienworld/article/details/11607009
http://blog.youkuaiyun.com/ialienworld/article/details/11607009
http://blog.youkuaiyun.com/ialienworld/article/details/11607009
对于没有及时发送代码的网友说声SORRY,下载链接如下
http://download.youkuaiyun.com/detail/u010129564/6892329
- 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;
- }
- @Override
- public 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/3
- downScrollBounce = getHeight() * 3 / 4;// 取得向下滚动的边际,大概为该控件的2/3
- System.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;
- }
- //===========================================================================================================
- /**
- * 触摸事件处理
- */
- @Override
- public 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;
- }
- @Override
- public int getCount() {
- // TODO 自动生成的方法存根
- return this.arrayDrawables.size();
- }
- @Override
- public Object getItem(int arg0) {
- // TODO 自动生成的方法存根
- return null;
- }
- @Override
- public long getItemId(int arg0) {
- // TODO 自动生成的方法存根
- return arg0;
- }
- @Override
- public 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实测截图如下:
-
猜你在找
7楼 itongworld 2014-01-30 15:05发表 [回复]-
-
对于没有及时发送代码的网友说声SORRY,下载链接如下
http://download.youkuaiyun.com/detail/u010129564/6892329