Неверный грязный прямоугольник с аппаратным ускорением
В этом классе я рисую простую основу для Tic-Tae-Toe. Он состоит из перехваченных линий и "Х" в центре ячейки. Поэтому, когда пользователь касается ячейки, тогда textColor
в нем надо поменять.
я использую invalidate(rect)
перерисовать конкретную ячейку, но в этом случае каждая ячейка меняется, это textColor
,
По словам Ромена Гая, canvas
с полным видом Rect
приходит для рисования. DisplayList
найдет перехват между командами рисования и вашей грязной Rect
и только эти команды будут нарисованы. Но кажется, что это не так. Частичная аннулирование в пользовательском представлении Android с аппаратным ускорением
А также я обнаружил странное изменение кода между 4.4 - 5.0 Android. Итак, вы можете видеть, что mCurrentDirty
исчез из кода вообще. Android View.invalidate (Rect) различное поведение между двумя устройствами
PS для SA эта логика работает корректно и только грязно Rect
изменено
package com.eugeneshapovalov.fizmigclient
import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.Rect
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.View
import timber.log.Timber
class TicTacToeView : View, View.OnTouchListener {
constructor(context: Context) : this(context, null)
constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
companion object {
const val CELL_SIZE_RATIO = 1 / 3f
const val LINE_SIZE = 2f
const val CELL_COUNT = 3
}
val linePaint = Paint()
val textPaint = Paint()
val dirtyCell = Rect()
var colorNumber: Int
init {
setOnTouchListener(this)
colorNumber = 0
linePaint.strokeWidth = resources.displayMetrics.density * LINE_SIZE
textPaint.textSize = 60f
}
private lateinit var cells: Array<Array<Rect>>
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
super.onSizeChanged(w, h, oldw, oldh)
initCells()
}
private fun initCells() {
cells = Array(CELL_COUNT, { Array(CELL_COUNT, { Rect() }) })
val xCell = (width * CELL_SIZE_RATIO).toInt()
val yCell = (height * CELL_SIZE_RATIO).toInt()
for (i in 0 until CELL_COUNT) {
for (j in 0 until CELL_COUNT) {
cells[i][j].left = (x + j * xCell).toInt()
cells[i][j].top = (y + i * yCell).toInt()
cells[i][j].right = (x + (j + 1) * xCell).toInt()
cells[i][j].bottom = (y + (i + 1) * yCell).toInt()
}
}
}
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
drawLines(canvas)
drawText(canvas)
}
private fun drawLines(canvas: Canvas) {
// Vertical lines
canvas.drawLine(x + width * CELL_SIZE_RATIO, y, x + width * CELL_SIZE_RATIO, y + height, linePaint)
canvas.drawLine(x + width * 2 * CELL_SIZE_RATIO, y, x + width * 2 * CELL_SIZE_RATIO, y + height, linePaint)
// Horizontal lines
canvas.drawLine(x, y + height * CELL_SIZE_RATIO, x + width, y + height * CELL_SIZE_RATIO, linePaint)
canvas.drawLine(x, y + height * 2 * CELL_SIZE_RATIO, x + width, y + height * 2 * CELL_SIZE_RATIO, linePaint)
}
private fun drawText(canvas: Canvas) {
textPaint.color = when (colorNumber % 5) {
0 -> Color.BLACK
1 -> Color.BLUE
2 -> Color.RED
3 -> Color.GRAY
4 -> Color.YELLOW
else -> Color.GREEN
}
for (i in 0 until CELL_COUNT) {
for (j in 0 until CELL_COUNT) {
val rect = cells[i][j]
canvas.drawText("X", rect.exactCenterX(), rect.exactCenterY(), textPaint)
}
}
}
override fun onTouch(v: View?, event: MotionEvent?): Boolean {
when (event?.action) {
MotionEvent.ACTION_UP -> {
for (i in 0 until CELL_COUNT) {
for (j in 0 until CELL_COUNT) {
val rect = cells[i][j]
if (rect.contains(event.x.toInt(), event.y.toInt())) {
colorNumber += (j + 7)
Timber.d("Rect: ${rect.flattenToString()}")
invalidate(rect)
}
}
}
}
}
return true
}
}