Android 安卓图像地图
我使用下面的代码来显示一个非常大的位图,它可以通过挤压手势进行缩放Android 安卓图像地图,android,gesture,tap,Android,Gesture,Tap,我使用下面的代码来显示一个非常大的位图,它可以通过挤压手势进行缩放 package com.davemorrissey.labs.subscaleview; import android.app.Activity; import android.graphics.PointF; import android.os.Bundle; import android.util.Log; import com.davemorrissey.labs.subscaleview.R.id; import j
package com.davemorrissey.labs.subscaleview;
import android.app.Activity;
import android.graphics.PointF;
import android.os.Bundle;
import android.util.Log;
import com.davemorrissey.labs.subscaleview.R.id;
import java.io.IOException;
public class DemoActivity extends Activity {
private static final String STATE_SCALE = "state-scale";
private static final String STATE_CENTER_X = "state-center-x";
private static final String STATE_CENTER_Y = "state-center-y";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
try {
SubsamplingScaleImageView imageView = (SubsamplingScaleImageView)findViewById(id.imageView);
imageView.setImageAsset("DSC00266.jpg");
if (savedInstanceState != null &&
savedInstanceState.containsKey(STATE_SCALE) &&
savedInstanceState.containsKey(STATE_CENTER_X) &&
savedInstanceState.containsKey(STATE_CENTER_Y)) {
imageView.setScaleAndCenter(savedInstanceState.getFloat(STATE_SCALE), new PointF(savedInstanceState.getFloat(STATE_CENTER_X), savedInstanceState.getFloat(STATE_CENTER_Y)));
}
} catch (IOException e) {
Log.e(DemoActivity.class.getSimpleName(), "Could not load asset", e);
}
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
SubsamplingScaleImageView imageView = (SubsamplingScaleImageView)findViewById(id.imageView);
outState.putFloat(STATE_SCALE, imageView.getScale());
PointF center = imageView.getCenter();
if (center != null) {
outState.putFloat(STATE_CENTER_X, center.x);
outState.putFloat(STATE_CENTER_Y, center.y);
}
}
}
手势由一个名为SubsamplingScaleImageView.java的单独类处理,该类具有以下代码来处理收缩和缩放
public boolean onTouchEvent(MotionEvent event) {
PointF vCenterEnd;
float vDistEnd;
flingMomentum = null;
flingFrom = null;
// Detect flings
if (detector == null || detector.onTouchEvent(event)) {
return true;
}
// Abort if not ready
if (vTranslate == null) {
return true;
}
int touchCount = event.getPointerCount();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_POINTER_1_DOWN:
case MotionEvent.ACTION_POINTER_2_DOWN:
if (touchCount >= 2) {
// Start pinch to zoom. Calculate distance between touch points and center point of the pinch.
float distance = distance(event.getX(0), event.getX(1), event.getY(0), event.getY(1));
scaleStart = scale;
vDistStart = distance;
vTranslateStart = new PointF(vTranslate.x, vTranslate.y);
vCenterStart = new PointF((event.getX(0) + event.getX(1))/2, (event.getY(0) + event.getY(1))/2);
isZooming = true;
} else {
// Start one-finger pan
vTranslateStart = new PointF(vTranslate.x, vTranslate.y);
vCenterStart = new PointF(event.getX(), event.getY());
}
case MotionEvent.ACTION_MOVE:
if (touchCount >= 2 && isZooming) {
// Calculate new distance between touch points, to scale and pan relative to start values.
vDistEnd = distance(event.getX(0), event.getX(1), event.getY(0), event.getY(1));
vCenterEnd = new PointF((event.getX(0) + event.getX(1))/2, (event.getY(0) + event.getY(1))/2);
scale = Math.min(maxScale, (vDistEnd / vDistStart) * scaleStart);
// Translate to place the source image coordinate that was at the center of the pinch at the start
// at the center of the pinch now, to give simultaneous pan + zoom.
float vLeftStart = vCenterStart.x - vTranslateStart.x;
float vTopStart = vCenterStart.y - vTranslateStart.y;
float vLeftNow = vLeftStart * (scale/scaleStart);
float vTopNow = vTopStart * (scale/scaleStart);
vTranslate.x = vCenterEnd.x - vLeftNow;
vTranslate.y = vCenterEnd.y - vTopNow;
fitToBounds();
refreshRequiredTiles(false);
} else if (!isZooming) {
// One finger pan - translate the image
vTranslate.x = vTranslateStart.x + (event.getX() - vCenterStart.x);
vTranslate.y = vTranslateStart.y + (event.getY() - vCenterStart.y);
fitToBounds();
refreshRequiredTiles(false);
}
invalidate();
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
case MotionEvent.ACTION_POINTER_2_UP:
if (event.getPointerCount() < 2) {
isZooming = false;
}
// Trigger load of tiles now required
refreshRequiredTiles(true);
break;
}
return true;
}
public boolean onTouchEvent(运动事件){
点F vCenter端;
浮动vDistEnd;
flingMomentum=null;
flingFrom=null;
//探测投掷物
if(检测器==null | |检测器.onTouchEvent(事件)){
返回true;
}
//如果未准备好,则中止
如果(vTranslate==null){
返回true;
}
int touchCount=event.getPointerCount();
开关(event.getAction()){
case MotionEvent.ACTION\u DOWN:
case MotionEvent.ACTION\u指针\u 1\u向下:
case MotionEvent.ACTION\u指针\u 2\u向下:
如果(触摸计数>=2){
//开始收缩缩放。计算接触点和收缩中心点之间的距离。
浮动距离=距离(event.getX(0)、event.getX(1)、event.getY(0)、event.getY(1));
scaleStart=比例;
vDistStart=距离;
vTranslateStart=新点F(vTranslate.x,vTranslate.y);
vCenterStart=newpointf((event.getX(0)+event.getX(1))/2,(event.getY(0)+event.getY(1))/2);
isZooming=true;
}否则{
//启动一个手指平底锅
vTranslateStart=新点F(vTranslate.x,vTranslate.y);
vCenterStart=newpointf(event.getX(),event.getY());
}
case MotionEvent.ACTION\u移动:
如果(触摸计数>=2&&isZooming){
//计算接触点之间的新距离,以相对于起始值缩放和平移。
vDistEnd=distance(event.getX(0)、event.getX(1)、event.getY(0)、event.getY(1));
vCenter=new PointF((event.getX(0)+event.getX(1))/2,(event.getY(0)+event.getY(1))/2);
scale=Math.min(最大刻度,(vDistEnd/vDistStart)*scaleStart;
//平移以放置源图像坐标,该坐标在开始时位于收缩的中心
//现在在收缩的中心,同时平移和缩放。
float vLeftStart=vCenterStart.x-vTranslateStart.x;
浮动vTopStart=vCenterStart.y-vTranslateStart.y;
float vLeftNow=vLeftStart*(缩放/缩放开始);
浮动vTopNow=vTopStart*(缩放/缩放开始);
vTranslate.x=vCenter.x-vLeftNow;
vTranslate.y=vCenter.y-vTopNow;
fitToBounds();
刷新所需瓷砖(假);
}否则如果(!正在缩放){
//单指平移-平移图像
vTranslate.x=vTranslateStart.x+(event.getX()-vCenterStart.x);
vTranslate.y=vTranslateStart.y+(event.getY()-vCenterStart.y);
fitToBounds();
刷新所需瓷砖(假);
}
使无效();
打破
case MotionEvent.ACTION\u UP:
case MotionEvent.ACTION\u指针\u向上:
case MotionEvent.ACTION\u指针\u 2\u向上:
if(event.getPointerCount()<2){
isZooming=false;
}
//现在需要触发瓦片加载
refreshRequiredTiles(真);
打破
}
返回true;
}
我现在希望能够在放大后双击一个区域,并让应用程序告诉我双击的坐标
我知道我需要在触控动作事件中输入代码,但我无法确定如何实现它
有人知道我是怎么做的吗
谢谢你的帮助
Mark您好,您可以试一试,我只是在使用Touch Listener,下面是代码片段,它可能会对您有所帮助 setOnTouchListener(新的OnTouchListener(){
public boolean onTouch(视图v,运动事件){
mScaleDetector.onTouchEvent(事件);
矩阵值(m);
float x=m[矩阵MTRANS_x];
浮点y=m[矩阵MTRANS_y];
PointF curr=新的PointF(event.getX(),event.getY());
if(event.getAction()==MotionEvent.ACTION\u向下){
xx=(int)event.getX();
yy=(int)event.getY();
}
开关(event.getAction()){
case MotionEvent.ACTION\u DOWN:
set(event.getX(),event.getY());
开始。设置(最后);
模式=拖动;
打破
case MotionEvent.ACTION\u移动:
如果(模式==拖动){
浮动deltaX=当前x-最后x;
浮动三角洲=当前y-最后y;
float scaleWidth=Math.round(origWidth*saveScale);
float scalehHeight=数学圆整(origHeight*saveScale);
if(标度宽度<宽度){
deltaX=0;
如果(y+deltaY>0)
deltaY=-y;
否则如果(y+deltaY<-底部)
三角洲=-(y+底部);
}else if(刻度高度<高度){
deltaY=0;
如果(x+deltaX>0)
deltaX=-x;
否则如果(x+deltaX<-右)
deltaX=-(x+右侧);
}否则{
如果(x+deltaX>0)
deltaX=-x;
否则如果(x+deltaX<-右)
deltaX=-(x+右侧);
如果(y+deltaY>0)
deltaY=-y;
否则如果(y+deltaY<-底部)
三角洲=-(y+底部);
}
矩阵。后翻译(d)
public boolean onTouch(View v, MotionEvent event) {
mScaleDetector.onTouchEvent(event);
matrix.getValues(m);
float x = m[Matrix.MTRANS_X];
float y = m[Matrix.MTRANS_Y];
PointF curr = new PointF(event.getX(), event.getY());
if(event.getAction()==MotionEvent.ACTION_DOWN){
xx = (int) event.getX();
yy = (int) event.getY();
}
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
last.set(event.getX(), event.getY());
start.set(last);
mode = DRAG;
break;
case MotionEvent.ACTION_MOVE:
if (mode == DRAG) {
float deltaX = curr.x - last.x;
float deltaY = curr.y - last.y;
float scaleWidth = Math.round(origWidth * saveScale);
float scaleHeight = Math.round(origHeight * saveScale);
if (scaleWidth < width) {
deltaX = 0;
if (y + deltaY > 0)
deltaY = -y;
else if (y + deltaY < -bottom)
deltaY = -(y + bottom);
} else if (scaleHeight < height) {
deltaY = 0;
if (x + deltaX > 0)
deltaX = -x;
else if (x + deltaX < -right)
deltaX = -(x + right);
} else {
if (x + deltaX > 0)
deltaX = -x;
else if (x + deltaX < -right)
deltaX = -(x + right);
if (y + deltaY > 0)
deltaY = -y;
else if (y + deltaY < -bottom)
deltaY = -(y + bottom);
}
matrix.postTranslate(deltaX, deltaY);
last.set(curr.x, curr.y);
}
break;
case MotionEvent.ACTION_UP:
mode = NONE;
int xDiff = (int) Math.abs(curr.x - start.x);
int yDiff = (int) Math.abs(curr.y - start.y);
if (xDiff < CLICK && yDiff < CLICK)
performClick();
break;
case MotionEvent.ACTION_POINTER_UP:
mode = NONE;
break;
}
final GestureDetector detector = new GestureDetector(getActivity(), new GestureDetector.SimpleOnGestureListener() {
@Override
public boolean onDoubleTap(MotionEvent e) {
PointF sCoords = imageView.viewToSourceCoord(e.getX(), e.getY());
Toast.makeText(getActivity(), "Screen: " + e.getX() + ", " + e.getY() + "; Image: " + sCoords.x + ", " + sCoords.y, Toast.LENGTH_SHORT).show();
return true;
}
});
imageView.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
return detector.onTouchEvent(motionEvent);
}
});