先上效果图,看看是不是你想要的效果,运行效果挺好,代码量不大,也没有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);
}
}
好了,有问题可以留言,欢迎拍砖,完整代码:点击这里进行下载