android - 如何为绘图/素描创建自定义视图(画布),可以像在 Evernote 应用程序中一样在任何方向上无限滚动/拖动
问题描述
我想构建一个绘图应用程序,用户可以在其中绘制用户想要的任何东西,我可以在屏幕大小的画布上绘制,我想为用户提供一个像 Evernote 应用程序这样的功能,用户可以通过拖动在任何方向上绘制帆布。我创建了一个自定义视图,可以在向下滚动时增加高度。但问题是它在滚动时闪烁很多。这里只是一个视图示例,任何帮助将不胜感激。提前致谢。
class DrawingSheet : View, View.OnTouchListener, GestureDetector.OnGestureListener {
private var mLastWidth: Int = 0
private var mLastHeight: Int = 0
private var mBrushStartX: Float = 0f
private var mBrushStartY: Float = 0f
private var mBrushEndX: Float = 0f
private var mBrushEndY: Float = 0f
private var gesture: GestureDetector? = null
private val mCanvas: Canvas = Canvas()
private val mDefaultBrushPaint = Paint().apply {
color = Color.RED
}
init {
minimumWidth = context.resources.displayMetrics.widthPixels
minimumHeight = context.resources.displayMetrics.heightPixels
mLastWidth = minimumWidth
mLastHeight = minimumHeight * 2
gesture = GestureDetector(context, this)
}
constructor(context: Context) : super(context)
constructor(context: Context, attributeSet: AttributeSet) : super(context, attributeSet)
override fun onDraw(canvas: Canvas?) {
super.onDraw(canvas)
canvas?.drawColor(Color.WHITE)
canvas?.drawLine(mBrushStartX, mBrushStartY, mBrushEndX, mBrushEndY, mDefaultBrushPaint)
canvas?.drawCircle(100f, 100f, 200f, mDefaultBrushPaint)
canvas?.drawCircle(600f, 900f, 200f, mDefaultBrushPaint)
canvas?.drawCircle(1000f, 1900f, 200f, mDefaultBrushPaint)
canvas?.drawCircle(1500f, 2900f, 200f, mDefaultBrushPaint)
var x = 0f
var y = 0f
while (y < height) {
canvas?.drawLine(x, y, width.toFloat(), y, mDefaultBrushPaint)
y += 100
}
/*x = 0f
y = 0f
while (x < width) {
canvas?.drawLine(x, y, x, height.toFloat(), mDefaultBrushPaint)
x += 100
}*/
}
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
println("onMeasure")
setMeasuredDimension(mLastWidth, mLastHeight)
}
@SuppressLint("ClickableViewAccessibility")
override fun onTouchEvent(event: MotionEvent?): Boolean {
return gesture?.onTouchEvent(event)!!
}
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
super.onSizeChanged(w, h, oldw, oldh)
}
override fun onDown(event: MotionEvent?): Boolean {
println("onDown")
return true
}
override fun onShowPress(e: MotionEvent?) {
println("onShowPress")
}
override fun onSingleTapUp(e: MotionEvent?): Boolean {
println("onSingleTapUp")
return true
}
override fun onScroll(
e1: MotionEvent?,
e2: MotionEvent?,
distanceX: Float,
distanceY: Float
): Boolean {
println("onScroll")
println(y)
println(distanceY)
println("y + height: ${y + height}")
if (y + height < 2500) {
updateLayoutParams {
height += minimumHeight
}
mLastHeight = layoutParams.height
mLastWidth = layoutParams.width
}
x -= distanceX
y -= distanceY
return true
}
override fun onLongPress(e: MotionEvent?) {
}
override fun onFling(
e1: MotionEvent?,
e2: MotionEvent?,
velocityX: Float,
velocityY: Float
): Boolean {
return true
}
}
解决方案
推荐阅读
- ansible - 当 shell 没有输出时,Ansible 注册失败
- python - 将列表中的数字乘以字符串
- java - 实例化一个新对象,从参数中得到一个indexoutofbounds,它是一个数组
- gcc - 哪些版本的 GMP、MPC 和 MPFR 用于编译 GCC?
- javascript - React hooks setState 可能在 try catch 中出现错误
- jquery - 单击按钮时如何获取与类最接近的值?
- python - 为什么矢量化 Pinv 比未矢量化慢?
- http - 继续没有 ssl 证书
- go - cmd.Process.Kill() 调用后进程不会死
- assembly - 汇编语言:累加器中的结果