我在绘制到If (input == 0){
Syso "You Tied"
}
Else
{
If (input == -1){
Syso "You Lose"
}
If (input == 1){
Syso "You Win"
}
If (input == 2){
Syso "You Lose"
}
If (input == -2){
Syso "You Win"
}
}
时遇到问题,当移动SurfaceView
上的位图图像时,它们会闪烁(或撕裂)。我在以前的代码迭代中没有遇到这个问题。但是现在我终于通过为每个位图使用单独的SurfaceView
来正确缩放位图,这个问题就开始发生了。这些是我的自定义Canvas
类的重要部分:
SurfaceView
这是我的自定义public class DrawingSurface extends SurfaceView implements SurfaceHolder.Callback {
public DrawingSurface(Context context, AttributeSet attributeSet, int defStyle) {
super(context, attributeSet, defStyle);
initialize(context);
}
private void initialize(Context context) {
mContext = context;
getHolder().addCallback(this);
setFocusable(true);
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
mHost = (EditorActivity) mContext;
Log.d("DrawingSurface", "SURFACE CREATED");
mDrawingThread = new DrawingThread(this, REFRESH_RATE);
mDrawingThread.setRunning(true);
mDrawingThread.start();
onConfigurationChanged(getResources().getConfiguration());
}
public Bitmap createBitmap() {
Bitmap bitmap = Bitmap.createBitmap(mBitmap);
Canvas canvas = new Canvas(bitmap);
Sticker[] stickers = mStickers.toArray(new Sticker[mStickers.size()]);
for (Sticker sticker : stickers) {
canvas.drawBitmap(sticker.getBitmap(), new Matrix(), mPaint);
} return bitmap;
}
public void drawSurface(Canvas canvas) {
Bitmap bitmap = createBitmap();
mMatrix.setScale(1.0f / mScaleFactor, 1.0f / mScaleFactor);
canvas.drawBitmap(bitmap, mMatrix, mPaint);
}
private void setScaleFactor() {
mScaleFactor = ((float) mBitmap.getWidth()) / getWidth();
}
public void addSticker(int drawableId) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inScaled = false;
Sticker sticker = new Sticker(
BitmapFactory.decodeResource(getResources(), drawableId, options),
new PointF(mBitmap.getWidth(), mBitmap.getHeight()),
mScaleFactor);
mActiveSticker = sticker;
mStickers.add(sticker);
}
}
:
Thread
标签类用于保存每个单独的public class DrawingThread extends Thread {
private volatile boolean mRunning = false;
private long mRefreshRate;
private DrawingSurface mSurface;
public DrawingThread (DrawingSurface surface, long time) {
super();
mSurface = surface;
mRefreshRate = time;
}
public void setRunning (boolean run) {
mRunning = run;
Log.d("DrawingThread", "Running: " + mRunning);
}
@Override
public void run() {
while (mRunning) {
try {
sleep(mRefreshRate);
onSurfaceUpdate();
} catch (InterruptedException exception) {
exception.printStackTrace();
}
}
}
public void onSurfaceChanged(Configuration config, Point fit, float ratio) {
float width, height;
if (config.orientation == Configuration.ORIENTATION_LANDSCAPE) {
width = fit.y * ratio;
height = fit.y;
} else if (config.orientation == Configuration.ORIENTATION_PORTRAIT) {
width = fit.x;
height = fit.x / ratio;
} else {
width = fit.x;
height = fit.x / ratio;
} mSurface.getHolder().setFixedSize((int) width, (int) height);
}
private void onSurfaceUpdate() {
Canvas canvas = null;
try {
canvas = mSurface.getHolder().lockCanvas();
synchronized (mSurface.getHolder()) {
if (canvas != null) {
mSurface.drawSurface(canvas);
}
}
} finally {
if (canvas != null) {
mSurface.getHolder().unlockCanvasAndPost(canvas);
}
}
}
}
和Canvas
:
Bitmap
我在StackOverflow以及其他网站上找到了关于同一主题的各种讨论。所有这些都得出结论,闪烁是由于public class Sticker {
private static final float START_SCALE = 0.5f;
private static final float MIN_SCALE = 0.3f;
private static final float MAX_SCALE = 7f;
private float mScale = 1f;
private float mScaleFactor;
private Canvas mCanvas = new Canvas();
private Bitmap mSticker;
private Bitmap mSurface;
private PointF mCenter = new PointF();
private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private Matrix mMatrix = new Matrix();
public Sticker(Bitmap sticker, PointF size, float scaleFactor) {
mSticker = sticker;
mSurface = Bitmap.createBitmap((int) size.x, (int) size.y, Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(mSurface);
mCanvas.drawColor(0, PorterDuff.Mode.CLEAR);
setScaleFactor(scaleFactor);
postSticker();
}
private void postSticker() {
mMatrix.postScale(START_SCALE, START_SCALE);
setCenter();
setTranslate(mCenter.x, mCenter.y);
}
public boolean collider(PointF point) {
int x = (int) (point.x * mScaleFactor);
int y = (int) (point.y * mScaleFactor);
int color = mSurface.getPixel(x, y);
if(color != Color.TRANSPARENT) {
return true;
} else {
return false;
}
}
public Bitmap getBitmap() {
return mSurface;
}
public void flipSticker() {
Matrix matrix = new Matrix();
matrix.preScale(-1, 1);
mSticker = Bitmap.createBitmap(mSticker, 0, 0,
mSticker.getWidth(), mSticker.getHeight(), matrix, false);
}
public void setScaleFactor(float scaleFactor) {
mScaleFactor = scaleFactor;
}
public void setTranslate(float deltaX, float deltaY) {
mMatrix.postTranslate(deltaX * mScaleFactor, deltaY * mScaleFactor);
draw();
}
public void setScale(float deltaScale, PointF midpoint) {
mScale *= deltaScale;
if(MIN_SCALE < mScale && mScale < MAX_SCALE) {
mMatrix.postScale(deltaScale, deltaScale,
midpoint.x * mScaleFactor, midpoint.y * mScaleFactor);
} draw();
}
public void setRotate(float deltaRotate, PointF midpoint) {
mMatrix.postRotate(deltaRotate, midpoint.x * mScaleFactor, midpoint.y * mScaleFactor);
draw();
}
private void setCenter() {
float width = (mSurface.getWidth() / 2) - ((mSticker.getWidth() / 2) * START_SCALE);
float height = (mSurface.getHeight() / 2) - ((mSticker.getHeight() / 2) * START_SCALE);
mCenter.set(width, height);
}
private void draw() {
mCanvas.drawColor(0, PorterDuff.Mode.CLEAR);
mCanvas.drawBitmap(mSticker, mMatrix, mPaint);
}
}
如何处理缓冲,使用两个表面进行交换。解决方案包括使用单独的位图首先绘制所有图像,然后将该位图绘制到SurfaceView
。正如您所看到的,我已经使用SurfaceView
方法完成了此操作,但闪烁仍然存在。
答案 0 :(得分:0)
我认为闪烁是由于Canvas
在createBitmap()
中使用之前未完成对位图的绘制。我将方法getBitmap()
更改为返回mSticker
而不是更大的mSurface
(用于检测用户触摸的位置),因此绘制的位图不是那么大。我添加了方法getMatrix()
以从mMatrix
返回Sticker
,并将其用于canvas.drawBitmap()
中的createBitmap()
方法。这停止了闪烁,即使我用于贴纸的png文件相当大(大多数是1024 x 1024)。