kotlin Android -有可能使用画布而不丢失背景吗?

mcvgt66p  于 2022-11-16  发布在  Kotlin
关注(0)|答案(1)|浏览(166)

我试图删除CustomView上的路径,但问题是背景在橡皮擦上被删除了。我试图解析两个相同大小的视图。但当我缩放视图时,问题出现了。我也尝试使用两个画布,但没有用。有什么方法可以用画布绘制而不丢失背景吗?任何帮助都将不胜感激。

我的自定义视图:

import android.content.Context
import android.graphics.*
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.os.Message
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.ScaleGestureDetector
import android.view.ScaleGestureDetector.OnScaleGestureListener
import androidx.appcompat.widget.AppCompatImageView
import androidx.core.content.ContextCompat
import androidx.core.content.ContextCompat.getColor
import androidx.core.content.ContextCompat.getDrawable
import androidx.core.graphics.drawable.toDrawable
import kotlin.math.max

class CustomImageView(context: Context, attributeSet: AttributeSet) :
    AppCompatImageView(context, attributeSet) {
    private var canvas = Canvas()
    private var paint = Paint()
    private var paintBrush = Paint()
    private var paintEraser = Paint()
    private var currentPaintPath = Paint()
    private var path = Path()
    private val pathList = mutableListOf<Stroke>()
    private val backupPath = mutableListOf<Stroke>()
    private val paintPreview = Paint()
    private val drawColor = getColor(context, R.color.green_persian)
    private var strokeSize = STROKE_SIZE
    private var downX = START_POINT
    private var downY = START_POINT
    private var bitmap = Bitmap.createBitmap(200, 200, Bitmap.Config.ARGB_8888)
    private var canvas2 = Canvas()
    private var toolMode = BRUSH_MODE
    private var pointStart = Point()
    private var tracing = false
    private lateinit var findThread: Thread
    private val mGesture: ScaleGestureDetector
    private val maatrix = Matrix()
    init {
        mGesture = ScaleGestureDetector(context, GestureListener())
    }

    private var scaleListener: ScaleListener? = null

    private fun setUpPaint() {
        paintBrush.color = drawColor
        paintBrush.style = Paint.Style.STROKE
        paintBrush.strokeWidth = strokeSize
        paintBrush.strokeCap = Paint.Cap.ROUND
        paintBrush.isAntiAlias = true

        paintEraser.style = Paint.Style.STROKE
        paintEraser.strokeWidth = strokeSize
        paintEraser.strokeCap = Paint.Cap.ROUND
        paintEraser.xfermode = PorterDuffXfermode(PorterDuff.Mode.CLEAR)
        paint = paintBrush
    }

    override fun onDraw(canvas: Canvas?) {
        canvas?.scale(mScaleFactor, mScaleFactor, focusX, focusY)
        super.onDraw(canvas)
//        canvas?.drawColor(Color.BLUE)
        canvas2.drawColor(Color.BLUE)
        canvas2.drawLine(0f,0f,500f,100f,paint);
        for (p in pathList) {
            paint = p.paint
            paint.strokeWidth = p.strokeSize
            canvas?.drawPath(p.path, paint)
        }
        paint = currentPaintPath
        canvas?.drawPath(path, paint)
    }

    internal fun setStrokeSize(size: Int) {
        strokeSize = STROKE_SIZE + size
        paint.strokeWidth = strokeSize
        paintBrush.strokeWidth = strokeSize
        paintEraser.strokeWidth = strokeSize
        invalidate()
        zoomCallback?.brushSize(size)
    }

    internal fun setEraserTool() {
        toolMode = ERASER_MODE
        paint = paintEraser
        invalidate()
        zoomCallback?.eraser()
    }

    override fun onTouchEvent(event: MotionEvent): Boolean {
        mGesture.onTouchEvent(event)
    
        return true
    }

    internal fun clearScreen() {
        path.reset()
        pathList.clear()
        backupPath.clear()
        canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR)
//        setBackgroundColor(Color.TRANSPARENT)
        invalidate()
        zoomCallback?.clear()
    }

    private var mScaleFactor = 1f
    private var focusX = 0f
    private var focusY = 0f
    private var isScaling = false

    inner class GestureListener : OnScaleGestureListener {
        override fun onScale(detector: ScaleGestureDetector): Boolean {
            mScaleFactor *= detector.scaleFactor
            mScaleFactor = max(0.5f, Math.min(mScaleFactor, 2.0f))
            scaleListener?.onScaleListener(focusX, focusY, mScaleFactor)
            postInvalidate()
            return true
        }

        override fun onScaleBegin(detector: ScaleGestureDetector): Boolean {
            isScaling = true
            focusX = detector.focusX
            focusY = detector.focusY
            return true
        }

        override fun onScaleEnd(scaleGestureDetector: ScaleGestureDetector) {
            isScaling = false
        }
    }

    internal fun setScaleListener(listener: ScaleListener) {
        this.scaleListener = listener
    }
}

版面配置:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/black">

    <ImageScaleAble
        android:id="@+id/ivOrigin"
        android:layout_width="322dp"
        android:layout_height="420dp"
        android:layout_marginTop="33.7dp"
        android:layout_marginBottom="132dp"
        android:background="@android:color/transparent"
        android:visibility="invisible"
        android:contentDescription="@string/item_tools_brush"
        app:layout_constraintBottom_toTopOf="@id/bnvTools"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/tbTools"
        app:srcCompat="@drawable/ic_rectangle" />

    <CustomImageView
        android:id="@+id/ivPreview"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:background="@color/white"
        android:foregroundTintMode="screen"
        android:contentDescription="@string/item_tools_brush"
        android:padding="0dp"
        app:layout_constraintBottom_toBottomOf="@+id/ivOrigin"
        app:layout_constraintEnd_toEndOf="@+id/ivOrigin"
        app:layout_constraintStart_toStartOf="@+id/ivOrigin"
        app:layout_constraintTop_toTopOf="@+id/ivOrigin" />

</androidx.constraintlayout.widget.ConstraintLayout>
4c8rllxm

4c8rllxm1#

我认为实现的逻辑相当限制了状态保存特性。
如果你想实现撤销、重做、不同对象的可见性(线条、背景等)以及其他许多功能,我认为最好的方法是将线条和形状保存为列表中的对象,然后在画布上绘制它们,这样当你“清除”画布时,你只删除了你想从画布上擦除的对象,这样你仍然可以在画布上绘制背景形状。

相关问题