app中對圖片的瀏覽、縮放是一個常用的功能,目前有一款插件photo_view,基本上可以滿足這些功能,但是有些地方需要修改完善
1.雙擊放大的時候,有三個狀態,會有一個放大的中間狀態,需要點擊三次才能回到原始大小,這個不太符合用戶的操作習慣,用戶一般就是雙擊放大,然后在雙擊返回
2.縮小的時候,即使圖片縮小到最小比例了,還需要雙擊下才能翻頁,這個影響用戶體驗
3.放大的時候,不能翻頁,很多app對圖片瀏覽,即使是放大的時候也是可以翻頁的,並且放大的狀態保留,由於此插件基於pageview組件,pageview對子控件的縮放似乎支持的還不夠好,所以作者采取的是放大的時候禁止pageview滾動這一方法來處理,在這里暫且不進行修改。
1.修改雙擊
PhotoViewScaleState nextScaleState(PhotoViewScaleState actual) { switch (actual) { case PhotoViewScaleState.initial: //return PhotoViewScaleState.covering; case PhotoViewScaleState.covering: return PhotoViewScaleState.originalSize; case PhotoViewScaleState.originalSize: return PhotoViewScaleState.initial; case PhotoViewScaleState.zooming: return PhotoViewScaleState.initial; default: return PhotoViewScaleState.initial; } }
注釋改行代碼,使狀態越過中間狀態,其他地方不需要修改
2.修改縮放到最小,不需要雙擊就可以翻頁
enum PhotoViewScaleState { initial, covering, originalSize, zooming,minscale }
添加一個狀態
minscale
void onScaleEnd(ScaleEndDetails details) { final double maxScale = widget.scaleBoundaries.computeMaxScale(); final double minScale = widget.scaleBoundaries.computeMinScale(); //animate back to maxScale if gesture exceeded the maxScale specified if (_scale > maxScale) { final double scaleComebackRatio = maxScale / _scale; animateScale(_scale, maxScale); final Offset clampedPosition = clampPosition(_position * scaleComebackRatio, maxScale); animatePosition(_position, clampedPosition); return; } //animate back to minScale if gesture fell smaller than the minScale specified if (_scale < minScale) { final double scaleComebackRatio = minScale / _scale; animateScale(_scale, minScale); animatePosition( _position, clampPosition(_position * scaleComebackRatio, minScale)); widget.setNextScaleState(PhotoViewScaleState.minscale); return; } // get magnitude from gesture velocity final double magnitude = details.velocity.pixelsPerSecond.distance; // animate velocity only if there is no scale change and a significant magnitude if (_scaleBefore / _scale == 1.0 && magnitude >= 400.0) { final Offset direction = details.velocity.pixelsPerSecond / magnitude; animatePosition(_position, clampPosition(_position + direction * 100.0)); } }
代碼中添加這一句
widget.setNextScaleState(PhotoViewScaleState.minscale);
if判斷增加這一句,目的是為了避免二次刷新
void didUpdateWidget(PhotoViewImageWrapper oldWidget) { super.didUpdateWidget(oldWidget); if (oldWidget.scaleState != widget.scaleState && widget.scaleState != PhotoViewScaleState.zooming&& widget.scaleState != PhotoViewScaleState.minscale) { final double prevScale = _scale == null ? getScaleForScaleState(widget.size, PhotoViewScaleState.initial, widget.childSize, widget.scaleBoundaries) : _scale; final double nextScale = getScaleForScaleState(widget.size, widget.scaleState, widget.childSize, widget.scaleBoundaries); animateScale(prevScale, nextScale); animatePosition(_position, Offset.zero); animateRotation(_rotation, 0.0); } }
同樣在這里也要增加判斷,該狀態下設置pageview的滾動特性
void scaleStateChangedCallback(PhotoViewScaleState scaleState) { setState(() { _locked = (scaleState != PhotoViewScaleState.initial && scaleState != PhotoViewScaleState.minscale); }); widget.scaleStateChangedCallback != null ? widget.scaleStateChangedCallback(scaleState) : null; }
代碼在這三個文件里,可以將源文件放於一個目錄下
