自定义GridView,实现item之间相互滑动

先上效果图,看看是不是你想要的效果,运行效果挺好,代码量不大,也没有bug,你如果也想要这种效果,就果断选它吧。

运行效果

这里说明一下,有两种状态,无论编辑还是完成,这里设置的是都可以进行图片拖动,区别再去,编辑时图片可以删除,还有注意的是点击添加这张图片和别的图片不能拖动互换,要想同样拖动互换,可以在Gridview里面进行修改,去掉后面的判断就可以了,点击添加图片,可以从相册,照相机里去添加,当然我这里简化了,你可以自己去实现这部分代码,也很简单,有问题,请留言,欢迎大家拍砖…

代码里都有相关注释,这里上传部分代码,完整代码下面会给链接,用到的可以去下载一下:

主界面MainActivity:

public class MainActivity extends AppCompatActivity {
    private TextView tv_edit;
    private DragGridView dragview;
    private List<Bitmap> mDatas;
    private GridViewAdapter adapter;
    private boolean flag = true;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        setTitle("DragView");
        initDatas();
        initView();
    }

    private void initDatas() {
        mDatas = new ArrayList<>();
        turnBitmap(R.drawable.a);
        turnBitmap(R.drawable.b);
        turnBitmap(R.drawable.c);
        turnBitmap(R.drawable.d);
        turnBitmap(R.drawable.e);
        turnBitmap(R.drawable.f);
        turnBitmap(R.drawable.add_picture);

    }

    private void turnBitmap(int drawableId) {
        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), drawableId);
        mDatas.add(bitmap);
    }

    private void initView() {
        tv_edit = (TextView) findViewById(R.id.tv_edit);
        dragview = (DragGridView) findViewById(R.id.dragview);
        adapter = new GridViewAdapter(this, mDatas, flag);
        dragview.setAdapter(adapter);
        tv_edit.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (flag) {
                    tv_edit.setText("完成");
                    flag = false;
                } else {
                    tv_edit.setText("编辑");
                    flag = true;
                }
                adapter.setFlag(flag);
                adapter.notifyDataSetChanged();
            }
        });
    }

}

自定义GridView代码(这个是关键):

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;
    private static DragGridView dragGridView;
    private OnItemLongClickListener onLongClickListener = new OnItemLongClickListener() {

        @Override
        //长按item开始拖动
        public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
            //记录长按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.valueOf(dragImageView.getTag().toString()) == 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不显示
            ((GridViewAdapter) getAdapter()).hideView(position);
            getParent().requestDisallowInterceptTouchEvent(true);
            return false;
        }
    };

    @Override
    public void setOnItemClickListener(OnItemClickListener listener) {
        super.setOnItemClickListener(listener);
    }

    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);
    }

    public static DragGridView getInstance(Context context) {
        if (null == dragGridView) {
            dragGridView = new DragGridView(context);
        }
        return dragGridView;
    }

    @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)) {
            Log.i("Tag", "" + 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) && (currDraggedPosition != getAdapter().getCount() - 1)
                    && (preDraggedOverPositon != getAdapter().getCount() - 1)
                    ) {
                ((GridViewAdapter) getAdapter()).swapView(preDraggedOverPositon, currDraggedPosition);
                preDraggedOverPositon = currDraggedPosition;
            }
            getParent().requestDisallowInterceptTouchEvent(true);
        }
        //释放dragImageView
        else if ((ev.getAction() == MotionEvent.ACTION_UP) && (isViewOnDrag == true)) {
            ((GridViewAdapter) getAdapter()).showHideView();
            if (Integer.valueOf(dragImageView.getTag().toString()) == DRAG_IMG_SHOW) {
                windowManager.removeView(dragImageView);
                dragImageView.setTag(DRAG_IMG_NOT_SHOW);
            }
            isViewOnDrag = false;

            getParent().requestDisallowInterceptTouchEvent(false);
        }
        return super.onTouchEvent(ev);
    }

    public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,
                MeasureSpec.AT_MOST);
        super.onMeasure(widthMeasureSpec, expandSpec);

    }
}

adapter类:

public class GridViewAdapter extends BaseAdapter {
    private List<Bitmap> mDatas;
    private Context mContext;
    private LayoutInflater inflater;
    private boolean flag=true;
    /**
     * 点击影藏的position
     */
    private int hidePosition = AdapterView.INVALID_POSITION;
    private DisplayMetrics metrics;

    public GridViewAdapter(Context context, List<Bitmap> mDatas, boolean flag) {
        this.mContext = context;
        this.mDatas = mDatas;
        inflater = LayoutInflater.from(mContext);
        metrics = mContext.getResources().getDisplayMetrics();
    }

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

    @Override
    public Bitmap getItem(int position) {
        return mDatas.get(position);
    }

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

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        ViewHolder holder = null;
        if (convertView == null) {
            convertView = inflater.inflate(R.layout.images_gallary_item,
                    null);
            holder = new ViewHolder();
            holder.ivThumb = (ImageView) convertView
                    .findViewById(R.id.iv_cs_gallay_item);
            holder.ivThumb.setLayoutParams(new RelativeLayout.LayoutParams(
                    setWidth_px(), setWidth_px() * 3 / 4));
            holder.ivThumb.setScaleType(ImageView.ScaleType.CENTER_CROP);
            holder.tvdelete = (ImageView) convertView
                    .findViewById(R.id.iv_cs_gallay_delete);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }
        if (! flag && position !=mDatas.size()-1) {
            holder.tvdelete.setVisibility(View.VISIBLE);
        } else {
            holder.tvdelete.setVisibility(View.INVISIBLE);
        }

        final Bitmap bitmap = mDatas.get(position);
        if (bitmap != null) {
            holder.ivThumb.setImageBitmap(bitmap);
        }


        holder.tvdelete.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mDatas.remove(position);
                notifyDataSetChanged();
            }
        });

        //hide时隐藏imageview
        if (position != hidePosition) {
            convertView.setVisibility(View.VISIBLE);
        } else {
            convertView.setVisibility(View.INVISIBLE);
        }
        convertView.setId(position);

        return convertView;
    }

    class ViewHolder {
        private ImageView ivThumb;
        private ImageView tvdelete;
    }

    public void setFlag(boolean flag) {
        this.flag = flag;
    }

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

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

    /**
     * 更新拖动时的gridView
     *
     * @param draggedPos 拖动的position
     * @param destPos    目表position
     */
    public void swapView(int draggedPos, int destPos) {
        //从前向后拖动,其他item依次前移
        if (draggedPos < destPos) {
            mDatas.add(destPos + 1, getItem(draggedPos));
            mDatas.remove(draggedPos);
        }
        //从后向前拖动,其他item依次后移
        else if (draggedPos > destPos) {
            mDatas.add(destPos, getItem(draggedPos));
            mDatas.remove(draggedPos + 1);
        }
        hidePosition = destPos;
        //       notifyDataSetChanged();
    }

    public int setWidth_px() {
        return dip2px((px2dip(metrics.widthPixels) - 24 - 24) / 3);
    }

    public int dip2px(float dipValue) {
        final float scale = mContext.getResources()
                .getDisplayMetrics().density;
        return (int) (dipValue * scale + 0.5f);
    }

    public int px2dip(float pxValue) {
        final float scale = mContext.getResources()
                .getDisplayMetrics().density;
        return (int) (pxValue / scale + 0.5f);
    }


}

好了,有问题可以留言,欢迎拍砖,完整代码:点击这里进行下载

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值