Android,在ImageView上丢失触摸事件
问题描述:
我明白这是我的代码的问题。但我找不出哪个是问题。我下载了一个“示例项目”来使用touchListener,它可以工作,但是如果我尝试在我的项目上做同样的事情,突然我只能得到“按下按钮”事件。Android,在ImageView上丢失触摸事件
活动:
@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);
}
map.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;
}
}
而触摸侦听器,我把它放在另一个类。 MapMovement:
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:
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分钟的代码。
真的非常感谢您的帮助。如果你不知道哪个是错误不是问题。但你不能来这里告诉我“更具体”,因为如果我可以“更具体”,我不会在这里问你,因为我会自己解决问题。
答
的解决方案是容易的,在MapMovement的onTouch不得不返回真正,而不是假。
真的非常感谢您的帮助。 (我自然很讽刺)
你为什么还给我反面的票? –
也许你需要更具体一些,而不仅仅是放在代码中。 – iCantSeeSharp
如果我可以更具体一些,我会发现哪个是问题。 –