Android 图片拖拽、放大缩小的自定义控件

来源:互联网 发布:网络小手分享论坛社区 编辑:程序博客网 时间:2024/05/22 15:38

需求:像相册中的图片跟随手指拖动,双指的放大和缩小,相册中拖出范围之后有弹回的动画,感觉上很圆润,很舒服,我写的例子中并没有加动画

思路:1.自定义DragImageView.java

            2.自定义中先画图片,图片大于屏幕就把图片缩小后显示,图片小于屏幕就直接显示,显示之前要计算显示图片的Rect,Rect是其实就是四个坐标,用来控制显示图片的范                  围,这个Rect是根据图片的长宽比例计算而来,显示在屏幕中间。

            3.跟随手指移动:在touchEvent事件中处理好单双指的各种事件之后,跟随手指就是不断的改变Rect的坐标,然后不断的invalidate()(该方法是重新强制绘制View);

            4.双指缩放:双指缩放的时候从图片Rect的中心缩放的,没有实现相册那种从手指中心缩放的那种。

            5.单指和双指的事件在touc事件中已近处理好了

                   event.getPointerCount()==2的情况就是双指部分

                   float    X0,Y0,X1,Y1双指的四个坐标

                   在双指移动的时候计算一个双指的距离出来m1,在MOVE执行的时候重新计算一个新的距离m2,去判断m1和m2大小来判断双指是张开还是捏合,并且执行相应事件,判断之后把m2复制给m1,这时的MOVE事件会有新的m2出来,所以就一直判断就ok了。放大和缩小就是按照一定的比例去改变Rect的值。


DragImageView.java

public class DragImageView extends View {private Paint mPaint;private Drawable mDrawable;private Rect mDrawableRect = new Rect();// private Rect mDrawableOffsetRect = new Rect();private Context mContext;private float mRation_WH = 0;private float mOldX = 0;private float mOldY = 0;private float mOldX0, mOldY0, mOldX1, mOldY1, mOldK, mOldB, mOldHandsX,mOldHandsY;private double mD1;private boolean isFirst = true;private int SINGALDOWN = 1;// 单点按下private int MUTILDOWM = 2;// 双点按下private int MUTILMOVE = 3;// 双点拖拽private int mStatus = 0;enum STATUS {SINGAL, MUTILDOWN, MUTILMOVE;}public DragImageView(Context context) {super(context);this.mContext = context;mPaint = new Paint();mPaint.setAntiAlias(true);mPaint.setColor(Color.BLACK);mPaint.setStyle(Style.FILL);mPaint.setTextSize(35.0f);}@SuppressLint("DrawAllocation")@Overrideprotected void onDraw(Canvas canvas) {// TODO Auto-generated method stubsuper.onDraw(canvas);if (mDrawable == null || mDrawable.getIntrinsicHeight() == 0|| mDrawable.getIntrinsicWidth() == 0) {return;}setBounds();mDrawable.draw(canvas);// Log.i("draw", "draw+++++++++++++++++++++++++++++++++++++++");}@SuppressLint("ClickableViewAccessibility")@Overridepublic boolean onTouchEvent(MotionEvent event) {// TODO Auto-generated method stubswitch (event.getPointerCount()) {case 1:switch (event.getAction()) {case MotionEvent.ACTION_DOWN:mStatus = SINGALDOWN;mOldX = event.getX();mOldY = event.getY();// Log.i("x_y_down", event.getX() + "__" + event.getY());break;case MotionEvent.ACTION_UP:checkBounds();// Log.i("x_y_up", event.getX() + "__" + event.getY());break;case MotionEvent.ACTION_MOVE:// Log.i("x_y_move", event.getX() + "__" + event.getY());if (mStatus == SINGALDOWN) {int offsetWidth = (int) (event.getX() - mOldX);int offsetHeight = (int) (event.getY() - mOldY);// Log.i("x_y_offset", offsetWidth + "__" + offsetHeight);mOldX = event.getX();mOldY = event.getY();mDrawableRect.offset(offsetWidth, offsetHeight);invalidate();}break;default:break;}break;default:/* * mStatus = MUTILDOWM; if (mStatus == MUTILDOWM) { mOldX0 = * event.getX(0); mOldY0 = event.getY(0); mOldX1 = event.getX(1); * mOldY1 = event.getY(1); mOldK = (mOldY1 - mOldY0) / (mOldX1 - * mOldX0); mOldB = (mOldY0 * mOldX1 - mOldY1 * mOldX0) / (mOldX1 - * mOldX0); mOldHandsX = (mOldX0 + mOldX1) / 2; mOldHandsY = * mOldHandsX * mOldK + mOldB; mD1 = Math.sqrt(Math.pow(mOldX0 - * mOldX1, 2) + Math.pow(mOldY0 - mOldY1, 2)); Log.i("mD1", mD1 + * "________________"); } */switch (event.getAction()) {case MotionEvent.ACTION_POINTER_DOWN:Log.i("DOUBLETOWDOWN", "true");break;case MotionEvent.ACTION_MOVE:// Log.i("x_y_move", event.getX(0) + "__" + event.getY(0) +// "___"// + event.getX(1) + "__" + event.getY(1));mStatus = MUTILMOVE;float X0 = event.getX(0);float Y0 = event.getY(0);float X1 = event.getX(1);float Y1 = event.getY(1);float k = (Y1 - Y0) / (X1 - X0);float b = (Y0 * X1 - Y1 * X0) / (X1 - X0);int RectCenterX = mDrawableRect.centerX();int RectCenterY = mDrawableRect.centerY();float mHandsX = (X0 + X1) / 2;float mHandsY = mHandsX * k + b;double mD2 = Math.sqrt(Math.pow(X0 - X1, 2)+ Math.pow(Y0 - Y1, 2));Log.i("GCM", mD2 + "________________X:" + mHandsX + "___Y:"+ mHandsY);if (mD1 < mD2) {// double mMultiple = mD2 / mD1;// int newWidth = (int) (mDrawableRect.width() * mMultiple);// int newHeight = (int) (newWidth / mRation_WH);//// int newleft = mDrawableRect.left / 2;// int newtop = mDrawableRect.top / 2;// int newright = mDrawableRect.right * (3 / 2);// int newbotto = mDrawableRect.bottom * (3 / 2);// // mDrawableRect.set(newleft, newtop, newright,// newbotto);//// mDrawableRect.set(RectCenterX - newWidth / 2, RectCenterY// - newHeight / 2, RectCenterX + newWidth / 2,// RectCenterY + newHeight / 2);// invalidate();if (mDrawableRect.width() < mContext.getResources().getDisplayMetrics().widthPixels * 2) {int offsetwidth = 10;int offsettop = (int) (offsetwidth / mRation_WH);mDrawableRect.set(mDrawableRect.left - offsetwidth,mDrawableRect.top - offsettop,mDrawableRect.right + offsetwidth,mDrawableRect.bottom + offsettop);Log.i("GCM", "aaaaaaaaaaaaaaa");invalidate();}// mDrawableRect.offset((int) mHandsX, (int) mHandsY);} else {if (mDrawableRect.width() > mContext.getResources().getDisplayMetrics().widthPixels / 3) {int offsetwidth = 10;int offsettop = (int) (offsetwidth / mRation_WH);mDrawableRect.set(mDrawableRect.left + offsetwidth,mDrawableRect.top + offsettop,mDrawableRect.right - offsetwidth,mDrawableRect.bottom - offsettop);invalidate();Log.i("GCM", "bbbbbbbbbbbbbbb");}}mD1 = mD2;if (mHandsX < RectCenterX) {if (mHandsY < RectCenterY) {Log.i("PPPPPPP", "1");} else {Log.i("PPPPPPP", "3");}} else {if (mHandsY < RectCenterY) {Log.i("PPPPPPP", "2");} else {Log.i("PPPPPPP", "4");}}//break;case MotionEvent.ACTION_UP:Log.i("mStatus", "mutildouble_up");mStatus = 0;break;default:break;}break;}return true;}public void setBounds() {if (isFirst) {mRation_WH = (float) mDrawable.getIntrinsicWidth()/ (float) mDrawable.getIntrinsicHeight();int px_w = Math.min(getWidth(),dip2px(mContext, mDrawable.getIntrinsicWidth()));int px_h = (int) (px_w / mRation_WH);int left = (getWidth() - px_w) / 2;int top = (getHeight() - px_h) / 2;int right = px_w + left;int bottom = px_h + top;mDrawableRect.set(left, top, right, bottom);// mDrawableOffsetRect.set(mDrawableRect);isFirst = false;Log.i("rect1______", mDrawableRect.left + "," + mDrawableRect.top+ "," + mDrawableRect.right + "," + mDrawableRect.bottom);}mDrawable.setBounds(mDrawableRect);Log.i("rect2______", mDrawableRect.left + "," + mDrawableRect.top + ","+ mDrawableRect.right + "," + mDrawableRect.bottom);Log.i("center_______",mDrawableRect.centerX() + "," + mDrawableRect.centerY());}public void checkBounds() {int newLeft = mDrawableRect.left;int newTop = mDrawableRect.top;boolean isChange = false;if (newLeft < -mDrawableRect.width()) {newLeft = -mDrawableRect.width();isChange = true;}if (newTop < -mDrawableRect.height()) {newTop = -mDrawableRect.height();isChange = true;}if (newLeft > getWidth()) {newLeft = getWidth();isChange = true;}if (newTop > getHeight()) {newTop = getHeight();isChange = true;}if (isChange) {mDrawableRect.offsetTo(newLeft, newTop);invalidate();}}public Drawable getmDrawable() {return mDrawable;}public void setmDrawable(Drawable mDrawable) {this.mDrawable = mDrawable;}public int dip2px(Context context, int value) {final float scale = context.getResources().getDisplayMetrics().density;return (int) (value * scale + 0.5f);}}
在界面中使用


public class MainActivity extends Activity {Context mContext;@Overrideprotected void onCreate(Bundle savedInstanceState) {// TODO Auto-generated method stubsuper.onCreate(savedInstanceState);this.mContext = getApplicationContext();requestWindowFeature(Window.FEATURE_NO_TITLE);DragImageView mView = new DragImageView(mContext);mView.setmDrawable(mContext.getResources().getDrawable(R.drawable.bbb));setContentView(mView);}}

效果



2 1
原创粉丝点击