一.项目要求要长按后拖拽的效果.
网络上有一份代码,存在两个尚未解决的问题:
1) 点击后就拖拽,并且如果你往下滑的时候,界面会受干扰,因为他用的是Action.Move
2) 当拖拽的View跑到快接近手机屏幕边缘时,GridView没有向下移动.
二.于是经过本人修改,实现了长按后才出现拖拽界面的效果,代码如下:
- package com.pl;
- import com.pl.MainActivity.ImageAdapter;
- import android.content.Context;
- import android.graphics.Bitmap;
- import android.graphics.PixelFormat;
- 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;
- public class DragGridView extends GridView
- {
- private int dragPosition; // 开始拖拽的位置
- private int dropPosition; // 结束拖拽的位置
- private int dragPointX; // 相对于item的x坐标
- private int dragPointY; // 相对于item的y坐标
- private int dragOffsetX;
- private int dragOffsetY;
- private ImageView dragImageView; // 拖动item的preview
- private WindowManager windowManager;
- private WindowManager.LayoutParams windowParams;
- private int itemHeight;
- public DragGridView(Context context, AttributeSet attrs)
- {
- super(context, attrs);
- }
- 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)
- {
- // onInterceptTouchEvent(ev);
- // TODO Auto-generated method stub
- L.l("============on Long Click=========");
- L.l("============X:" + ev.getX() + " Y:" + ev.getY());
- int x = (int) ev.getX();
- int y = (int) ev.getY();
- L.l("============X:" + x + " Y:" + y);
- dragPosition = dropPosition = pointToPosition(x, y);
- System.out.println(dragPosition);
- if (dragPosition == AdapterView.INVALID_POSITION)
- {
- }
- ViewGroup itemView = (ViewGroup) getChildAt(dragPosition
- - getFirstVisiblePosition());
- // 得到当前点在item内部的偏移量 即相对于item左上角的坐标
- dragPointX = x - itemView.getLeft();
- dragPointY = y - itemView.getTop();
- dragOffsetX = (int) (ev.getRawX() - x);
- dragOffsetY = (int) (ev.getRawY() - y);
- itemHeight=itemView.getHeight();
- L.l("========================y:" + y + " getRawY:"
- + ev.getRawY());
- // 解决问题3
- // 每次都销毁一次cache,重新生成一个bitmap
- itemView.destroyDrawingCache();
- itemView.setDrawingCacheEnabled(true);
- Bitmap bm = Bitmap.createBitmap(itemView.getDrawingCache());
- // 建立item的缩略图
- startDrag(bm, x, y);
- return false;
- };
- });
- return super.onInterceptTouchEvent(ev);
- }
- @Override
- public boolean onInterceptTouchEvent(MotionEvent ev)
- {
- if (ev.getAction() == MotionEvent.ACTION_DOWN)
- {
- return setOnItemLongClickListener(ev);
- }
- return super.onInterceptTouchEvent(ev);
- }
- private void startDrag(Bitmap bm, int x, int y)
- {
- stopDrag();
- windowParams = new WindowManager.LayoutParams();
- System.out.println("X: " + x + " dragPointX: " + dragPointX
- + " dragOffsetX: " + dragOffsetX);
- windowParams.gravity = Gravity.TOP | Gravity.LEFT;// 这个必须加
- // 得到preview左上角相对于屏幕的坐标
- windowParams.x = x - dragPointX + dragOffsetX;
- windowParams.y = y - dragPointY + dragOffsetY;
- // L.l("==================windowParams.y==============="+windowParams.y);
- // 设置宽和高
- windowParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
- windowParams.width = 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.format = PixelFormat.TRANSLUCENT;
- windowParams.windowAnimations = 0;
- ImageView iv = new ImageView(getContext());
- iv.setImageBitmap(bm);
- windowManager = (WindowManager) getContext().getSystemService(
- Context.WINDOW_SERVICE);// "window"
- windowManager.addView(iv, windowParams);
- dragImageView = iv;
- }
- @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:
- onDrag(x, y);
- break;
- case MotionEvent.ACTION_UP:
- stopDrag();
- onDrop(x, y);
- break;
- }
- }
- return super.onTouchEvent(ev);
- }
- private void onDrag(int x, int y)
- {
- if (dragImageView != null)
- {
- windowParams.alpha = 0.6f;
- windowParams.x = x - dragPointX + dragOffsetX;
- windowParams.y = y - dragPointY + dragOffsetY;
- // L.l("=================windowParams.y=====000========"+windowParams.y);
- windowManager.updateViewLayout(dragImageView, windowParams);
- }
- int tempScrollX = x - dragPointX + dragOffsetX;
- int tempScrollY = y - dragPointY + dragOffsetY;
- if (tempScrollY +itemHeight> 600)
- {
- this.scrollTo(0, tempScrollY);
- }
- else
- if (pointToPosition(x, y) > 2)
- {
- this.scrollTo(0, tempScrollY - 300);
- }
- }
- private void onDrop(int x, int y)
- {
- int tempPosition = pointToPosition(x, y);
- if (tempPosition != AdapterView.INVALID_POSITION)
- {
- dropPosition = tempPosition;
- }
- if (dropPosition != dragPosition)
- {
- System.out.println("dragPosition: " + dragPosition
- + " dropPosition: " + dropPosition);
- ImageAdapter adapter = (ImageAdapter) this.getAdapter();
- adapter.exchange(dragPosition, dropPosition);
- // 解决问题3
- /*
- * ViewGroup itemView1 = (ViewGroup)getChildAt(dragPosition - getFirstVisiblePosition()); ViewGroup
- * itemView2 = (ViewGroup)getChildAt(dropPosition - getFirstVisiblePosition());
- * itemView1.destroyDrawingCache(); itemView2.destroyDrawingCache();
- */
- }
- }
- private void stopDrag()
- {
- if (dragImageView != null)
- {
- windowManager.removeView(dragImageView);
- dragImageView = null;
- }
- }
- }
- package com.pl;
- import android.app.Activity;
- import android.content.Context;
- import android.os.Bundle;
- import android.view.LayoutInflater;
- import android.view.View;
- import android.view.ViewGroup;
- import android.widget.AdapterView;
- import android.widget.AdapterView.OnItemClickListener;
- import android.widget.BaseAdapter;
- import android.widget.ImageView;
- import android.widget.TextView;
- import java.util.ArrayList;
- import java.util.List;
- public class MainActivity extends Activity {
- private DragGridView gv;
- private List<String> list = new ArrayList<String>();
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- initData();
- gv = (DragGridView)findViewById(R.id.drag_grid);
- gv.setAdapter(new ImageAdapter(this));
- gv.setOnItemClickListener(new OnItemClickListener()
- {
- @Override
- public void onItemClick(AdapterView<?> parent, View view,
- int position, long id)
- {
- // TODO Auto-generated method stub
- L.l("============onItemClick====position:"+position);
- }
- } );
- }
- private void initData(){
- for(int i=1;i<100;i++){
- list.add(""+i);
- }
- }
- public class ImageAdapter extends BaseAdapter{
- private Context mContext;
- private LayoutInflater lif;
- public ImageAdapter(Context c){
- mContext = c;
- lif = LayoutInflater.from(c);
- }
- public int getCount() {
- return list.size();
- }
- public Object getItem(int position) {
- // TODO Auto-generated method stub
- return list.get(position);
- }
- public long getItemId(int position) {
- // TODO Auto-generated method stub
- return position;
- }
- /**
- * 遇到的问题:
- * 1、删除错了 会有重复的图片
- * 这个是由 remove引起的
- * 删除时 我们先删除了小的position
- * 比如说 startPosition = 2;endPosition = 3;
- * 当我先删startPosition时 这时 删除前position为3的项 已经是position为2了
- * 2、数组越界 异常
- * 这个是由 add引起的
- * 比如说 startPosition = 8;endPosition = 7;
- * 一共gridview有9个元素 也就是说8 已经是最大的了
- * 当删除完后 你先增加爱 startposition时 就会异常了
- * 3、preview问题
- * 当我拖拽互换几次后 机会出现 当前的图片 显示的是另一个图片的preview
- *
- * 得调用 destroyDrawingCache
- * @param startPosition
- * @param endPosition
- */
- public void exchange(int startPosition, int endPosition){
- //比较一下 使startPosition永远小于endPosition的值 解决问题1 ,2
- if(startPosition > endPosition){
- int temp = endPosition;
- endPosition = startPosition;
- startPosition = temp;
- }
- Object endObject = getItem(endPosition);
- Object startObject = getItem(startPosition);
- //list.remove(endPosition);
- //list.remove(startPosition);
- System.out.println(startPosition + "========"+endPosition);
- list.set(startPosition,(String)endObject);
- list.set(endPosition,(String)startObject);
- notifyDataSetChanged();
- }
- public View getView(int position, View convertView, ViewGroup parent) {
- //ImageView iv;
- if(convertView==null){
- convertView = lif.inflate(R.layout.grid_item, null);
- // iv = new ImageView(mContext);
- // try{
- // Field f = (Field)R.drawable.class.getDeclaredField(list.get(position));
- // int i = f.getInt(R.drawable.class);
- // iv.setImageResource(i);
- // }catch(Exception e){
- // e.printStackTrace();
- // }
- }
- try {
- TextView textView=(TextView)convertView.findViewById(R.id.textView);
- textView.setText(list.get(position));
- ImageView imgView=(ImageView)convertView.findViewById(R.id.image);
- imgView.setBackgroundResource(R.drawable.icon);
- } catch (Exception e) {
- e.printStackTrace();
- }
- return convertView;
- }
- }
- }
三.完整代码如下下载
http://download.csdn.net/detail/synwith/3693769