我明白这是我的代码的问题。但我无法找出问题所在。我下载了一个“示例项目”来使用 touchListener,它可以工作,但是如果我尝试在我的项目上做同样的事情,突然间我只能得到“按下按钮”事件。
活动:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.navigator_layout);
b = this.getIntent().getStringArrayExtra("building");
cv = (MapView) this.findViewById(R.id.map);
MapMovement mm = new MapMovement(cv);
compass = new Compass(this, cv, debug);
}
地图.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@color/black"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen" >
<it.inav.graphics.MapView
android:id="@+id/map"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_centerInParent="true" />
</RelativeLayout>
我省略了 MapView 的某些部分,我在其中获取图像等,询问您是否认为重要:
public class MapView extends ImageView {
...
public MapView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public MapView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MapView(Context context) {
super(context);
}
public void init(List<Floor> floors) {
this.floors = floors;
setFocusable(true);
}
private void setInitialZoom() {
if (screen_center == null)
return;
// recupero la dimensione dell'immagine
int image_width = bmp.getWidth();
int image_heigth = bmp.getHeight();
int longest_i = image_width;
if (longest_i < image_heigth)
longest_i = image_heigth;
float longest_s = screen_center.x * 2;
if (longest_s < screen_center.y * 2)
longest_s = screen_center.y * 2;
float zoom = (float)longest_s / longest_i;
this.min_zoom = zoom;
this.zoom = zoom;
setImageCenter(null);
}
private void setZoom(float zoom) {
if (zoom < min_zoom)
this.zoom = min_zoom;
else if (zoom > 1)
this.zoom = 1;
else
this.zoom = zoom;
this.invalidate();
}
private void setImageCenter(PointF posizione) {
if (posizione != null)
image_center = new PointF(posizione.x, posizione.y);
else
image_center = new PointF(bmp.getWidth(), bmp.getHeight());
}
private void prepareImage(Canvas canvas) {
canvas.rotate((float)(bearing - selected_floor.bearing), screen_center.x, screen_center.y);
// scalo l'immagine
image = new Matrix();
image.setScale(zoom, zoom);
Paint drawPaint = new Paint();
drawPaint.setAntiAlias(true);
drawPaint.setFilterBitmap(true);
float centerScaledWidth = image_center.x * zoom / 2;
float centerScaledHeigth = image_center.y * zoom / 2;
image.postTranslate(screen_center.x - centerScaledWidth,
screen_center.y - centerScaledHeigth);
canvas.drawBitmap(bmp, image, drawPaint);
canvas.save();
canvas.restore();
}
private void drawMarkers(Canvas canvas) {
Paint drawPaint = new Paint();
drawPaint.setAntiAlias(true);
drawPaint.setColor(Color.WHITE);
canvas.drawCircle(screen_center.x, screen_center.y, MARKER_DIAMETER + 1, drawPaint);
drawPaint.setColor(Color.RED);
canvas.drawCircle(screen_center.x, screen_center.y, MARKER_DIAMETER, drawPaint);
canvas.save();
canvas.restore();
}
private void setScreenCenter() {
if (screen_center != null)
return;
// recupero la dimensione dello schermo
int screen_height = getMeasuredHeight();
int screen_width = getMeasuredWidth();
if ((screen_height == 0) || (screen_width == 0))
return;
screen_center = new PointF(screen_width / 2, screen_height / 2);
setInitialZoom();
}
@Override
public void draw(Canvas canvas) {
setScreenCenter();
if (selected_floor != null) {
prepareImage(canvas);
drawMarkers(canvas);
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int measuredWidth = measure(widthMeasureSpec);
int measuredHeight = measure(heightMeasureSpec);
setMeasuredDimension(measuredWidth, measuredHeight);
}
private int measure(int measureSpec) {
int result = 0;
// Decode the measurement specifications.
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
if (specMode == MeasureSpec.UNSPECIFIED) {
// Return a default size of 200 if no bounds are specified.
result = 200;
} else {
// As you want to fill the available space
// always return the full available bounds.
result = specSize;
}
return result;
}
public void setBearing(float _bearing) {
bearing = _bearing;
}
}
还有触摸监听器,我把它放在另一个类中。地图运动:
public class MapMovement implements OnTouchListener {
...
// We can be in one of these 3 states
private static final int NONE = 0;
private static final int DRAG = 1;
private static final int ZOOM = 2;
private int mode = NONE;
public MapMovement(MapView mapView) {
this.mapView = mapView;
mapView.setOnTouchListener(this);
}
public void setImageCenter(PointF p) {
this.image_center = p;
}
private void dumpEvent(MotionEvent event) {
String names[] = { "DOWN" , "UP" , "MOVE" , "CANCEL" , "OUTSIDE" ,
"POINTER_DOWN" , "POINTER_UP" , "7?" , "8?" , "9?" };
StringBuilder sb = new StringBuilder();
int action = event.getAction();
int actionCode = action & MotionEvent.ACTION_MASK;
sb.append("event ACTION_" ).append(names[actionCode]);
if (actionCode == MotionEvent.ACTION_POINTER_DOWN
|| actionCode == MotionEvent.ACTION_POINTER_UP) {
sb.append("(pid " ).append(
action >> MotionEvent.ACTION_POINTER_ID_SHIFT);
sb.append(")" );
}
sb.append("[" );
for (int i = 0; i < event.getPointerCount(); i++) {
sb.append("#" ).append(i);
sb.append("(pid " ).append(event.getPointerId(i));
sb.append(")=" ).append((int) event.getX(i));
sb.append("," ).append((int) event.getY(i));
if (i + 1 < event.getPointerCount())
sb.append(";" );
}
sb.append("]" );
Log.d("event", sb.toString());
}
@Override
public boolean onTouch(View v, MotionEvent event) {
// Dump touch event to log
dumpEvent(event);
return false;
}
}
这是我尝试在 MapView 上执行“DRAG”时的输出日志:
12-24 09:41:58.412: D/event(31342): event ACTION_DOWN[#0(pid 0)=85,248]
12-24 09:42:01.752: D/event(31342): event ACTION_DOWN[#0(pid 0)=106,126]
12-24 09:42:02.466: D/event(31342): event ACTION_DOWN[#0(pid 0)=96,286]
日志代码和我下载的测试项目一样,这就是我能得到的所有输出。没有 ACTION_UP,没有 ACTION_MOVEMENT,什么都没有。
我不知道问题出在哪里或在哪里。我想要的只是使用触摸事件在活动中移动图像,但似乎我只能获得一个触摸事件 ACTION_DOWN。
我已经发布了我认为可能是错误的所有代码部分。如果我认为问题肯定出在一个类或布局中,我会发布它,而不是我已经浪费了 15 分钟为您编辑的一堆代码。
真的很感谢你的帮助。如果你不知道哪个是错误不是问题。但是你不能来这里告诉我“更具体”,因为如果我可以“更具体”,我不会在这里问你,因为我会自己解决问题。