自定义控件之可拖拽gridview

  1. 先写适配器,因为需要适配器来操控显示和调换item


public class GirdViewAdapter extends BaseAdapter {
    private Context context;
    private List<ChanneListBean> beans;
    private int hidePosition = AdapterView.INVALID_POSITION;

    public GirdViewAdapter(Context context, List<ChanneListBean> beans) {
        this.context = context;
        this.beans = beans;
    }

    @Override
    public int getCount() {
        return beans.size();
    }

    @Override
    public ChanneListBean getItem(int position) {
        return beans.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder viewHolder = null;
        if(convertView == null) {
        	convertView = LayoutInflater.from(context).inflate(R.layout.items_channel, null);
        	viewHolder = new ViewHolder();
        	viewHolder.tv_channel = (TextView) convertView.findViewById(R.id.tv_channels);
        	convertView.setTag(viewHolder);
        }
        else {
            viewHolder = (ViewHolder) convertView.getTag();
        }

        //hide时隐藏Text
         if(position != hidePosition) {
            viewHolder.tv_channel.setTextSize(15);
            if (beans.get(position).getName().trim().length() == 5 ) {
            	viewHolder.tv_channel.setText(beans.get(position).getName().trim().substring(0,3));
			}
			else {
				viewHolder.tv_channel.setText(beans.get(position).getName().trim().substring(0,2));
			}
           
        }
        else {
            viewHolder.tv_channel.setText("");
        }
        viewHolder.tv_channel.setId(position);

        return convertView;
    }

    public void hideView(int pos) {
        hidePosition = pos;
        notifyDataSetChanged();
    }

    public void showHideView() {
        hidePosition = AdapterView.INVALID_POSITION;
        notifyDataSetChanged();
    }

    public void removeView(int pos) {
        beans.remove(pos);
        notifyDataSetChanged();
    }

    //更新拖动时的gridView
    public void swapView(int draggedPos, int destPos) {
        //从前向后拖动,其他item依次前移
    	if (destPos < 2) {
			Logutil.e("前面去不了啦");
			
		}else {
			if(draggedPos < destPos) {
	            beans.add(destPos+1, getItem(draggedPos));
	            beans.remove(draggedPos);
	        }
	        //从后向前拖动,其他item依次后移
	        else if(draggedPos > destPos) {
	            beans.add(destPos, getItem(draggedPos));
	            beans.remove(draggedPos+1);
	        }
	        hidePosition = destPos;
	        notifyDataSetChanged();
		}
        
    }
    
     class ViewHolder{
    	TextView tv_channel;
    }
    
}
  1. 再写可拖拽的girdview
public class DragGridView extends GridView {

    private static final int DRAG_IMG_SHOW = 1;
    private static final int DRAG_IMG_NOT_SHOW = 0;
    private static final float AMP_FACTOR = 1.2f;

    /**被拖动的视图*/
    private ImageView dragImageView;
    private WindowManager.LayoutParams dragImageViewParams;
    private WindowManager windowManager;
    private boolean isViewOnDrag = false;

    /**前一次拖动的位置*/
    private int preDraggedOverPositon = AdapterView.INVALID_POSITION;
    private int downRawX;
    private int downRawY;

