Проблема с invalidate (Rect dirty)

Ответить
Slider007
Сообщения: 2
Зарегистрирован: 04 авг 2013, 18:00

Проблема с invalidate (Rect dirty)

Сообщение Slider007 » 21 окт 2014, 18:04

Друзья, вопрос навеян уроком "Урок 141. Рисование. Доступ к Canvas" http://startandroid.ru/ru/uroki/vse-uro ... anvas.html

Делаю такую вещь:
При нажатии на область экрана, в этой области появляется кружочек.
Делаю так, чтоб перерисовывалась только область непосредственно под кружочком, а не весь экран. Достигаю этого использованием invalidate (Rect dirty):
cir.png
cir.png (25.06 КБ) 3594 просмотра
В эмуляторе (2.3.3) всё заработало как надо (см. картинку).

Проверяю на своем телефоне (Highscreen Boost 2, Android 4.1.2, root) - проблема! :o Перерисовывается весь экран, как будто используется НЕ invalidate (Rect dirty), а invalidate ().

Затем проверяю на планшете (Lenovo, Android 4.4.2) и телефоне жены (Sony Xperia V, Android 4.3). На них всё работает как надо, как в эмуляторе.

Погуглил проблему, оказалось у кого-то тоже похожая проблема на 4.1.2 - http://stackoverflow.com/questions/1867 ... res-bounds

Подскажите, кто знает, что за проблема такая с 4.1.2? И как её обойти можно?

Спасибо!

Вот мой код:
[syntax=java]package ru.slidernsk.test;

import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;


public class TestActivity extends Activity implements OnTouchListener {

float myX;
float myY;
DrawView dw;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.sudoku);
dw = new DrawView(this);
dw.setOnTouchListener(this);
setContentView(dw);
}

class DrawView extends View {
int myColor;
boolean isCreated;
Paint p;

public DrawView(Context context) {
super(context);
p = new Paint();
p.setStyle(Paint.Style.STROKE);
isCreated = false;
}

@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (!isCreated) {
isCreated = true;
}
else {
p.setColor(Color.RED);
p.setStrokeWidth(1);
canvas.drawCircle(myX, myY, 49, p);
}
}

@Override
public boolean performClick() {
super.performClick();
return false;
}
}

@Override
public boolean onTouch(View v, MotionEvent event) {

myX = event.getX();
myY = event.getY();

Rect rect = new Rect();
rect.set((int)(myX-50),(int)(myY-50),(int)(myX+50),(int)(myY+50));

switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
dw.invalidate(rect); //ПЕРЕРИСОВКА ФРАГМЕНТА ЭКРАНА!!!!
break;
case MotionEvent.ACTION_UP:
v.performClick();
break;
default:
break;
}
return true;
}
}[/syntax]

P.S. За код не бейте, первый опыт в java...

Nyashka
Сообщения: 40
Зарегистрирован: 19 мар 2013, 13:06

Re: Проблема с invalidate (Rect dirty)

Сообщение Nyashka » 19 ноя 2014, 15:19

Мне тоже приходилось повозиться с тем что бы заполучить остатки конвы с прошлой прорисовки, так как на гаджете с 2.7 прорисовка кадра целиком занимала 70 мс. Для этих целей я лочил конву как в примере урока на который вы дали ссылку. Обратите внимание что это совсем не тоже самое что invalidate() и на 2.Х это ускоряет работу, а на 4.Х наоборот замедляет, поэтому в 4.Х лучше использовать invalidate(), но там и проблем с производительностью вроде как и нету. Так же стоит обратить внимание что лок конвы дает вам один из нескольких буферов которых может быть 2 или 3, поэтому очередной лок даст вам не предыдущий кадр, а предпредыдущий, или предпредпредыдущий если буферов 3. Если все что вас интересует - это сохранение уже нарисованного, то можете создать свой кэш из битмап, и затем рисовать обновления сначала в кэш, а потом при прорисовке рисовать битмап из кэша (я так делал для повышения производительности на 2.7, но сейчас мне влом заботиться о поддержке таких гаджетов)

Slider007
Сообщения: 2
Зарегистрирован: 04 авг 2013, 18:00

Re: Проблема с invalidate (Rect dirty)

Сообщение Slider007 » 14 дек 2014, 17:36

Спасибо!

Ответить