Я хотел бы спросить о проблеме, которая была рассмотрена здесь один или два раза, но никакая информация, которую я нашел, не могла бы помочь мне преодолеть проблему, с которой я столкнулся несколько дней назад.
Я хочу сделать живые обои для андроида, используя холсты - это не достаточно сложно графически, чтобы требовать 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) изменяет размер (!) Dirty, передаваемый в качестве параметра для размера полного экрана и дальнейшего рисования, используя его вывод результатов на весь экран (здесь: http://home.elka.pw.edu.pl/~pgawron/include/Android/android_22.jpg). На самом деле я вижу, как плохо прорисовывается каждый прямоугольник (во весь экран): весь экран очень быстро меняет свой цвет.
К сожалению, Google не смог найти для меня ни одного правильного примера использования lockCanvas (Rect dirty). Ниже я прилагаю свой полный и единственный класс, используемый для целей тестирования. Проект полного затмения доступен только там, где размещены скриншоты.
Я был бы очень признателен, если бы кто-нибудь наконец помог мне и исправил мой код (если бы только проблема была в моем коде). Я действительно потратил слишком много времени на это.
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);
}
}
}
}