在绘图应用程序中,若橡皮擦工作,则撤消和重做功能停止工作,反之亦然

iq3niunx  于 2021-09-29  发布在  Java
关注(0)|答案(0)|浏览(220)

我是安卓系统的新手。我正在尝试创建绘图应用程序。我已经实现了画笔大小选择器、颜色选择器、撤消和重做功能,我还想使用porterduffxfermode实现真正的橡皮擦工具。
当我在action_up事件中添加这两行代码时,我得到了期望的结果,橡皮擦工作,但undo和redo函数停止工作。

// commit the path to our offscreen
   canvas?.drawPath(mDrawPath!!, mDrawPaint!!)
//kill this so we don't double draw
   mDrawPath!!.reset()

我会感谢你的帮助,因为我在这个问题上陷入了很长一段时间。
工程视图的全部代码如下所示:

class DrawingView(context: Context, attrs: AttributeSet): View(context, attrs) {

private var mDrawPath: CustomPath? = null
private var mCanvasBitmap: Bitmap? = null
private var mDrawPaint: Paint? = null
private var mCanvasPaint: Paint? = null
private var mBrushSize: Float = 0.toFloat()
private var color: Int = Color.GREEN
private var canvas: Canvas? = null
private val mPaths = ArrayList<CustomPath>()
private val mUndoPaths = ArrayList<CustomPath>()
// Eraser mode
private var erase = false

init {
    setUpDrawing()
}

fun onClickUndo() {
    if (mPaths.size > 0) {
            mUndoPaths.add(mPaths.removeAt(mPaths.size - 1))
        invalidate()
    }
}

fun onClickRedo() {
    if (mUndoPaths.size > 0) {
        mPaths.add(mUndoPaths.removeAt(mUndoPaths.size - 1))
        invalidate()
    }
}

fun onClickEraser(isErase: Boolean) {

    erase = isErase

    if (erase) {
        mDrawPaint!!.xfermode = PorterDuffXfermode(PorterDuff.Mode.CLEAR)
    } else {
        mDrawPaint!!.xfermode = null
    }

}

@RequiresApi(Build.VERSION_CODES.Q)
private fun setUpDrawing() {

        mDrawPaint = Paint()
        mDrawPath = CustomPath(color, mBrushSize)
        mDrawPaint!!.color = color
        mDrawPaint!!.style = Paint.Style.STROKE
        mDrawPaint!!.strokeJoin = Paint.Join.ROUND
        mDrawPaint!!.strokeCap = Paint.Cap.ROUND
        mCanvasPaint = Paint(Paint.DITHER_FLAG)
        mDrawPaint!!.isAntiAlias = true
        mDrawPaint!!.isDither = true
        mDrawPaint!!.xfermode = null
        //mBrushSize = 20.toFloat()
        mDrawPaint!!.setColor(0xFFFF0000)
        mDrawPaint!!.alpha = 0xFF
}

override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
    super.onSizeChanged(w, h, oldw, oldh)
    mCanvasBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888)
    canvas = Canvas(mCanvasBitmap!!)
}

// Change Canvas to Canvas? if fails
@SuppressLint("DrawAllocation")
@RequiresApi(Build.VERSION_CODES.Q)
override fun onDraw(canvas: Canvas) {
    super.onDraw(canvas)

    canvas.drawBitmap(mCanvasBitmap!!, 0f, 0f, mCanvasPaint)       

    for (path in mPaths) {
        mDrawPaint!!.strokeWidth = path.brushThickness
        mDrawPaint!!.color = path.color
        canvas.drawPath(path, mDrawPaint!!)
    }

    if (!mDrawPath!!.isEmpty) {
        mDrawPaint!!.strokeWidth = mDrawPath!!.brushThickness
        mDrawPaint!!.color = mDrawPath!!.color
        canvas.drawPath(mDrawPath!!, mDrawPaint!!)
    }
}

@SuppressLint("ClickableViewAccessibility")
override fun onTouchEvent(event: MotionEvent?): Boolean {
    val touchX = event?.x
    val touchY = event?.y

    when(event?.action){
        MotionEvent.ACTION_DOWN ->{

            mDrawPath!!.color = color
            mDrawPath!!.brushThickness = mBrushSize

            mDrawPath!!.reset()
            if (touchX != null) {
                if (touchY != null) {
                    mDrawPath!!.moveTo(touchX, touchY)
                }
            }
        }
        MotionEvent.ACTION_MOVE ->{
            if (touchX != null) {
                if (touchY != null) {
                    mDrawPath!!.lineTo(touchX, touchY)
                }
            }
        }
        MotionEvent.ACTION_UP ->{
            mDrawPath!!.lineTo(touchX!!, touchY!!)

            //THESE 2 LINES OF CODE
            // commit the path to our offscreen
             canvas?.drawPath(mDrawPath!!, mDrawPaint!!)
            //kill this so we don't double draw
             mDrawPath!!.reset()

            mPaths.add(mDrawPath!!)
            mDrawPath = CustomPath(color, mBrushSize)
        }
        else -> return false
    }
    invalidate()

    return true
}

fun setSizeForBrush(newSize: Float){
    mBrushSize = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, newSize, resources.displayMetrics)
    mDrawPaint!!.strokeWidth = mBrushSize
}

   fun setColor(color: Int){
       this.color = color
    }

internal inner class CustomPath(var color: Int,
                                var brushThickness: Float) : android.graphics.Path()

}

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题