gpt4 book ai didi

android - 使用表面 View 时闪烁

转载 作者:行者123 更新时间:2023-11-29 00:12:17 26 4
gpt4 key购买 nike

我正在使用表面 View 显示一些图形,问题是当我在屏幕上移动图形时有闪烁效果,我理解这是由于双缓冲问题,尽管我经历了很多帖子,我无法解决问题,请查看我的代码并帮助我解决此问题。

public class CustomSurfaceView  extends SurfaceView implements Runnable{

Thread mThread = null;
SurfaceHolder mSurfaceHolder;
volatile boolean mRunning = false;
Bitmap mBitmap;
boolean mTouched;
float mTouched_x,mTouched_y;
Context mContext;
float mCurrentPosOfRect1x1,mCurrentPosOfRect1y1,mCurrentPosOfRect1x2,mCurrentPosOfRect1y2;
float mCurrentPosOfRect2x1,mCurrentPosOfRect2y1,mCurrentPosOfRect2x2,mCurrentPosOfRect2y2;

private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
boolean isInitialized = false;

/**
* Constructor..
*/
public CustomSurfaceView(Context context) {
super(context);
mSurfaceHolder = getHolder();
mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
mContext = context;

mCurrentPosOfRect1x1 = 100;
mCurrentPosOfRect1y1 = 100;
mCurrentPosOfRect1x2 = 300;
mCurrentPosOfRect1y2 = 300;

mCurrentPosOfRect2x1 = 300;
mCurrentPosOfRect2y1 = 300;
mCurrentPosOfRect2x2 = 500;
mCurrentPosOfRect2y2 = 500;
}

public void onResumeMySurfaceView(){
mRunning = true;
mThread = new Thread(this);
mThread.start();
}

public void onPauseMySurfaceView(){
boolean retry = true;
mRunning = false;
while(retry){
try {
mThread.join();
retry = false;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

@Override
public void run() {
while(mRunning){
if(mSurfaceHolder.getSurface().isValid()){
Canvas canvas = mSurfaceHolder.lockCanvas();
//... actual drawing on canvas

mPaint.setStyle(Paint.Style.STROKE);

if(mTouched){
canvas.drawColor(Color.BLACK);

mPaint.setColor(Color.BLACK);
mPaint.setStrokeWidth(3);
mPaint.setStrokeWidth(0);
mPaint.setColor(Color.CYAN);
//Left,top
//Right bottom.
if(!isInitialized){
canvas.drawRect(mCurrentPosOfRect1x1, mCurrentPosOfRect1y1,mCurrentPosOfRect1x2, mCurrentPosOfRect1y2,mPaint);
isInitialized = true;

}

mPaint.setColor(Color.BLACK);
mPaint.setStrokeWidth(3);
mPaint.setStrokeWidth(0);
mPaint.setColor(Color.BLUE);
//Left,top
//Right bottom.
if(!isInitialized){
canvas.drawRect(mCurrentPosOfRect2x1, mCurrentPosOfRect2y1,mCurrentPosOfRect2x2, mCurrentPosOfRect2y2,mPaint);
isInitialized = true;

}

if(isInitialized){
//Check whether the touch points are inside the rectangle & then move...
if((mTouched_x>mCurrentPosOfRect1x1) && (mTouched_x<mCurrentPosOfRect1x2) && (mTouched_y>mCurrentPosOfRect1y1) && (mTouched_y<mCurrentPosOfRect1y2)){
mCurrentPosOfRect1x1 = mTouched_x-100;
mCurrentPosOfRect1x2 = mTouched_x+100;
mCurrentPosOfRect1y1 = mTouched_y-100;
mCurrentPosOfRect1y2 = mTouched_y+100;
}else if((mTouched_x>mCurrentPosOfRect2x1) && (mTouched_x<mCurrentPosOfRect2x2) && (mTouched_y>mCurrentPosOfRect2y1) && (mTouched_y<mCurrentPosOfRect2y2)){
mCurrentPosOfRect2x1 = mTouched_x-100;
mCurrentPosOfRect2x2 = mTouched_x+100;
mCurrentPosOfRect2y1 = mTouched_y-100;
mCurrentPosOfRect2y2 = mTouched_y+100;

}
}

canvas.drawRect(mCurrentPosOfRect1x1, mCurrentPosOfRect1y1,mCurrentPosOfRect1x2, mCurrentPosOfRect1y2, mPaint);
mPaint.setColor(Color.RED);
canvas.drawRect(mCurrentPosOfRect2x1, mCurrentPosOfRect2y1,mCurrentPosOfRect2x2, mCurrentPosOfRect2y2, mPaint);
mPaint.setColor(Color.BLUE);


Paint paint = new Paint() {
{
setStyle(Paint.Style.STROKE);
setStrokeCap(Paint.Cap.ROUND);
setStrokeWidth(3.0f);
setAntiAlias(true);
}
};

paint.setColor(Color.YELLOW);

final Path path = new Path();
final float x1 = mCurrentPosOfRect1x1+ 100;
final float y1 = mCurrentPosOfRect1y1 + 100;



final float x3 = (mCurrentPosOfRect2x1+ 100) ;
final float y3 = (mCurrentPosOfRect2y1 + 100);

final float x2 = (x1 +200);
final float y2 = (y1 -100);

final float x4 = (x3-100);
final float y4 = (y3+200);

path.moveTo(x1, y1);

path.cubicTo(x2,y2,x4,y4,x3,y3);
canvas.drawPath(path, paint);

}

mSurfaceHolder.unlockCanvasAndPost(canvas);
}

}

}
@Override
public boolean onTouchEvent(MotionEvent event){

mTouched_x = event.getX();
mTouched_y = event.getY();
int action = event.getAction();
switch(action){
case MotionEvent.ACTION_DOWN:
mTouched = true;
break;
case MotionEvent.ACTION_MOVE:
mTouched = true;
break;
case MotionEvent.ACTION_UP:
mTouched = false;
break;
case MotionEvent.ACTION_CANCEL:
mTouched = false;
break;
case MotionEvent.ACTION_OUTSIDE:
mTouched = false;
break;
default:
}
return true; //processed
}
}

最佳答案

如果调用 lockCanvas(),则需要绘制脏矩形中的每个像素。由于您在调用它时没有使用脏矩形,这意味着更新 Canvas 上的每个像素。

我认为您的代码存在问题,当 mTouchedfalse 时,您根本没有绘制任何东西。因为 Surface 是双缓冲或三缓冲的,所以您要重新显示前一帧的内容,这会导致振动效果。

我认为您需要做的就是在 lockCanvas() 调用之前移动对 mTouched 的测试,所以如果您不这样做,就不要翻转缓冲区打算画任何东西。

您可能需要查看 SurfaceView lifecycle appendix在图形架构文档中,如果您以前没有看过它,因为线程管理有时会产生惊喜。

关于android - 使用表面 View 时闪烁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29348022/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com