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