概述:
根据需求方的要求,app中预览大图需要显示高清图片。且支持高清预览横向长图(原图)和纵向长图(原图)。且图片可以自由的放大缩小,并且超长图默认需要撑满横屏或者竖屏,可以滑动查看被遮挡的部分
项目中使用Glide来加载图片,默认情况下Glide是不显示原图的,并且会根据ScaleType计算缓存图片大小然后显示出来。
显示原图可行的方案有两种:
1.通过Glide的asDrawable或者asBitmap把实际的drawable或者Bitmap取出来并放到对应的View上。
2.通过设置Glide.with(this).override(原始图片宽度,原始图片高度)
预览超长图:
1.使用ScalePhotoView
示例代码(重在思路):
1.预览的工具类(支持本地图片和网络图片预览)
class ScaleLongImageUtil { private fun tooHeight(path: String, photoView: GalleryScalePhotoView) { GlideUtils.getInstance() .loadNetDrawable(path, photoView, object : GlideUtils.OnDrawableLoadedListener { override fun onl oadSuccess(resource: Drawable?) { photoView.setImageDrawable(resource) scaleImageVPolicy(photoView, resource!!) } override fun onl oadFailed() { } }) } /** * 竖长图缩放策略: * 1.默认宽度缩放至屏幕宽度 * 2.双击:如果缩放系数>1.0f就=1.0f,如果<=1.0f就放大两倍 */ private fun scaleImageVPolicy( photoView: GalleryScalePhotoView, drawable: Drawable ) { var scale = 1f var orgScale = 1f getRealData(photoView) { realWidth, realHeight -> val screenWidth = PxUtils.getScreenWidth(photoView.context) scale = screenWidth / (realWidth * 1.0f) orgScale = scale photoView.setScale(scale, true) LogUtils.e("width:$realWidth,height:$realHeight,scale:$scale,screenWidth:$screenWidth") } photoView.setOnDoubleTapListener(object : GestureDetector.OnDoubleTapListener { override fun onSingleTapConfirmed(e: MotionEvent?): Boolean { return true } override fun onDoubleTap(e: MotionEvent?): Boolean { var currentScale = photoView.scale if (orgScale >= currentScale) { photoView.scale = scale * 2 } else { photoView.scale = orgScale } return true } override fun onDoubleTapEvent(e: MotionEvent?): Boolean { return true } }) } /** * 横向图片的缩放策略 * 1.默认显示完整宽度(不做任何处理就行,因为fitCenter模式就能完美完成) * 2.放大后双击恢复缩小显示 * 3.如果是缩小装填双击放大置最高等 */ private fun scaleImageHPolicy(photoView: GalleryScalePhotoView) { photoView.setOnDoubleTapListener(object : GestureDetector.OnDoubleTapListener { override fun onSingleTapConfirmed(e: MotionEvent?): Boolean { return true } override fun onDoubleTap(e: MotionEvent?): Boolean { var currentScale = photoView.scale if (currentScale > 1.0f) { photoView.scale = 1.0f } else { photoView.scale = 20.0f } return true } override fun onDoubleTapEvent(e: MotionEvent?): Boolean { return true } }) } private fun imageTooWidth(photoView: GalleryScalePhotoView) { scaleImageHPolicy(photoView) } /** * 定义长图和宽图的策略 */ fun showImageWHPolicy( path: String, photoView: GalleryScalePhotoView, imageWidth: Int, imageHeight: Int ) { LongImageUtil.scaleLongImage( photoView.context, imageWidth, imageHeight, object : LongImageUtil.OnImageScaleListener { override fun onTooWidth(scale: Float) { LogUtils.e("方法名:onTooWidth") GlideUtils.getInstance().loadNetImage(path, photoView) imageTooWidth(photoView) } override fun onTooHeight(scale: Float) { LogUtils.e("方法名:onTooHeight") tooHeight(path, photoView) } override fun onNormal() { LogUtils.e("方法名:onNormal") //啥也不用干 //不对,应该有一个正常图片的双击策略 GlideUtils.getInstance().loadNetImage(path, photoView) } }, PxUtils.getScreenWidth(photoView.context), PxUtils.dp2px(photoView.context, 235f) ) } /** * 获取ImageView实际图片的宽高 */ private fun getRealData( photoView: GalleryScalePhotoView, getWH: (relWidth: Int, relHeight: Int) -> Unit ) { // 获取图片大小 在onDraw()内才能拿到值 val width: Int = photoView.drawable.bounds.width() val height: Int = photoView.drawable.bounds.height() //获得ImageView中Image的变换矩阵 val m: Matrix = photoView.imageMatrix val values = FloatArray(10) m.getValues(values) //Image在绘制过程中的变换矩阵,从中获得x和y方向的缩放系数 val sx = values[0] val sy = values[4] val realImgShowWidth = (width * sx).toInt() val realImgShowHeight = (height * sy).toInt() LogUtils.e("realImgShowWidth:${realImgShowWidth},realImgShowHeight:${realImgShowHeight}") getWH(realImgShowWidth, realImgShowHeight) } }
2.使用方法
scaleUtil = ScaleLongImageUtil() scaleUtil?.showImageWHPolicy(url, ivScaleView, 图片原始宽度, 图片原始高度)
ps:有一个地方非常重要,那就是当ImageView设置ScaleType.fitCenter的时候如何拿到ImageView中的显示区域实际的宽高。拿到这个宽高后就可以就按scale的值了
/** * 获取ImageView实际图片的宽高 */ private fun getRealData( photoView: GalleryScalePhotoView, getWH: (relWidth: Int, relHeight: Int) -> Unit ) { // 获取图片大小 在onDraw()内才能拿到值 val width: Int = photoView.drawable.bounds.width() val height: Int = photoView.drawable.bounds.height() //获得ImageView中Image的变换矩阵 val m: Matrix = photoView.imageMatrix val values = FloatArray(10) m.getValues(values) //Image在绘制过程中的变换矩阵,从中获得x和y方向的缩放系数 val sx = values[0] val sy = values[4] val realImgShowWidth = (width * sx).toInt() val realImgShowHeight = (height * sy).toInt() LogUtils.e("realImgShowWidth:${realImgShowWidth},realImgShowHeight:${realImgShowHeight}") getWH(realImgShowWidth, realImgShowHeight) }
标签:原图,scale,val,Int,override,超长,photoView,fun,Android From: https://www.cnblogs.com/tony-yang-flutter/p/17145545.html