在本课程中,我为 Tic-Tae-Toe 绘制了简单的基础。它由截取的行和" X"在牢房的中心。
因此,当用户触摸单元格时,应该更改其中的textColor
。
我使用invalidate(rect)
重绘具体单元格,但在这种情况下,每个单元格都会更改它textColor
。
根据 Romain Guy 字样,canvas
全视图Rect
来了
用于绘图。 DisplayList
会在绘图命令和脏 Rect
之间找到拦截,并且只会绘制这些命令。但似乎它并没有这么做。
Partial invalidation in custom Android view with hardware acceleration
此外,我发现在 4.4 - 5.0 Android之间发生了奇怪的代码更改。所以你可以看到mCurrentDirty
从代码中消失了。
Android View.invalidate(Rect) different behavior between two devices
SA的P.S 此逻辑正常工作,只更改了脏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
}
}