package
com.jj.drag;
import
android.content.Context;
import
android.graphics.Bitmap;
import
android.graphics.Color;
import
android.os.AsyncTask;
import
android.util.AttributeSet;
import
android.util.Log;
import
android.view.Gravity;
import
android.view.MotionEvent;
import
android.view.View;
import
android.view.ViewConfiguration;
import
android.view.ViewGroup;
import
android.view.WindowManager;
import
android.widget.AbsListView;
import
android.widget.AbsListView.OnScrollListener;
import
android.widget.AdapterView;
import
android.widget.ImageView;
import
android.widget.ListView;
import
com.jj.drag.MainActivity.DragListAdapter;
public
class
DragListView
extends
ListView {
private
WindowManager windowManager;
private
WindowManager.LayoutParams windowParams;
private
int
scaledTouchSlop;
private
ImageView dragImageView;
private
int
dragSrcPosition;
private
int
dragPosition;
private
int
dragPoint;
private
int
dragOffset;
private
int
upScrollBounce;
private
int
downScrollBounce;
private
final
static
int
step =
1
;
private
int
current_Step;
private
int
temChangId;
private
boolean
isLock;
public
void
setLock(
boolean
isLock) {
this
.isLock = isLock;
}
public
DragListView(Context context, AttributeSet attrs) {
super
(context, attrs);
scaledTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
}
/***
* touch事件拦截 在这里我进行相应拦截,
*/
@Override
public
boolean
onInterceptTouchEvent(MotionEvent ev) {
if
(ev.getAction() == MotionEvent.ACTION_DOWN && !isLock) {
int
x = (
int
) ev.getX();
int
y = (
int
) ev.getY();
temChangId = dragSrcPosition = dragPosition = pointToPosition(x, y);
if
(dragPosition == AdapterView.INVALID_POSITION) {
return
super
.onInterceptTouchEvent(ev);
}
ViewGroup itemView = (ViewGroup) getChildAt(dragPosition
- getFirstVisiblePosition());
dragPoint = y - itemView.getTop();
dragOffset = (
int
) (ev.getRawY() - y);
View dragger = itemView.findViewById(R.id.iv_drag_list_item_2);
if
(dragger !=
null
&& x > dragger.getLeft() -
20
) {
upScrollBounce = getHeight() /
3
;
downScrollBounce = getHeight() *
2
/
3
;
itemView.setBackgroundColor(Color.BLUE);
itemView.setDrawingCacheEnabled(
true
);
Bitmap bm = Bitmap.createBitmap(itemView.getDrawingCache());
startDrag(bm, y);
}
return
false
;
}
return
super
.onInterceptTouchEvent(ev);
}
/**
* 触摸事件处理
*/
@Override
public
boolean
onTouchEvent(MotionEvent ev) {
if
(dragImageView !=
null
&& dragPosition != INVALID_POSITION
&& !isLock) {
int
action = ev.getAction();
switch
(action) {
case
MotionEvent.ACTION_UP:
int
upY = (
int
) ev.getY();
stopDrag();
onDrop(upY);
break
;
case
MotionEvent.ACTION_MOVE:
int
moveY = (
int
) ev.getY();
onDrag(moveY);
break
;
case
MotionEvent.ACTION_DOWN:
break
;
default
:
break
;
}
return
true
;
}
return
super
.onTouchEvent(ev);
}
/**
* 准备拖动,初始化拖动项的图像
*
* @param bm
* @param y
*/
private
void
startDrag(Bitmap bm,
int
y) {
/***
* 初始化window.
*/
windowParams =
new
WindowManager.LayoutParams();
windowParams.gravity = Gravity.TOP;
windowParams.x =
0
;
windowParams.y = y - dragPoint + dragOffset;
windowParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
windowParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
windowParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
| WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
| WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
windowParams.windowAnimations =
0
;
ImageView imageView =
new
ImageView(getContext());
imageView.setImageBitmap(bm);
windowManager = (WindowManager) getContext().getSystemService(
"window"
);
windowManager.addView(imageView, windowParams);
dragImageView = imageView;
}
/**
* 拖动执行,在Move方法中执行
*
* @param y
*/
public
void
onDrag(
int
y) {
int
drag_top = y - dragPoint;
if
(dragImageView !=
null
&& drag_top >=
0
) {
windowParams.alpha =
0
.5f;
windowParams.y = y - dragPoint + dragOffset;
windowManager.updateViewLayout(dragImageView, windowParams);
}
int
tempPosition = pointToPosition(
0
, y);
if
(tempPosition != INVALID_POSITION) {
dragPosition = tempPosition;
}
onChange(y);
doScroller(y);
}
/***
* ListView的移动.
* 要明白移动原理:当我移动到下端的时候,ListView向上滑动,当我移动到上端的时候,ListView要向下滑动。正好和实际的相反.
*
*/
public
void
doScroller(
int
y) {
if
(y < upScrollBounce) {
current_Step = step + (upScrollBounce - y) /
10
;
}
else
if
(y > downScrollBounce) {
current_Step = -(step + (y - downScrollBounce)) /
10
;
}
else
{
current_Step =
0
;
}
View view = getChildAt(dragPosition - getFirstVisiblePosition());
setSelectionFromTop(dragPosition, view.getTop() + current_Step);
}
/**
* 停止拖动,删除影像
*/
public
void
stopDrag() {
if
(dragImageView !=
null
) {
windowManager.removeView(dragImageView);
dragImageView =
null
;
}
}
/***
* 拖动时时change
*/
private
void
onChange(
int
y) {
if
(dragPosition < getAdapter().getCount()) {
DragListAdapter adapter = (DragListAdapter) getAdapter();
adapter.isHidden =
false
;
if
(dragPosition != temChangId) {
adapter.update(temChangId, dragPosition);
temChangId = dragPosition;
}
}
int
tempPosition = pointToPosition(
0
, y);
if
(tempPosition != INVALID_POSITION) {
dragPosition = tempPosition;
}
if
(y < getChildAt(
0
).getTop()) {
dragPosition =
0
;
}
else
if
(y > getChildAt(getChildCount() -
1
).getBottom()) {
dragPosition = getAdapter().getCount() -
1
;
}
}
/**
* 拖动放下的时候
*
* @param y
*/
public
void
onDrop(
int
y) {
if
(dragPosition < getAdapter().getCount()) {
DragListAdapter adapter = (DragListAdapter) getAdapter();
adapter.isHidden =
false
;
adapter.notifyDataSetChanged();
}
}
}