Android SurfaceView Rect对象被删除
我正在开发一个带有多个矩形的绘图视图,这些矩形可以重新调整大小并拖动(在相机预览中)。 我想我成功了。但问题是,矩形似乎被删除了拖动或调整大小时,它们有时会从视图中消失,并从矩形阵列中删除。有人能指出错误吗??提前谢谢 这是我的DrawView课程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
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);
非常感谢你,你让我高兴极了。