安卓-是否可以在不丢失背景的情况下使用Canvas



我试图删除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>

我认为实现的逻辑非常限制了状态保存功能。

如果你想实现撤消、重做、不同对象(线条、背景等(的可见性和其他许多功能,我认为最好的方法是将线条和形状保存为列表中的对象,然后在画布上绘制它们,所以当你;清除";在画布中,您只删除要从画布中擦除的对象,因此您仍然有画布的背景形状可供绘制。

最新更新