我将自定义视图动态添加到FrameLayout。自定义视图会覆盖onTouchEvent方法,自定义视图也会覆盖onDraw方法以正确地重绘位图。一切正常,但如果我在自定义视图外触摸并开始拖动,它仍会拖动我的自定义视图。这就是我所拥有的:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/custom_view_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipChildren="false"
android:background="@drawable/balloons"
tools:context="com.blah.test.SomeActivity">
</FrameLayout>
我在SomeActivity.java中添加了我的自定义视图:
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.stencil_tigerclaw);
parentView = (FrameLayout) findViewById(R.id.custom_view_container);
stencil = new CustomImageView(this, bitmap, parentView);
parentView.addView(stencil);
这是我的CustomImageView:
public class CustomImageView extends ImageView {
private Bitmap bitmap;
private int width;
private int height;
private float scale = 1;
private float angle = 0;
private Matrix transform = new Matrix();
private Vector2D position = new Vector2D();
private TouchManager touchManager = new TouchManager(2);
private boolean isInitialized = false;
private FrameLayout parentView;
public CustomImageView(Context context, Bitmap bitmap, FrameLayout parentView) {
super(context);
this.bitmap = bitmap;
this.width = bitmap.getWidth();
this.height = bitmap.getHeight();
this.parentView = parentView;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
try {
touchManager.update(event);
if (touchManager.getPressCount() == 1) {
position.add(touchManager.moveDelta(0));
}
else {
if (touchManager.getPressCount() == 2) {
Vector2D current = touchManager.getVector(0, 1);
Vector2D previous = touchManager.getPreviousVector(0, 1);
float currentDistance = current.getLength();
float previousDistance = previous.getLength();
if (previousDistance != 0) {
scale *= currentDistance / previousDistance;
}
angle -= Vector2D.getSignedAngleBetween(current, previous);
}
}
invalidate();
}
catch(Throwable t) {
// Do something...
}
return true;
}
public float getAngle() {
return angle;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (!isInitialized) {
position.set(parentView.getWidth()/2, parentView.getHeight()/2);
isInitialized = true;
}
Paint paint = new Paint();
transform.reset();
transform.postTranslate(-width / 2.0f, -height / 2.0f);
transform.postRotate(getDegreesFromRadians(angle));
transform.postScale(scale, scale);
transform.postTranslate(position.getX(), position.getY());
canvas.drawBitmap(bitmap, transform, paint);
}
最后这是我的TouchManager课程:
public class TouchManager {
private final int maxNumberOfTouchPoints;
private final Vector2D[] points;
private final Vector2D[] previousPoints;
public TouchManager(final int maxNumberOfTouchPoints) {
this.maxNumberOfTouchPoints = maxNumberOfTouchPoints;
points = new Vector2D[maxNumberOfTouchPoints];
previousPoints = new Vector2D[maxNumberOfTouchPoints];
}
public boolean isPressed(int index) {
return points[index] != null;
}
public int getPressCount() {
int count = 0;
for(Vector2D point : points) {
if (point != null)
++count;
}
return count;
}
public Vector2D moveDelta(int index) {
if (isPressed(index)) {
Vector2D previous = previousPoints[index] != null ? previousPoints[index] : points[index];
return Vector2D.subtract(points[index], previous);
}
else {
return new Vector2D();
}
}
private static Vector2D getVector(Vector2D a, Vector2D b) {
if (a == null || b == null)
throw new RuntimeException("can't do this on nulls");
return Vector2D.subtract(b, a);
}
public Vector2D getPoint(int index) {
return points[index] != null ? points[index] : new Vector2D();
}
public Vector2D getPreviousPoint(int index) {
return previousPoints[index] != null ? previousPoints[index] : new Vector2D();
}
public Vector2D getVector(int indexA, int indexB) {
return getVector(points[indexA], points[indexB]);
}
public Vector2D getPreviousVector(int indexA, int indexB) {
if (previousPoints[indexA] == null || previousPoints[indexB] == null)
return getVector(points[indexA], points[indexB]);
else
return getVector(previousPoints[indexA], previousPoints[indexB]);
}
public void update(MotionEvent event) {
int actionCode = event.getAction() & MotionEvent.ACTION_MASK;
if (actionCode == MotionEvent.ACTION_POINTER_UP || actionCode == MotionEvent.ACTION_UP) {
int index = event.getAction() >> MotionEvent.ACTION_POINTER_ID_SHIFT;
previousPoints[index] = points[index] = null;
}
else {
for(int i = 0; i < maxNumberOfTouchPoints; ++i) {
if (i < event.getPointerCount()) {
int index = event.getPointerId(i);
Vector2D newPoint = new Vector2D(event.getX(i), event.getY(i));
if (points[index] == null)
points[index] = newPoint;
else {
if (previousPoints[index] != null) {
previousPoints[index].set(points[index]);
}
else {
previousPoints[index] = new Vector2D(newPoint);
}
if (Vector2D.subtract(points[index], newPoint).getLength() < 64)
points[index].set(newPoint);
}
}
else {
previousPoints[i] = points[i] = null;
}
}
}
}
}
谢谢!
答案 0 :(得分:0)
发现我的问题,当您创建自定义视图时,需要覆盖
protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec)
正确设置宽度和高度。