经过魔改接入过开源的图片裁剪框架。但是总是心有不甘,感觉这样不会有什么提升,于是回学校之后整理思路纯手撸了一个,当然有些思路还是借鉴了各种开源框架。但是总归是自己写出来的还是有点激动的!
这是本人第一次尝试完全从头写View,欢迎各位大佬指教。
好的步入正题,首先我们先从图片的缩放开始。
ZoomImageView
fun drawImage(canvas: Canvas?) {
canvas?.drawBitmap(mBitmap, null, frame, null)
Log.d(TAG, "$frame")
}
一个很简单的思路,利用RectF来进行图片的绘制,之所以放上这段弱智的代码,就是表明之后我们只需要专心维护我们的frame就行了!是不是感觉思路清晰了许多。
fun onScroll(disX: Float, disY: Float) {
M.reset()
M.postTranslate(-disX, -disY)
M.mapRect(frame)
}
fun onScale(factor: Float, focusX: Float, focusY: Float) {
if (factor == 1f) {
return
}
M.setScale(factor, factor, focusX, focusY)
M.mapRect(frame)
}
接下来就是图片的拖动和缩放。我们使用Martix对frame进行变化,也是两段很清晰的代码。这些都是基础方法一定要搞清楚,如果对matrix相关方法不熟悉的可以学习学习,我们之后对RectF的变化都是基于matrix的。
ClipImageView
/**
* 缩放手势方法
*/
override fun onScaleBegin(detector: ScaleGestureDetector?): Boolean {
isScaling = true
Log.d(TAG, "onScaleBegin")
return true
}
override fun onScale(detector: ScaleGestureDetector?): Boolean {
Log.d(TAG, "onScale")
if (detector != null) {
zoomImageView.onScale(detector.scaleFactor, scrollX + detector.focusX,
scrollY + detector.focusY)
invalidate()
}
return true
}
override fun onScaleEnd(detector: ScaleGestureDetector?) {
Log.d(TAG, "onScaleEnd")
isScaling = false
}
/**
* 其他手势方法
*/
override fun onScroll(e1: MotionEvent?, e2: MotionEvent?, distanceX: Float, distanceY: Float): Boolean {
Log.d(TAG, "onScroll")
if (mAnchor != null) {
clipImageWindowView.onScroll(mAnchor, -distanceX, -distanceY)
} else {
zoomImageView.onScroll(distanceX, distanceY)
}
invalidate()
return true
}
最后呢为了避免再onTouchEvent中写太多的判断逻辑(好吧其实是我菜),我们使用Android为我们提供的ScaleGestureDetector和GestureDetector对手势进行判断。在修正frame之后重绘图片,就可以得到图片缩放和移动的效果啦!这里忽略关于裁剪框的方法,那些我们留到之后博客再进行讲解。
这里我们只做了最基础的工作,很简单大家可以试一下。下次博客我将为大家详细解析关于图片缩小后的复原,划出边界后的自动修正。而我们也将接触动画的系列知识。
上学党不容易,明天再更新!
忽略复位大概可以达到的效果
项目github地址:https://github.com/lqy20160609/ImageClip