1

在这门课上,我为井字游戏画了简单的基础。它由截断的线和单元格中心的“X”组成。因此,当用户触摸单元格时,textColor应该更改它。

invalidate(rect)用来重绘混凝土单元格,但在这种情况下,每个单元格都会更改它的textColor.

Romain Guy的话来说,canvaswith 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
    }
}
4

0 回答 0