Layout:
<?xml version="1.0" encoding="UTF-8"?>
<com.example.android_test.MyDragLayer xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/rootView"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<com.example.android_test.MyLinearlayout
android:id="@+id/linear"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
</com.example.android_test.MyLinearlayout>
</com.example.android_test.MyDragLayer>
MyLinearLayout,带详细注释
public class MyLinearlayout extends RelativeLayout {
private View mDragView;
private Bitmap mDragBitmap = null;
private int mBitmapOffsetX;
private int mBitmapOffsetY;
private boolean mDragging = false;
public MyDragLayer mDragLayer;
/**
* X offset from where we touched on the cell to its upper-left corner
*/
private float mTouchOffsetX;
/**
* Y offset from where we touched on the cell to its upper-left corner
*/
private float mTouchOffsetY;
private static final float DRAG_SCALE = 18.0f; // 放大多少
private float mLastMotionX;
private float mLastMotionY;
private ImageView mView;
public MyLinearlayout(Context context, AttributeSet attrs) {
super(context, attrs);
inflate(context, R.layout.relative_ex, this);
init(context);
}
private void init(Context context) {
final int top = this.getResources().getDimensionPixelSize(R.dimen.top);
final ImageView image1 = (ImageView) findViewById(R.id.item1);
final ImageView image2 = (ImageView) findViewById(R.id.item2);
final int x = 50;
final int y = top;
mView = image2;
final int switch_to_left = 50;
//点击btn1的时候image1将移动到距离屏幕左边50的位置
Button btn1 = (Button) findViewById(R.id.btn1);
btn1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// final MyTranslateAnimation ani = new MyTranslateAnimation(
// image1.getLeft() - switch_to_left, 0, image1.getTop()
// - y, 0);
// // TranslateAnimation(float fromXDelta, float toXDelta, float
// // fromYDelta, float toYDelta)
// // float fromXDelta:这个参数表示动画开始的点离当前View X坐标上的差值;
// // float toXDelta, 这个参数表示动画结束的点离当前View X坐标上的差值;
// // 如果view在A(x,y)点 那么动画就是从B点(x+fromXDelta, y+fromYDelta)点移动到C
// // 点(x+toXDelta,y+toYDelta)点.
//
// ani.setDuration(300);
// ani.dstX = switch_to_left;
// ani.dstY = y;
// // ani.setFillBefore(true);
// ani.view = image1;
//
// //这个使view最后停留在距离左边switch_to_left的位置
// ani.view.layout(ani.dstX, ani.dstY,
// ani.dstX + ani.view.getWidth(),
// ani.dstY + ani.view.getHeight());
//
// ani.setAnimationListener(new Animation.AnimationListener() {
// public void onAnimationStart(Animation animation) {
// }
//
// public void onAnimationRepeat(Animation animation) {
// }
//
// public void onAnimationEnd(Animation animation) {
// ani.view.setVisibility(View.VISIBLE);
// }
// });
//
// image1.setVisibility(View.INVISIBLE);
// image1.startAnimation(ani);
TranslateAnimation trans = new TranslateAnimation(0,-switch_to_left,0,0);
trans.setFillAfter(true);
trans.setDuration(300);
image1.startAnimation(trans);
}
});
//长按mView可以获取它的cache并移动
mView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
startDrag();
return false;
}
});
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
// System.out.println("onInterceptTouchEvent:" + ev);
int action = ev.getAction();
final float x = ev.getX();
final float y = ev.getY();
if (action == MotionEvent.ACTION_DOWN) {
mLastMotionX = x;
mLastMotionY = y;
requestFocus();
}
if (mDragging) {
return true;
}
return super.onInterceptTouchEvent(ev);
}
class MyTranslateAnimation extends TranslateAnimation {
public int dstX;
public int dstY;
public View view;
public MyTranslateAnimation(float fromXDelta, float toXDelta,
float fromYDelta, float toYDelta) {
super(fromXDelta, toXDelta, fromYDelta, toYDelta);
}
}
public void startDrag() {
View view = mView;
if (view != null) {
mDragView = view;
mDragging = true;
//本身这个view先置为invisible
view.setVisibility(View.INVISIBLE);
Rect r = new Rect();
r.set(view.getScrollX(), view.getScrollY(), 0, 0);
//把view组件的坐标转化为同一坐标系上
offsetDescendantRectToMyCoords(view, r);
//mTouchOffsetX为手指相对view的点击位置
mTouchOffsetX = mLastMotionX - r.left;
mTouchOffsetY = mLastMotionY - r.top;
view.clearFocus();
view.setPressed(false);
boolean willNotCache = view.willNotCacheDrawing();
view.setWillNotCacheDrawing(false);
// Reset the drawing cache background color to fully transparent
// for the duration of this operation
int color = view.getDrawingCacheBackgroundColor();
view.setDrawingCacheBackgroundColor(0);
//如果有cache则先destroy
if (color != 0) {
view.destroyDrawingCache();
}
//buildDrawingCache后才可以用getDrawingCache取到view的bitmap
view.buildDrawingCache();
Bitmap viewBitmap = view.getDrawingCache();
int width = viewBitmap.getWidth();
int height = viewBitmap.getHeight();
Matrix scale = new Matrix();
float scaleFactor = view.getWidth();
scaleFactor = (scaleFactor + DRAG_SCALE) / scaleFactor;
scale.setScale(scaleFactor, scaleFactor);
mDragBitmap = Bitmap.createBitmap(viewBitmap, 0, 0, width, height,
scale, true);
//这里destroy这个cache
view.destroyDrawingCache();
view.setWillNotCacheDrawing(willNotCache);
view.setDrawingCacheBackgroundColor(color);
final Bitmap dragBitmap = mDragBitmap;
mBitmapOffsetX = (dragBitmap.getWidth() - width) / 2;
mBitmapOffsetY = (dragBitmap.getHeight() - height) / 2;
invalidate();
mDragLayer.startDrag(mDragBitmap,
(int) (mTouchOffsetX + mBitmapOffsetX),
(int) (mTouchOffsetY + mBitmapOffsetY));
}
}
}
MyDragLayer:
public class MyDragLayer extends FrameLayout {
/**
* The bitmap that is currently being dragged
*/
private Bitmap mDragBitmap = null;
private float mLastMotionX;
private float mLastMotionY;
private float mOffsetX;
private float mOffsetY;
private Paint mDragPaint;
private static final int TRANSITION_DURATION = 250;
public MyDragLayer(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
mLastMotionX = ev.getX();
mLastMotionY = ev.getY();
int dx = 0;
int dy = 0;
invalidate();
boolean result = super.onInterceptTouchEvent(ev);
return result;
}
@Override
protected void <strong>dispatchDraw</strong>(Canvas canvas) { <strong>//这个方法才能时获取的cache在屏幕上随着手指移动</strong>
super.dispatchDraw(canvas);
if (mDragBitmap != null && !mDragBitmap.isRecycled()) {
// Draw actual icon being dragged
canvas.drawBitmap(mDragBitmap, getScrollX() + mLastMotionX
- mOffsetX, getScrollY() + mLastMotionY - mOffsetY,
mDragPaint);
}
}
public void startDrag(Bitmap bitmap, int offsetx, int offsety) { <strong>//这个方法传入Bitmap</strong>
mDragBitmap = bitmap;
mOffsetX = offsetx;
mOffsetY = offsety;
mDragPaint = null;
invalidate();
}
}
效果图: