歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Android 圖片拖拽、放大縮小的自定義控件

Android 圖片拖拽、放大縮小的自定義控件

日期:2017/3/1 9:36:08   编辑:Linux編程

Android 圖片拖拽、放大縮小的自定義控件

需求:像相冊中的圖片跟隨手指拖動,雙指的放大和縮小,相冊中拖出范圍之後有彈回的動畫,感覺上很圓潤,很舒服,我寫的例子中並沒有加動畫

思路: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")
@Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
if (mDrawable == null || mDrawable.getIntrinsicHeight() == 0
|| mDrawable.getIntrinsicWidth() == 0) {
return;
}
setBounds();
mDrawable.draw(canvas);
// Log.i("draw", "draw+++++++++++++++++++++++++++++++++++++++");

}

@SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouchEvent(MotionEvent event) {
// TODO Auto-generated method stub
switch (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;

@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.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);

}
}

效果

最簡單的Ubuntu Touch & Android 雙系統安裝方式 http://www.linuxidc.com/Linux/2014-01/94881.htm

在Nexus上實現Ubuntu和Android 4.4.2 雙啟動 http://www.linuxidc.com/Linux/2014-05/101849.htm

Ubuntu 14.04 配置 Android SDK 開發環境 http://www.linuxidc.com/Linux/2014-05/101039.htm

64位Ubuntu 11.10下Android開發環境的搭建(JDK+Eclipse+ADT+Android SDK詳細) http://www.linuxidc.com/Linux/2013-06/85303.htm

Ubuntu 14.04 x64配置Android 4.4 kitkat編譯環境的方法 http://www.linuxidc.com/Linux/2014-04/101148.htm

Ubuntu 12.10 x64 安裝 Android SDK http://www.linuxidc.com/Linux/2013-03/82005.htm

更多Android相關信息見Android 專題頁面 http://www.linuxidc.com/topicnews.aspx?tid=11

Copyright © Linux教程網 All Rights Reserved