    /**长按选中拖动item*/
    private OnItemLongClickListener onLongClickListener = new OnItemLongClickListener(){

        @Override
        //长按item开始拖动
        public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
        	if (position ==0 || position == 1) {
				Logutil.e( "这两个位置不可变");
				return true;
			}else {
				//记录长按item位置
	            preDraggedOverPositon = position;

	            //获取被长按item的drawing cache
	            view.destroyDrawingCache();
	            view.setDrawingCacheEnabled(true);
	            //通过被长按item,获取拖动item的bitmap
	            Bitmap dragBitmap = Bitmap.createBitmap(view.getDrawingCache());

	            //设置拖动item的参数
	            dragImageViewParams.gravity = Gravity.TOP | Gravity.LEFT;
	            //设置拖动item为原item 1.2倍
	            dragImageViewParams.width = (int)(AMP_FACTOR*dragBitmap.getWidth());
	            dragImageViewParams.height = (int)(AMP_FACTOR*dragBitmap.getHeight());
	            //设置触摸点为绘制拖动item的中心
	            dragImageViewParams.x = (downRawX - dragImageViewParams.width/2);
	            dragImageViewParams.y = (downRawY - dragImageViewParams.height/2);
	            dragImageViewParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
	                                        | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
	                                        | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
	                                        | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
	            dragImageViewParams.format = PixelFormat.TRANSLUCENT;
	            dragImageViewParams.windowAnimations = 0;

	            //dragImageView为被拖动item的容器,清空上一次的显示
	            if ((Integer)dragImageView.getTag() == DRAG_IMG_SHOW) {
	                windowManager.removeView(dragImageView);
	                dragImageView.setTag(DRAG_IMG_NOT_SHOW);
	            }

	            //设置本次被长按的item
	            dragImageView.setImageBitmap(dragBitmap);

	            //添加拖动item到屏幕
	            windowManager.addView(dragImageView, dragImageViewParams);
	            dragImageView.setTag(DRAG_IMG_SHOW);
	            isViewOnDrag = true;

	            //设置被长按item不显示
	            ((GirdViewAdapter)getAdapter()).hideView(position);
	            return true;
			}

            
        }
    };

    public DragGridView(Context context) {
        super(context);
        initView();
    }

    public DragGridView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initView();
    }

    public DragGridView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initView();
    }

    public void initView() {
        setOnItemLongClickListener(onLongClickListener);
        //初始化显示被拖动item的image view
        dragImageView = new ImageView(getContext());
        dragImageView.setTag(DRAG_IMG_NOT_SHOW);
        //初始化用于设置dragImageView的参数对象
        dragImageViewParams = new WindowManager.LayoutParams();
        //获取窗口管理对象,用于后面向窗口中添加dragImageView
        windowManager = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
    }


    @Override
    public boolean onTouchEvent(MotionEvent ev) {

        //被按下时记录按下的坐标
        if(ev.getAction() == MotionEvent.ACTION_DOWN) {
            //获取触摸点相对于屏幕的坐标
            downRawX = (int)ev.getRawX();
            downRawY = (int)ev.getRawY();
        }
        //dragImageView处于被拖动时,更新dragImageView位置
        else if((ev.getAction() == MotionEvent.ACTION_MOVE) && (isViewOnDrag == true)) {
            Logutil.i("" + ev.getRawX() + " " + ev.getRawY());
            //设置触摸点为dragImageView中心
            dragImageViewParams.x = (int)(ev.getRawX() - dragImageView.getWidth()/2);
            dragImageViewParams.y = (int)(ev.getRawY() - dragImageView.getHeight()/2);
            //更新窗口显示
            windowManager.updateViewLayout(dragImageView, dragImageViewParams);
            //获取当前触摸点的item position
            int currDraggedPosition = pointToPosition((int)ev.getX(), (int)ev.getY());
            //如果当前停留位置item不等于上次停留位置的item,交换本次和上次停留的item
            if((currDraggedPosition != AdapterView.INVALID_POSITION) && (currDraggedPosition != preDraggedOverPositon)) {
                ((GirdViewAdapter)getAdapter()).swapView(preDraggedOverPositon, currDraggedPosition);
                preDraggedOverPositon = currDraggedPosition;
            }
        }
        //释放dragImageView
        else if((ev.getAction() == MotionEvent.ACTION_UP) && (isViewOnDrag == true)) {
            ((GirdViewAdapter)getAdapter()).showHideView();
            if((Integer)dragImageView.getTag() == DRAG_IMG_SHOW) {
                windowManager.removeView(dragImageView);
                dragImageView.setTag(DRAG_IMG_NOT_SHOW);
            }
            isViewOnDrag = false;
        }
        return super.onTouchEvent(ev);
    }
}

转载于:https://my.oschina.net/u/3292760/blog/844838

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值