在写这篇文章前,碰巧看到有个哥们也做了这个功能,【Android】可拖拽排序的ListView。而且就在几个小时前发表的,本来想还是算了,我就不写这个功能,不过我大致浏览了他的实现原理跟我的实现原理还是有很大差别,所以还是决定写这样一篇文章,因为我相信大家看文章,更多是想了解其中的原理,而非单纯的为了实现某个功能。只有了解了原理,才能扩展,实现更多的功能。
好了,回到正题,先来看效果图
分析原理
1、长按获取所按 Item 的 View,并通过View 生成一个 Drawable;
2、 在 ListView 中根据手势滑动不断的绘制 Drawable;
3、Drawable每到达另一个 Item的位置,就替换这个 item,并设置动画效果;
4、当 Drawable 滑到屏幕的最下方或者最上方,且此 ListView 可以滚动,这 listView 执行滚动。
开篇就讲了,此功能的实现方式不止一种,所以有兴趣了解其他实现原理可以看 [【Android】可拖拽排序的ListView]这篇文章。
分步实现
这里就按照原理来一步一步实现此功能,先来看如何获取 Drawable
通过 View 获取 bitmapDrawable
通过 position 获取 View
/*获取Item的View*/
View mobileView = getViewForPosition(position);
因为我们一般在 ListView 的 adapter 中都会复用 View,所以这里需要做一个 position 的转化
/**
* 通过位置获取View
*
* @param position
* @return
*/
public View getViewForPosition(int position) {
int itemPosition = position - getFirstVisiblePosition();
View view = getChildAt(itemPosition);
return view;
}
通过 View,获取 Drawable
/**
* 创建一个
* BitmapDrawable
* @param view
* @return
*/
private BitmapDrawable createDrawable(View view) {
BitmapDrawable bitmapDrawable = null;
/*获取位置变量*/
int left = view.getLeft();
int top = view.getTop();
int right = left + view.getMeasuredWidth();
int bottom = top + view.getMeasuredHeight();
/*首先创建一个Bitmap,这个位图为空位图,里面啥也没有*/
Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888);
/*创建一个画布,把空位图放入画布中*/
Canvas canvas = new Canvas(bitmap);
/*把所选的item的View 绘制到画布上,其实也就是会知道了Bitmap上*/
view.draw(canvas);
/*绘制边矩形*/
Rect rect = new Rect(0,0,bitmap.getWidth(),bitmap.getHeight()) ;
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG) ;
paint.setStrokeWidth(12);
paint.setStyle(Paint.Style.STROKE);
paint.setColor(0xff1f8c03);
canvas.drawRect(rect, paint);
/*把bitmap转化成BitmapDrawable*/
bitmapDrawable = new BitmapDrawable(getResources(), bitmap);
/*设置drawable的原始位置*/
mCellOriginBounds = new