Android SurfaceView Rect对象被删除

Android SurfaceView Rect对象被删除,android,drag-and-drop,surfaceview,scaling,rect,Android,Drag And Drop,Surfaceview,Scaling,Rect,我正在开发一个带有多个矩形的绘图视图,这些矩形可以重新调整大小并拖动(在相机预览中)。 我想我成功了。但问题是,矩形似乎被删除了拖动或调整大小时,它们有时会从视图中消失,并从矩形阵列中删除。有人能指出错误吗??提前谢谢 这是我的DrawView课程 import java.util.ArrayList; import java.util.List; import android.content.Context; import android.graphics.Canvas; import an

我正在开发一个带有多个矩形的绘图视图,这些矩形可以重新调整大小并拖动(在相机预览中)。 我想我成功了。但问题是,矩形似乎被删除了拖动或调整大小时,它们有时会从视图中消失,并从矩形阵列中删除。有人能指出错误吗??提前谢谢

这是我的DrawView课程

import java.util.ArrayList;
import java.util.List;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.Log;
import android.view.SurfaceView;

public class DrawView extends SurfaceView {

    private Paint textPaint = new Paint();
    private List<Rect> Rectangles;
    private float x_axis;
    private float y_axis;
    private boolean found;
    private String TAG="DrawView";
    private Rect tempRect;



    public DrawView(Context context) {
        super(context);
        // Create out paint to use for drawing
        textPaint.setARGB(255, 200, 0, 0);
        textPaint.setStyle(Paint.Style.STROKE);
        textPaint.setColor(Color.RED);
        textPaint.setStrokeWidth(3);
        textPaint.setAlpha(200);
        /* This call is necessary, or else the 
         * draw method will not be called. 
         */
        Rectangles=new ArrayList<Rect>();

        setWillNotDraw(false);
    }


    public void setCoordinates (float x1, float y1) {

        x_axis=x1;
        y_axis=y1;

        Rectangles.add(new Rect(Math.round(x_axis)-150, Math.round(y_axis)-70, Math.round(x_axis)+150, Math.round(y_axis)+70));
        // indicate view should be redrawn
        postInvalidate();

    }

    public void tryDrag(float x, float y){

        if(tempRect!=null){
            tempRect.set(Math.round(x-tempRect.width()/2),Math.round(y+tempRect.height()/2)
                    ,Math.round(x+tempRect.width()/2),Math.round(y-tempRect.height()/2));
            postInvalidate();
        }

    }
    public void DrawNow(){
        postInvalidate();
    }

    public void   animateDrag(float x, float y){
        found=false;
        tempRect=null;
        for(Rect R: Rectangles){

            if(R.contains(Math.round(x), Math.round(y))){
                found=true;
                tempRect =R;
                break;
            }

        }


        if(found){

            Log.d(TAG, "inside a rectange");        
        }

    }

    public void doScale(float x, float y){
        if(tempRect!=null){

            int tempWidth=Math.round((tempRect.width()*x)/2);
            int tempHeight=Math.round((tempRect.height()*y)/2);

            tempRect.set(tempRect.centerX()-tempWidth,tempRect.centerY()+tempHeight,tempRect.centerX()+tempWidth,tempRect.centerY()-tempHeight);

            postInvalidate();

        }

    }


