flutter photo_view的改造


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;
  }

代碼在這三個文件里,可以將源文件放於一個目錄下


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM