Android, canvas: Как очистить (удалить содержимое) холст (= растровые изображения), живущий в surfaceView?
для того, чтобы сделать простую игру, я использовал шаблон, который рисует полотно с растровыми изображениями, как это:
private void doDraw(Canvas canvas) {
for (int i=0;i<8;i++)
for (int j=0;j<9;j++)
for (int k=0;k<7;k++) {
canvas.drawBitmap(mBits[allBits[i][j][k]], i*50 -k*7, j*50 -k*7, null); } }
(холст определяется в "run ()" / SurfaceView живет в GameThread.)
мой первый вопрос заключается в том, как мне очистить (или перерисовать)весь холст для нового макета?
Во-вторых, как я могу обновить только часть экрана?
// This is the routine that calls "doDraw":
public void run() {
while (mRun) {
Canvas c = null;
try {
c = mSurfaceHolder.lockCanvas(null);
synchronized (mSurfaceHolder) {
if (mMode == STATE_RUNNING)
updateGame();
doDraw(c); }
} finally {
if (c != null) {
mSurfaceHolder.unlockCanvasAndPost(c); } } } }
14 ответов:
Как очистить (или перерисовать) весь холст для нового макета (=попробовать в игре) ?
просто позвони
Canvas.drawColor(Color.BLACK), или любой цвет вы хотите очистить свойCanvasС.и: как я могу обновить только часть экрана ?
нет такого метода, который просто обновляет "часть экрана", так как ОС Android перерисовывает каждый пиксель при обновлении экрана. Но, когда вы не очищаете старый рисунки на вашем
Canvas, старые рисунки все еще находятся на поверхности, и это, вероятно, один из способов "обновить только часть" экрана.Итак, если вы хотите "обновить часть экрана", просто избегайте вызова
Canvas.drawColor()метод.
нарисуйте прозрачный цвет с PorterDuff clear mode делает трюк для того, что я хотел.
Canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR)
нашел это в группах google, и это сработало для меня..
Paint clearPaint = new Paint(); clearPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); canvas.drawRect(0, 0, width, height, clearPaint);Это удаляет рисунков, прямоугольников и т. д. при сохранении набора растрового изображения..
я попробовал ответ @mobistry:
canvas.drawColor(Color.TRANSPARENT, Mode.CLEAR);но это не сработало для меня.
решение для меня было:
canvas.drawColor(Color.TRANSPARENT, Mode.MULTIPLY);может быть, у кого-то есть такая же проблема.
пожалуйста, вставьте ниже код на surfaceview расширить конструктор класса.............
кодирование конструктор
SurfaceHolder holder = getHolder(); holder.addCallback(this); SurfaceView sur = (SurfaceView)findViewById(R.id.surfaceview); sur.setZOrderOnTop(true); // necessary holder = sur.getHolder(); holder.setFormat(PixelFormat.TRANSPARENT);кодирование xml
<com.welcome.panelview.PanelViewWelcomeScreen android:id="@+id/one" android:layout_width="600px" android:layout_height="312px" android:layout_gravity="center" android:layout_marginTop="10px" android:background="@drawable/welcome" />попробовать выше код...
для меня вызов
Canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR)или что-то подобное будет работать только после того, как я коснитесь экрана. Поэтому я бы назвал приведенную выше строку кода, но экран будет очищаться только после того, как я коснулся экрана. Так что для меня сработало позвонитьinvalidate()следовал поinit()который вызывается во время создания для инициализации представления.private void init() { setFocusable(true); setFocusableInTouchMode(true); setOnTouchListener(this); mPaint = new Paint(); mPaint.setAntiAlias(true); mPaint.setDither(true); mPaint.setColor(Color.BLACK); mPaint.setStyle(Paint.Style.STROKE); mPaint.setStrokeJoin(Paint.Join.ROUND); mPaint.setStrokeCap(Paint.Cap.ROUND); mPaint.setStrokeWidth(6); mCanvas = new Canvas(); mPaths = new LinkedList<>(); addNewPath(); }
вот код минимального примера, показывающего, что вы всегда должны перерисовывать каждый пиксель холста в каждом кадре.
это действие рисует новое растровое изображение каждую секунду на SurfaceView, не очищая экран раньше. Если вы протестируете его, вы увидите, что растровое изображение не всегда записывается в один и тот же буфер, и экран будет чередоваться между двумя буферами.
Я тестировал его на своем телефоне (Nexus S, Android 2.3.3) и на эмуляторе (Android 2.2).
public class TestCanvas extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(new TestView(this)); } } class TestView extends SurfaceView implements SurfaceHolder.Callback { private TestThread mThread; private int mWidth; private int mHeight; private Bitmap mBitmap; private SurfaceHolder mSurfaceHolder; public TestView(Context context) { super(context); mThread = new TestThread(); mBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.icon); mSurfaceHolder = getHolder(); mSurfaceHolder.addCallback(this); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { mWidth = width; mHeight = height; mThread.start(); } @Override public void surfaceCreated(SurfaceHolder holder) {/* Do nothing */} @Override public void surfaceDestroyed(SurfaceHolder holder) { if (mThread != null && mThread.isAlive()) mThread.interrupt(); } class TestThread extends Thread { @Override public void run() { while (!isInterrupted()) { Canvas c = null; try { c = mSurfaceHolder.lockCanvas(null); synchronized (mSurfaceHolder) { c.drawBitmap(mBitmap, (int) (Math.random() * mWidth), (int) (Math.random() * mHeight), null); } } finally { if (c != null) mSurfaceHolder.unlockCanvasAndPost(c); } try { sleep(1000); } catch (InterruptedException e) { interrupt(); } } } } }
мне пришлось использовать отдельный чертеж прохода, чтобы очистить холст (блокировка и разблокировка):
Canvas canvas = null; try { canvas = holder.lockCanvas(); if (canvas == null) { // exit drawing thread break; } canvas.drawColor(colorToClearFromCanvas, PorterDuff.Mode.CLEAR); } finally { if (canvas != null) { holder.unlockCanvasAndPost(canvas); } }
ваше первое требование, как очистить или перерисовать весь холст-ответ - использовать холст.drawColor(цвет.Черный) метод для очистки экрана с цветом черного или все, что вы укажете .
ваше второе требование, как обновить часть экрана-ответ - например, если вы хотите сохранить все остальные вещи неизменными на экране, но в небольшой области экрана, чтобы показать целое число(скажем, счетчик), которое увеличивается через каждые пять секунд. затем используйте холст.drawrect метод для рисования это небольшая область, указав левую верхнюю правую нижнюю и краску. затем вычислите значение счетчика(используя postdalayed в течение 5 секунд и т. д. мне нравится Хендлер.postDelayed (Runnable_Object, 5000);) , преобразует его в текстовую строку, вычисляет координаты x и y в этом небольшом прямоугольнике и использует текстовое представление для отображения изменяющегося значения счетчика.
Comments