<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.cyfang.test.MainActivity" >
<com.cyfang.test.MyImageView
android:id="@+id/myImageView"
android:layout_width="480px"
android:layout_height="400px" />
</RelativeLayout>
Activity:
package com.cyfang.test;
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
MyImageView:
package com.cyfang.test;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.FloatMath;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.widget.ImageView;
public class MyImageView extends ImageView {
/** 使用者動作 */
private enum Action {
/** 沒動作 */
None,
/** 縮放 */
Zoom,
/** 拖曳 */
Drag
};
/** 動作 */
private Action action = Action.None;
/** 矩形大小 */
private RectF rectF;
/** 畫筆 */
private Paint paint = new Paint();
{
// 空心
paint.setStyle(Paint.Style.STROKE);
// 藍色
paint.setColor(Color.BLUE);
};
/** 自訂ImageView */
public MyImageView(Context context, AttributeSet attrs) {
super(context, attrs);
this.rectF = new RectF(0, 0, 480 - 50, 400 - 5);
this.setOnTouchListener(new OnTouchListener() {
/** 使用者點擊位置 */
private float x, y;
/** 距離 */
private float distance = 1f;
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
x = event.getX();
y = event.getY();
action = Action.Drag;
break;
case MotionEvent.ACTION_POINTER_UP:
action = Action.None;
break;
case MotionEvent.ACTION_POINTER_DOWN:
distance = getDistance(event);
// 螢幕觸碰為2個觸控點時
if (event.getPointerCount() == 2) {
action = Action.Zoom;
}
break;
case MotionEvent.ACTION_MOVE:
if (action == Action.Drag) {
int moveX = (int) (event.getRawX() - x);
int moveY = (int) (event.getRawY() - y);
// 設定layout位置
v.layout(moveX, moveY, moveX + v.getWidth(), moveY + v.getHeight());
} else if (action == Action.Zoom) {
// 距離
float newDistance = getDistance(event);
// 縮放比例
float scale = newDistance / this.distance;
// 設定當前距離
this.distance = newDistance;
// 將ImageView放大
LayoutParams params = v.getLayoutParams();
params.width = (int) (v.getWidth() * scale);
params.height = (int) (v.getHeight() * scale);
// 重新定義矩形大小
rectF = new RectF(0, 0, params.width - 50, params.height - 5);
v.setLayoutParams(params);
}
break;
}
return true;
}
});
}
// onDraw會持續渲染
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// 畫矩形
canvas.drawRect(rectF, paint);
}
/** 取距離公式 */
private float getDistance(MotionEvent event) {
// x點距離
float x = event.getX(0) - event.getX(1);
// y點距離
float y = event.getY(0) - event.getY(1);
return FloatMath.sqrt(x * x + y * y);
}
}
縮放前:
縮放後:
移動前:
移動後:


