缩小回执,移动回执等(现在只支持竖屏)
代码如下 继承自imageview,通过设置bitmap
package com.example.dragimg;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Point;
import android.view.Display;
import android.view.MotionEvent;
import android.view.WindowManager;
import android.widget.ImageView;
/**
* @author mengyangwang E-mail:wangmengyang101@gmail.com
* @version Date Created:18 Aug 2014 13:36:02
* @Description
*/
public class TouchableImgView extends ImageView {
private float zoom_distance = 0f;
private final float width_height_ratio;
private float scale_ratio = 0;
private float zoom_x, zoom_y = 0f;
private float zoom_width_adjust, zoom_height_adjust;
private Mode mode = Mode.Default;
private int min_l, min_r, min_t, min_b;
private int move_min_l, move_min_r, move_min_t, move_min_b;
/** relative boundary for this view */
private int boundary_l, boundary_t, boundary_r, boundary_b;
private final int zoom_max, zoom_min;
private final int screen_width, screen_height;
private int move_x, move_y;
private float bm_width;
private float bm_height;
private Rescale rescale = Rescale.Default;
private boolean rebound_width = false;
private boolean rebound_height = false;
private enum Rescale {
Default, Zoom_In;
}
private enum Mode {
Move, Zoom, Default;
}
public TouchableImgView(Context context) {
super(context);
screen_width = MainActivity.getScreen_width();
screen_height = MainActivity.getScreen_height();
zoom_max = screen_width << 2;
zoom_min = screen_width >> 1;
width_height_ratio = screen_width / screen_height;
}
@Override
public void setImageBitmap(Bitmap bitmap) {
super.setImageBitmap(bitmap);
bm_width = bitmap.getWidth();
bm_height = bitmap.getHeight();
if (bm_width > bm_height) {
bm_height = screen_width / bm_width * bm_height;
bm_width = screen_width;
} else {
bm_width = screen_height / bm_height * bm_width;
bm_height = screen_height;
}
zoom_width_adjust = (int) (screen_width - bm_width) >> 1;
zoom_height_adjust = (int) (screen_height - bm_height) >> 1;
boundary_l = (int) -zoom_width_adjust;
boundary_r = (int) (screen_width + boundary_l);
boundary_t = (int) -zoom_height_adjust;
boundary_b = (int) (screen_height + boundary_t);
move_min_l = (int) ((screen_width >> 2) - zoom_width_adjust);
move_min_r = (int) (screen_width - zoom_width_adjust - (screen_width >> 2));
move_min_t = (int) ((screen_height >> 2) - zoom_height_adjust);
move_min_b = (int) (screen_height - zoom_height_adjust - (screen_height >> 2));
min_l = (int) bm_width >> 2;
min_r = (int) (bm_width - min_l);
min_t = (int) bm_height >> 2;
min_b = (int) (bm_height - min_t);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
onTouchDown(event);
break;
case MotionEvent.ACTION_POINTER_DOWN:
onPointerDown(event);
break;
case MotionEvent.ACTION_MOVE:
onTouchMove(event);
break;
case MotionEvent.ACTION_UP:
int move_rebound_horizontal = 0;
int move_rebound_vertical = 0;
if (rebound_width && rebound_height) {
move_rebound_horizontal = getMove_rebound_horizontal();
move_rebound_vertical = getMove_rebound_vertical();
} else if (rebound_width) {
move_rebound_horizontal = getMove_rebound_horizontal();
} else if (rebound_height) {
move_rebound_vertical = getMove_rebound_vertical();
} else {
break;
}
this.layout(this.getLeft() - move_rebound_horizontal, this.getTop()
- move_rebound_vertical, this.getRight()
- move_rebound_horizontal, this.getBottom()
- move_rebound_vertical);
rebound_width = false;
rebound_height = false;
break;
case MotionEvent.ACTION_POINTER_UP:
if (rescale == Rescale.Zoom_In) {
this.setFrame(0, 0, (int) bm_width, (int) bm_height);
}
rescale = Rescale.Default;
mode = Mode.Default;
break;
}
return true;
}
private int getMove_rebound_horizontal() {
if (this.getLeft() > boundary_l) {
return this.getLeft() - boundary_l;
} else if (this.getRight() < boundary_r) {
return this.getRight() - boundary_r;
}
return 0;
}
private int getMove_rebound_vertical() {
if (this.getTop() > boundary_t) {
return this.getTop() - boundary_t;
} else if (this.getBottom() < boundary_b) {
return this.getBottom() - boundary_b;
}
return 0;
}
private void onTouchDown(MotionEvent event) {
mode = Mode.Move;
move_x = (int) event.getRawX();
move_y = (int) event.getRawY();
}
private void onTouchMove(MotionEvent event) {
// move
if (mode == Mode.Move) {
onMove(event);
} else
// zoom
if (mode == Mode.Zoom) {
float m_distance = getDistance(event);
float diff = m_distance - zoom_distance;
if (diff > 5 || diff < -5) {
scale_ratio = diff / 500;
onScale(scale_ratio);
zoom_distance = m_distance;
}
}
}
private void onMove(MotionEvent event) {
if (this.getWidth() <= screen_width
&& this.getHeight() <= screen_height) {
return;
}
int l = this.getLeft();
int r = this.getRight();
int t = this.getTop();
int b = this.getBottom();
width: if (this.getWidth() > screen_width) {
int current_x = (int) event.getRawX();
int diff_x = (current_x - move_x);
move_x = current_x;
if (Math.abs(diff_x) > 5) {
l = this.getLeft() + diff_x;
r = this.getRight() + diff_x;
} else {
break width;
}
// if reach rebound boundary
if (l > move_min_l) {
r = r - (l - move_min_l);
l = move_min_l;
} else if (r < move_min_r) {
l = l + (move_min_r - r);
r = move_min_r;
}
if (l > boundary_l) {
rebound_width = true;
} else if (r < boundary_r) {
rebound_width = true;
}
}
height: if (this.getHeight() > screen_height) {
int current_y = (int) event.getRawY();
int diff_y = (current_y - move_y);
move_y = current_y;
if (Math.abs(diff_y) > 5) {
t = this.getTop() + diff_y;
b = this.getBottom() + diff_y;
} else {
break height;
}
if (t > move_min_t) {
b = b - (t - move_min_t);
t = move_min_t;
} else if (b < move_min_b) {
t = t + (move_min_b - b);
b = move_min_b;
}
if (t > boundary_t) {
rebound_height = true;
} else if (b < boundary_b) {
rebound_height = true;
}
}
this.layout(l, t, r, b);
}
private void onScale(float ratio) {
// zoom_out
if (ratio > 0 && this.getWidth() < zoom_max) {
int l = (int) (this.getLeft() - (zoom_x - zoom_width_adjust)
* ratio);
int r = (int) (this.getRight() + (screen_width - zoom_x - zoom_width_adjust)
* ratio);
int t = (int) (this.getTop() - (zoom_y - zoom_height_adjust)
* ratio);
int b = (int) (this.getBottom() + (screen_height - zoom_y - zoom_height_adjust)
* ratio);
// adjust
if ((r - l) > screen_width) {
if (l > boundary_l) {
r = r - (l - boundary_l);
l = boundary_l;
} else if (r < boundary_r) {
l = l + (boundary_r - r);
r = boundary_r;
}
}
if ((b - t) > screen_height) {
if (t > boundary_t) {
b = b - (t - boundary_t);
t = boundary_t;
} else if (b < boundary_b) {
t = t + (boundary_b - b);
b = boundary_b;
}
}
this.setFrame(l, t, r, b);
}
// zoom_in
if (ratio < 0 && this.getWidth() > zoom_min) {
ratio = Math.abs(ratio);
// TODO reduction degree should be adjusted
int left = (int) ((min_l - this.getLeft()) * ratio * width_height_ratio);
int right = (int) ((this.getRight() - min_r) * ratio * width_height_ratio);
int top = (int) ((min_t - this.getTop()) * ratio);
int bottom = (int) ((this.getBottom() - min_b) * ratio);
int l = (int) (this.getLeft() + left);
int r = (int) (this.getRight() - right);
int t = (int) (this.getTop() + top);
int b = (int) (this.getBottom() - bottom);
if (l > 0 || r < screen_width || t > 0 || b < screen_height) {
rescale = Rescale.Zoom_In;
}
if (l > min_l) {
l = min_l;
}
if (r < min_r) {
r = min_r;
}
if (t > min_t) {
t = min_t;
}
if (b < min_b) {
b = min_b;
}
this.setFrame(l, t, r, b);
}
}
private void onPointerDown(MotionEvent event) {
if (event.getEventTime() > 1000 && event.getPointerCount() == 2) {
zoom_distance = getDistance(event);
mode = Mode.Zoom;
} else {
mode = Mode.Default;
}
}
private float getDistance(MotionEvent event) {
if (!(event.getPointerCount() == 2)) {
return 0f;
}
float f_x = event.getX(0);
float s_x = event.getX(1);
float f_y = event.getY(0);
float s_y = event.getY(1);
zoom_x = event.getRawX();
zoom_y = event.getRawY();
return (float) Math.sqrt(Math.pow(f_x - s_x, 2)
+ Math.pow(f_y - s_y, 2));
}
public float getBm_width() {
return bm_width;
}
public float getBm_height() {
return bm_height;
}
}
imgView = new TouchableImgView(getApplicationContext());
imgView.setImageBitmap(bitmap);
imgView.setLayoutParams(new LayoutParams((int) imgView.getBm_width(),
(int) imgView.getBm_height()));
imgView.setScaleType(ImageView.ScaleType.FIT_CENTER);
imgView.setImageBitmap(bitmap);
imgView.setX((screen_width - imgView.getBm_width()) / 2);
imgView.setY((screen_height - imgView.getBm_height()) / 2);
mapLayout.addView(imgView);