在这门课上,我为井字游戏画了简单的基础。它由截断的线和单元格中心的“X”组成。因此,当用户触摸单元格时,textColor
应该更改它。
我invalidate(rect)
用来重绘混凝土单元格,但在这种情况下,每个单元格都会更改它的textColor
.
用Romain Guy的话来说,canvas
with the whole viewRect
是为绘图而来的。将在绘图命令和您的dirtyDisplayList
之间找到拦截,并且只会绘制那些命令。但似乎,它不是这样工作的。
使用硬件加速的自定义 Android 视图中的部分失效 Rect
而且我还发现了4.4 - 5.0 Android 之间的奇怪代码更改。所以你可以看到,它mCurrentDirty
从代码中完全消失了。
Android View.invalidate(Rect) 两个设备之间的不同行为
PS for 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
}
}