Как правильно запихнуть canvas в поток?

170
24 февраля 2018, 21:42

Есть код, который закрашивает голубыми квадратами изображение. Происходит это все сразу при открытии приложения. Как сделать, чтобы постепенно на глазах закрашивались эти квадраты с какой-то задержкой? То есть нужно видимо цикл занести в поток

MainActivity

public class MainActivity extends Activity {
    private View drawView, drawViewRect;
    int i, j;
    String Tag = "oh!";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        drawView = new DrawView(this);
        setContentView(drawView);
        for (i = 1; i <= 36; i++) {
            for (j = 48; j >= 1; j--) {
                drawViewRect = new DrawViewRect(this);
                setContentView(drawViewRect);
            }
        }
    }
}

DrawView

public class DrawView extends View {
    Paint p;
    Rect rect;
    Bitmap bitmap;
    String Tag = "Oh!";
    private int startX = 0;
    private int startY = 0;
    private int endX = 0;
    private int endY = 0;
    private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG) {
        {
            setDither(true);
            setColor(Color.RED);
            setStrokeWidth(20);
        }
    };
    public DrawView(Context context) {
        super(context);
        p = new Paint();
        //шаблон квадрата
        rect = new Rect(0,940,20,960);
    }
    public DrawView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //фоновая заливка
        canvas.drawARGB(80, 102, 204, 255);
        //фоновая картинка
        bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.pic);
        p.setColor(Color.RED);
        canvas.drawBitmap(bitmap, 0, 0, p);
    }
}

DrawViewRect

public class DrawViewRect extends View {
    Paint p;
    Rect rect;
    Bitmap bitmap;
    String Tag = "Oh!";
    //конструктор
    public DrawViewRect(Context context) {
        super(context);
        p = new Paint();
        //шаблон квадрата
        rect = new Rect(0,940,20,960);
    }
    public DrawViewRect(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    @Override
    protected void onDraw(Canvas canvas) {

                p.setStyle(Paint.Style.FILL);
                p.setARGB(255, 0, 0, 255);
                canvas.drawRect(rect, p);
                canvas.translate(0, -20);
    }

}
Answer 1
  1. В классе DrawView из метода onDraw убираем циклы с квадратиками; т.о. метод будет вызываться 1 раз и отрисовывать только фон и картинку.
  2. Создаем еще один класс DrawViewRect для отрисовки квадратиков; в нем метод onDraw будет вызываться столько раз, сколько у нас квадратиков. Сюда помещаем содержимое из циков с квадратиками.
  3. В том месте, откуда у нас вызывался изначально первый клас с методом onDraw, вызываем его, а затем строим циклы, а внутри циклов вызываем второй класс с методом onDraw. Перед вызовом добавляем строчку Thread.currentThread().sleep(200);
Answer 2

Используйте postInvalidateDelayed().

Вот простой пример, как можно рисовать линию постепенно.

public class DrawView extends View {
    private int startX = 0;
    private int startY = 0;
    private int endX = 0;
    private int endY = 0;
    private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG) {
        {
            setDither(true);
            setColor(Color.RED);
            setStrokeWidth(20);
        }
    };
    public DrawView(Context context) {
        super(context);
    }
    public DrawView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawLine(startX, startY, endX, endY, paint);
        if (endX != 300 && endY != 300) {
            endY++;
            endX++;
            postInvalidateDelayed(1000 / 30);
        }
    }
}

И не делайте bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.pic); в onDraw(). Лучше вынести инициализацию в конструктор.

READ ALSO
Проверка ходов в шахматах

Проверка ходов в шахматах

Пишу код для шахматСтолкнулся с проблемой определения корректности хода EnPassant у пешки, то есть, когда вражеская пешка "прыгает" на две клетки...

130
Получить данные из POST запроса в PlayFramework

Получить данные из POST запроса в PlayFramework

Отправляю post-запросом файл,

174
Как распределить логику между классами UI

Как распределить логику между классами UI

У меня есть класс которые в себе содержит логику RecyclerView, также в этом классе содержится логика меню, а помимо этого еще toolBar и другие компоненты...

127
GET запрос Retrofit 2

GET запрос Retrofit 2

Помогите разобраться с запросом Retrofit 2

150