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

来源:互联网 发布:linux sqlplus 安装 编辑:程序博客网 时间:2024/06/05 17:04

先上效果图,看看是不是你想要的效果,运行效果挺好,代码量不大,也没有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);    }}

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

0 0
原创粉丝点击