首页 > 代码库 > 如何采用绝对坐标的方式动画方式移动view和如何点击view的时候获取它的cachebitmap并移动

如何采用绝对坐标的方式动画方式移动view和如何点击view的时候获取它的cachebitmap并移动

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();
	}
}