    @Override
    protected void onDraw(Canvas canvas){
        // A Simple Text Render to test the display

        for(Rect R: Rectangles)
            canvas.drawRect(R.left,R.top,R.right,R.bottom, textPaint);


    }
}
    private float scaleFactorY;
    private float scaleFactorX;

    @Override 
    public boolean onTouchEvent(MotionEvent event){ 


        mScaleDetector.onTouchEvent(event);

        if(mScaleDetector.isInProgress()) return false;
        //let the ScaleGestureDetector try first

        // if scale detector is not in progress 
        mDetector.onTouchEvent(event);
        super.onTouchEvent(event);
        return true;

    }

    @Override
    public boolean onDown(MotionEvent event) { 
        Log.d(DEBUG_TAG,"onDown: " ); 
        if(scaling==0)
        dv.animateDrag(event.getX(),event.getY());
        return true;
    }

    @Override
    public boolean onFling(MotionEvent event1, MotionEvent event2, 
            float velocityX, float velocityY) {
        Log.d(DEBUG_TAG, "onFling: " );
        return true;
    }

    @Override
    public void onLongPress(MotionEvent event) {
        Log.d(DEBUG_TAG, "onLongPress: "); 


    }

    @Override
    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
            float distanceY) {
        if(scaling>0) return false;
        dv.tryDrag(e2.getX(),e2.getY());
        return true;
    }

    @Override
    public void onShowPress(MotionEvent event) {
        Log.d(DEBUG_TAG, "onShowPress: ");
    }

    @Override
    public boolean onSingleTapUp(MotionEvent event) {
        Log.d(DEBUG_TAG, "onSingleTapUp: " );
        return true;
    }

    @Override
    public boolean onDoubleTap(MotionEvent event) {
        Log.d(DEBUG_TAG, "onDoubleTap: ");
        return true;
    }

    @Override
    public boolean onDoubleTapEvent(MotionEvent event) {
        Log.d(DEBUG_TAG, "onDoubleTapEvent: ");
        return true;
    }

    @Override
    public boolean onSingleTapConfirmed(MotionEvent event) {
        Log.d(DEBUG_TAG, "onSingleTapConfirmed: ");

        int pointerIndex0 = event.findPointerIndex(event.getPointerId(0));
        // Get the 1st pointer's current position
        float x0 = event.getX(pointerIndex0);
        float y0 = event.getY(pointerIndex0);
        Log.d(TAG, "X0= "+x0+ " Y0=" + y0);

        if(RactangleCount<5){

            dv.setCoordinates(x0, y0);

            if (safeToTakePicture && prvw) {

                ((FrameLayout) findViewById(R.id.preview)).addView(dv);

                safeToTakePicture = false;
                preview.camera.takePicture(shutterCallback, rawCallback, jpegCallback); 
                prvw=false; 

            }

            RactangleCount++;
        }


        return true;
    }





    @Override
    public boolean onDrag(View v, DragEvent event) {
        // TODO Auto-generated method stub
        Log.d(TAG,"on Drag");
        // dv.animateDrag(event.getX(),event.getY());

        //dv.tryDrag(e2.getX(),e2.getY());
        return false;
    }





    @Override
    public boolean onScale(ScaleGestureDetector detector) {
        scaling++;
        Log.d(TAG,"on scale");

            scaleFactorX= detector.getCurrentSpanX()/detector.getPreviousSpanX();
            scaleFactorY= detector.getCurrentSpanY()/detector.getPreviousSpanY();
            Log.d(TAG,"on" + "Xfactor"+scaleFactorX+"Yfactor"+scaleFactorY);



        dv.doScale(scaleFactorX,scaleFactorY);

        return true;
    }





    @Override
    public boolean onScaleBegin(ScaleGestureDetector detector) {
        // TODO Auto-generated method stub

        scaling=1;
        Log.d(TAG,"on scale begin");


        return true;
    }





    @Override
    public void onScaleEnd(ScaleGestureDetector detector) {
        // TODO Auto-generated method stub
        Log.d(TAG,"on scale end");

        scaling=0;
    }
}
import java.util.ArrayList;
导入java.util.List;
导入android.content.Context;
导入android.graphics.Canvas;
导入android.graphics.Color;
导入android.graphics.Paint;
导入android.graphics.Rect;
导入android.util.Log;
导入android.view.SurfaceView;
公共类DrawView扩展了SurfaceView{
私有绘画文本绘画=新绘画();
私有列表矩形;
私有浮动x_轴;
私有浮动y_轴;
发现私有布尔值;
私有字符串标记=“DrawView”;
私有Rect-tempRect;
公共绘图视图(上下文){
超级(上下文);
//创建用于绘图的绘制
setARGB(255,200,0,0);
textPaint.setStyle(Paint.Style.STROKE);
textPaint.setColor(Color.RED);
textPaint.设置行程宽度(3);
textPaint.setAlpha(200);
/*这个电话是必须的,否则
*将不调用draw方法。
*/
矩形=新的ArrayList();
setWillNotDraw(假);
}
公共无效集合坐标(浮点x1,浮点y1){
x_轴=x1;
y_轴=y1;
添加(新矩形(数学圆(x_轴)-150,数学圆(y_轴)-70,数学圆(x_轴)+150,数学圆(y_轴)+70);
//指示应重新绘制视图
后验证();
}
公共无效tryDrag(浮动x,浮动y){
if(tempRect!=null){
tempRect.set(Math.round(x-tempRect.width()/2)、Math.round(y+tempRect.height()/2)
,Math.round(x+tempRect.width()/2),Math.round(y-tempRect.height()/2);
后验证();
}
}
公众假期{
后验证();
}
公共无效动画标记(浮动x、浮动y){
发现=错误;
tempRect=null;
用于(矩形R:矩形){
if(R.contains(Math.round(x)、Math.round(y))){
发现=真;
tempRect=R;
打破
}
}
如果(找到){
Log.d(标记“在矩形范围内”);
}
}
公共无效剂量表(浮动x、浮动y){
if(tempRect!=null){
int tempWidth=Math.round((tempRect.width()*x)/2);
int tempHeight=Math.round((tempRect.height()*y)/2);
tempRect.set(tempRect.centerX()-tempWidth,tempRect.centerY()+tempHeight,tempRect.centerX()+tempWidth,tempRect.centerY()-tempHeight);
后验证();
}
}
@凌驾
受保护的void onDraw(画布){
//用于测试显示的简单文本渲染
用于(矩形R:矩形)
canvas.drawRect(右左、右上、右右下、textPaint);
}
}
这是我的活动类代码部分

import java.util.ArrayList;
import java.util.List;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.Log;
import android.view.SurfaceView;

public class DrawView extends SurfaceView {

    private Paint textPaint = new Paint();
    private List<Rect> Rectangles;
    private float x_axis;
    private float y_axis;
    private boolean found;
    private String TAG="DrawView";
    private Rect tempRect;



    public DrawView(Context context) {
        super(context);
        // Create out paint to use for drawing
        textPaint.setARGB(255, 200, 0, 0);
        textPaint.setStyle(Paint.Style.STROKE);
        textPaint.setColor(Color.RED);
        textPaint.setStrokeWidth(3);
        textPaint.setAlpha(200);
        /* This call is necessary, or else the 
         * draw method will not be called. 
         */
        Rectangles=new ArrayList<Rect>();

        setWillNotDraw(false);
    }


    public void setCoordinates (float x1, float y1) {

        x_axis=x1;
        y_axis=y1;

        Rectangles.add(new Rect(Math.round(x_axis)-150, Math.round(y_axis)-70, Math.round(x_axis)+150, Math.round(y_axis)+70));
        // indicate view should be redrawn
        postInvalidate();

    }

    public void tryDrag(float x, float y){

        if(tempRect!=null){
            tempRect.set(Math.round(x-tempRect.width()/2),Math.round(y+tempRect.height()/2)
                    ,Math.round(x+tempRect.width()/2),Math.round(y-tempRect.height()/2));
            postInvalidate();
        }

    }
    public void DrawNow(){
        postInvalidate();
    }

    public void   animateDrag(float x, float y){
        found=false;
        tempRect=null;
        for(Rect R: Rectangles){

            if(R.contains(Math.round(x), Math.round(y))){
                found=true;
                tempRect =R;
                break;
            }

        }


        if(found){

            Log.d(TAG, "inside a rectange");        
        }

    }

    public void doScale(float x, float y){
        if(tempRect!=null){

            int tempWidth=Math.round((tempRect.width()*x)/2);
            int tempHeight=Math.round((tempRect.height()*y)/2);

            tempRect.set(tempRect.centerX()-tempWidth,tempRect.centerY()+tempHeight,tempRect.centerX()+tempWidth,tempRect.centerY()-tempHeight);

            postInvalidate();

        }

    }


    @Override
    protected void onDraw(Canvas canvas){
        // A Simple Text Render to test the display

        for(Rect R: Rectangles)
            canvas.drawRect(R.left,R.top,R.right,R.bottom, textPaint);


    }
}
    private float scaleFactorY;
    private float scaleFactorX;

    @Override 
    public boolean onTouchEvent(MotionEvent event){ 


        mScaleDetector.onTouchEvent(event);

        if(mScaleDetector.isInProgress()) return false;
        //let the ScaleGestureDetector try first

        // if scale detector is not in progress 
        mDetector.onTouchEvent(event);
        super.onTouchEvent(event);
        return true;

    }

    @Override
    public boolean onDown(MotionEvent event) { 
        Log.d(DEBUG_TAG,"onDown: " ); 
        if(scaling==0)
        dv.animateDrag(event.getX(),event.getY());
        return true;
    }

    @Override
    public boolean onFling(MotionEvent event1, MotionEvent event2, 
            float velocityX, float velocityY) {
        Log.d(DEBUG_TAG, "onFling: " );
        return true;
    }

    @Override
    public void onLongPress(MotionEvent event) {
        Log.d(DEBUG_TAG, "onLongPress: "); 


    }

    @Override
    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
            float distanceY) {
        if(scaling>0) return false;
        dv.tryDrag(e2.getX(),e2.getY());
        return true;
    }

    @Override
    public void onShowPress(MotionEvent event) {
        Log.d(DEBUG_TAG, "onShowPress: ");
    }

    @Override
    public boolean onSingleTapUp(MotionEvent event) {
        Log.d(DEBUG_TAG, "onSingleTapUp: " );
        return true;
    }

    @Override
    public boolean onDoubleTap(MotionEvent event) {
        Log.d(DEBUG_TAG, "onDoubleTap: ");
        return true;
    }

    @Override
    public boolean onDoubleTapEvent(MotionEvent event) {
        Log.d(DEBUG_TAG, "onDoubleTapEvent: ");
        return true;
    }

    @Override
    public boolean onSingleTapConfirmed(MotionEvent event) {
        Log.d(DEBUG_TAG, "onSingleTapConfirmed: ");

        int pointerIndex0 = event.findPointerIndex(event.getPointerId(0));
        // Get the 1st pointer's current position
        float x0 = event.getX(pointerIndex0);
        float y0 = event.getY(pointerIndex0);
        Log.d(TAG, "X0= "+x0+ " Y0=" + y0);

        if(RactangleCount<5){

            dv.setCoordinates(x0, y0);

            if (safeToTakePicture && prvw) {

                ((FrameLayout) findViewById(R.id.preview)).addView(dv);

                safeToTakePicture = false;
                preview.camera.takePicture(shutterCallback, rawCallback, jpegCallback); 
                prvw=false; 

            }

            RactangleCount++;
        }


        return true;
    }





    @Override
    public boolean onDrag(View v, DragEvent event) {
        // TODO Auto-generated method stub
        Log.d(TAG,"on Drag");
        // dv.animateDrag(event.getX(),event.getY());

        //dv.tryDrag(e2.getX(),e2.getY());
        return false;
    }





    @Override
    public boolean onScale(ScaleGestureDetector detector) {
        scaling++;
        Log.d(TAG,"on scale");

            scaleFactorX= detector.getCurrentSpanX()/detector.getPreviousSpanX();
            scaleFactorY= detector.getCurrentSpanY()/detector.getPreviousSpanY();
            Log.d(TAG,"on" + "Xfactor"+scaleFactorX+"Yfactor"+scaleFactorY);



        dv.doScale(scaleFactorX,scaleFactorY);

        return true;
    }





    @Override
    public boolean onScaleBegin(ScaleGestureDetector detector) {
        // TODO Auto-generated method stub

        scaling=1;
        Log.d(TAG,"on scale begin");


        return true;
    }





    @Override
    public void onScaleEnd(ScaleGestureDetector detector) {
        // TODO Auto-generated method stub
        Log.d(TAG,"on scale end");

        scaling=0;
    }
}
private float scaleFactorY;
私有浮点scaleFactorX;
@凌驾
公共布尔onTouchEvent(MotionEvent事件){
mScaleDetector.onTouchEvent(事件);
if(mscaledtector.isInProgress())返回false;
//让ScaleGestureDetector先试试
//如果天平探测器未运行
mDetector.onTouchEvent(事件);
超级事件(事件);
返回true;
}
@凌驾
公共布尔onDown(MotionEvent事件){
Log.d(DEBUG_标记,“onDown:”);
如果(缩放==0)
animateDrag(event.getX(),event.getY());
返回true;
}
@凌驾
公共布尔onFling(MotionEvent1、MotionEvent2、,
浮动速度x,浮动速度y){
Log.d(DEBUG_标记,“onFling:”);
返回true;
}
@凌驾
public void onLongPress(运动事件){
Log.d(DEBUG_标签,“onLongPress:”);
}
@凌驾
公共布尔onScroll(MotionEvent e1、MotionEvent e2、浮点距离X、,
浮动距离){
如果(缩放>0)返回false;
dv.tryDrag(e2.getX(),e2.getY());
返回true;
}
@凌驾
在ShowPress上公开作废(运动事件){
Log.d(DEBUG_标记,“onShowPress:”);
}
@凌驾
公共布尔onSingleTapUp(运动事件){
Log.d(DEBUG_标记,“onSingleTapUp:”);
返回true;
}
@凌驾
公共布尔onDoubleTap(运动事件){
Log.d(DEBUG_标签,“onDoubleTap:”);
返回true;
}
@凌驾
公共布尔OnDoubleTapeEvent(运动事件){
Log.d(DEBUG_标记,“onDoubleTapEvent:”);
返回true;
}
@凌驾
公共布尔值OnSingleTapConfiged(MotionEvent事件){
d(DEBUG_标记,“onSingleTapConfirmed:”);
int pointerIndex0=event.findPointerIndex(event.getPointerId(0));
//获取第一个指针的当前位置
float x0=event.getX(pointerIndex0);
float y0=event.getY(pointerIndex0);
Log.d(标签,“X0=”+X0+“Y0=”+Y0);
如果(计算)已解决!
如果任何人有相同类型的问题,答案是检查矩形边界。。顶部y坐标始终应小于底部y坐标。否则曲面视图可能会产生意外结果

这是有错误的一行

 tempRect.set(tempRect.centerX()-tempWidth,tempRect.centerY()+tempHeight,tempRect.centerX()+tempWidth,tempRect.centerY()-tempHeight);
它应该被更正为

tempRect.set(tempRect.centerX()-tempWidth,tempRect.centerY()-tempHeight,tempRect.centerX()+tempWidth,tempRect.centerY()+tempHeight);

非常感谢你,你让我高兴极了。