为什么即使我没有';不要触摸Android上的视图
我正在向FrameLayout动态添加自定义视图。自定义视图覆盖onTouchEvent方法,自定义视图还覆盖onDraw方法以正确重画位图。一切正常,只是如果我在自定义视图外触摸并开始拖动,它仍然会拖动自定义视图。这就是我所拥有的:为什么即使我没有';不要触摸Android上的视图,android,android-layout,Android,Android Layout,我正在向FrameLayout动态添加自定义视图。自定义视图覆盖onTouchEvent方法,自定义视图还覆盖onDraw方法以正确重画位图。一切正常,只是如果我在自定义视图外触摸并开始拖动,它仍然会拖动自定义视图。这就是我所拥有的: <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" an
<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>
以下是我的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;
}
}
}
}
}
公共类TouchManager{
私有最终int maxNumberOfTouchPoints;
专用最终矢量2D[]点;
私有最终矢量2D[]先前点;
公共TouchManager(最终int maxNumberOfTouchPoints){
this.maxNumberOfTouchPoints=maxNumberOfTouchPoints;
点=新矢量2D[maxNumberOfTouchPoints];
previousPoints=新矢量2D[maxNumberOfTouchPoints];
}
公共布尔值isPressed(整型索引){
返回点[索引]!=null;
}
public int getPressCount(){
整数计数=0;
对于(矢量2D点:点){
如果(点!=null)
++计数;
}
返回计数;
}
公共向量2D moveDelta(整数索引){
如果(显示(索引)){
Vector2D previousPoints[索引]!=null?previousPoints[索引]:points[索引];
返回向量2d.subtract(点[索引],上一个);
}
否则{
返回新向量2d();
}
}
私有静态Vector2D getVector(vector2da,vector2db){
如果(a==null | | b==null)
抛出新的RuntimeException(“不能对null执行此操作”);
返回向量2d。减法(b,a);
}
公共向量2D获取点(整数索引){
返回点[索引]!=null?点[索引]:新矢量2D();
}
公共向量2D getPreviousPoint(int索引){
返回previousPoints[索引]!=null?previousPoints[索引]:新矢量2D();
}
公共向量2d getVector(int indexA,int indexB){
返回getVector(点[indexA],点[indexB]);
}
公共向量2D getPreviousVector(int indexA,int indexB){
if(上一个点[indexA]==null | |上一个点[indexB]==null)
返回getVector(点[indexA],点[indexB]);
其他的
返回getVector(previousPoints[indexA],previousPoints[indexB]);
}
公共无效更新(MotionEvent){
int actionCode=event.getAction()&MotionEvent.ACTION\u掩码;
if(actionCode==MotionEvent.ACTION_指针| | actionCode==MotionEvent.ACTION_UP){
int index=event.getAction()>>MotionEvent.ACTION\u指针\u ID\u移位;
上一个点[索引]=点[索引]=空;
}
否则{
对于(int i=0;i
谢谢 发现我的问题,创建自定义视图时,需要覆盖
protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec)
正确设置宽度和高度。这会将图像设置为正确的宽度和高度,但图像不能在屏幕上的任何位置拖动,只能从0,0和图像宽度和高度绘制。
protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec)