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); } }); //长按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(); } }
如何采用绝对坐标的方式动画方式移动view和如何点击view的时候获取它的cachebitmap并移动,布布扣,bubuko.com