我想问一个在这里已经解决过一两次的问题,但是我发现的任何信息都无法帮助我克服几天前遇到的问题。
我想使用画布为 android 制作动态壁纸 - 它的图形不够复杂,不需要 OpenGL。为简单起见,假设它由纯色背景和两个较小的矩形组成。绘图包括三个独立的阶段(在单线程中):
- backgroundDraw() 请求整个画布锁定并在其上绘制纯色
- draw1() 请求部分 (Rect r1) 锁定并仅在锁定的矩形上绘制
- draw2() 请求部分 (Rect r2) 锁定并仅在锁定的矩形上绘制
我在多个 Android 版本(模拟器和设备)上对其进行了测试:2.1、2.2、2.3.3。它似乎只在后一个上正常工作(这里:http ://home.elka.pw.edu.pl/~pgawron/include/Android/android_233.jpg )。在以前的 Android 版本上,SurfaceHolder.lockCanvas(Rect dirty) resizes(!)dirty 作为参数传递给全屏的大小,并使用它进一步绘制结果在整个屏幕上绘制(这里:http ://home.elka.pw.edu .pl/~pgawron/include/Android/android_22.jpg)。事实上,我可以看到每个矩形是如何画得不好的(全屏):整个屏幕很快就会改变它的颜色。
不幸的是,谷歌找不到任何合适的 lockCanvas(Rect dirty) 用法示例。下面我附上我完整且唯一的用于测试目的的课程。在提供的屏幕截图放置的位置可以访问完整的 Eclipse 项目。
如果有人最终可以帮助我并更正我的代码(如果问题出在我的代码中),我将不胜感激。我真的在这上面浪费了太多时间。
BR,
彼得雷利
package sec.polishcode.test;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.os.SystemClock;
import android.service.wallpaper.WallpaperService;
import android.util.Log;
import android.view.SurfaceHolder;
public class TestLiveWallpaper extends WallpaperService{
@Override
public Engine onCreateEngine() {
return new MyEngine();
}
class MyEngine extends Engine implements SurfaceHolder.Callback {
private final String LOGTAG = MyEngine.class.getSimpleName();
private Paint backgroundPaint = new Paint();
private Paint mPaint1 = new Paint();
private Paint mPaint2 = new Paint();
private long lastVisibilityOnChange;
private final Rect r1 = new Rect(20, 20, 60, 280);
private final Rect r2 = new Rect(70, 20, 110, 280);
public MyEngine() {
getSurfaceHolder().addCallback(this);
backgroundPaint.setColor(Color.YELLOW);
mPaint1.setColor(Color.LTGRAY);
mPaint2.setColor(Color.MAGENTA);
}
@Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2,
int arg3) {
drawSurface();
}
@Override
public void surfaceCreated(SurfaceHolder arg0) {
Log.i(LOGTAG, "surfaceCreated");
}
@Override
public void surfaceDestroyed(SurfaceHolder arg0) {
Log.i(LOGTAG, "surfaceDestroyed");
}
@Override
public void onCreate(SurfaceHolder surfaceHolder) {
super.onCreate(surfaceHolder);
setTouchEventsEnabled(true);
}
@Override
public void onVisibilityChanged(boolean visible) {
if (!visible)
return;
lastVisibilityOnChange = SystemClock.elapsedRealtime();
drawSurface();
}
@Override
public void onOffsetsChanged(float xOffset, float yOffset, float xStep,
float yStep, int xPixels, int yPixels) {
if (SystemClock.elapsedRealtime() - lastVisibilityOnChange > 30)
return;
Log.i(LOGTAG, "onOffsetsChanged filtered");
drawSurface();
}
private void drawSurface() {
backgroundDraw();
draw1();
draw2();
}
private void backgroundDraw() {
final SurfaceHolder holder = getSurfaceHolder();
Canvas c = null;
try {
c = holder.lockCanvas();
if (c != null) {
c.drawRect(holder.getSurfaceFrame(), backgroundPaint);
}
} finally {
if (c != null)
holder.unlockCanvasAndPost(c);
}
}
private void draw1() {
final SurfaceHolder holder = getSurfaceHolder();
Canvas c = null;
try {
c = holder.lockCanvas(r1);
if (c != null) {
c.drawRect(r1, mPaint1);
}
} finally {
if (c != null)
holder.unlockCanvasAndPost(c);
}
}
private void draw2() {
final SurfaceHolder holder = getSurfaceHolder();
Canvas c = null;
try {
c = holder.lockCanvas(r2);
if (c != null) {
c.drawRect(r2, mPaint2);
}
} finally {
if (c != null)
holder.unlockCanvasAndPost(c);
}
}
}
}