Flutter   发布时间:2022-05-03  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了Flutter实战一Flutter聊天应用(十一)大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

@R_681_9616@程序现在可以点击查看图像,但还没有实现查看时放大、缩小与移动图像。要实现这个功能,需要监听用户在图像上的操作,并调用相应的回调处理用户操作。我们先将Transform控件从_ImageZoomableStatebuild方法中拆分出来。在_ImageZoomableState类中添加_drawImage方法

class _ImageZoomableState extends State<ImageZoomable> {
  //...
  Widget _drawImage() {
    if (_image == null) {
      return null;
    }

    return new Transform(
      transform: new Matrix4.diagonal3Values(1.0,1.0,1.0),child: new CustomPaint(
        painter: new _ImageZoomablePainter(
          image: _image,offset: Offset.zero,zoom: 1.0,)
      )
    );
  }
  //...
}

修改_ImageZoomableStatebuild方法,使用GestureDetector控件包装_drawImage方法中的Transform控件,我们可以使用GestureDetector控件监听用户的各种操作手势。

class _ImageZoomableState extends State<ImageZoomable> {
  //...
  @override
  Widget build(BuildContext context) {
    return new GestureDetector(
      child: _drawImage(),);
  }
  //...
}

图片缩放需要一个比例,在ImageZoomable类定义中声明一个成员变量scale来设置图像的显示比例,同时为变量scale设置认值,使scale变量为可选参数。

class ImageZoomable extends StatefulWidget {
  ImageZoomable(this.image,{Key key,this.scale = 2.0}) : super(key: key);

  final ImageProvider image;
  final double scale;

  @override
  _ImageZoomableState createState() => new _ImageZoomableState(scalE);
}

_ImageZoomableState类定义中接收ImageZoomable类成员变量scale,并声明三个Offset(不可变的二维浮点偏移量)类型的成员变量。_starTingFocalPoint变量存储初始焦点值,_prevIoUsOffset变量存储历史偏移量,_offset变量使用静态方法Offset.zero为其赋值,Offset类的静态方法zero返回一个零幅度偏移量,即常量Offset(0.0,0.0)_zoom_prevIoUsZoom则是用于存储缩放值与存储历史缩放值。

class _ImageZoomableState extends State<ImageZoomable> {
  _ImageZoomableState(this._scalE);

  final double _scale;
  ImageStream _imageStream;
  ui.Image _image;

  Offset _starTingFocalPoint;
  Offset _prevIoUsOffset;
  Offset _offset = Offset.zero;

  double _zoom = 1.0;
  double _prevIoUsZoom;
  //...
}

现在我们可以修改_drawImage方法Transform控件的硬编码。

class _ImageZoomableState extends State<ImageZoomable> {
//...
  Widget _drawImage() {
    //...
    return new Transform(
      transform: new Matrix4.diagonal3Values(_scale,_scale,_scalE),child: new CustomPaint(
        painter: new _ImageZoomablePainter(
          image: _image,offset: _offset,zoom: _zoom / _scale,)
      )
    );
  }
  //...
}

现在回到@H_901_5@main.dart文件中来,修改ImageZoomable类的调用

class Chatmessage extends StatelessWidget {
  //...
  @override
  Widget build(BuildContext context) {
    return new SizeTransition(
        //...
                      onTap: (){
                        Navigator.of(context).push( new MaterialPageRoute<Null>(
                          builder: (BuildContext context) {
                            return new ImageZoomable(
                              new NetworkImage(snapshot.value['imageUrl'])
                            );
                          }
                        ));
                      },//...
    );
  }
}

Flutter实战一Flutter聊天应用(十一)

我们要在用户对图像操作之前获取图像偏移位置相关的参数,也就是之前声明一些_ImageZoomableState类成员变量。我们需要在_ImageZoomableState类中增加_handleScaleStart方法作为手势监听器onScaleStart的回调函数

手势监听器onScaleStart触发回调的条件:与屏幕接触的指针已经建立起了一个焦点时,此时初始图像显示比例为1.0。参数details的类型为ScaleStartDetails,该类型存储手势监听器onScaleStart的详细信息,其focalPoint属性以全局坐标方式返回与屏幕接触的指针初始焦点。

class _ImageZoomableState extends State<ImageZoomable> {
  //...
  void _handleScaleStart(ScaleStartDetails details) {
    if (_image == null) {
      return;
    }
    _starTingFocalPoint = details.focalPoint / _scale;
    _prevIoUsOffset = _offset;
    _prevIoUsZoom = _zoom;
  }
  //...
}

现在我们在_ImageZoomableState类的GestureDetector控件中添加一个onScaleStart监听器,把上面的_handleScaleStart方法作为回调。

class _ImageZoomableState extends State<ImageZoomable> {
  //...
  @override
  Widget build(BuildContext context) {
    return new GestureDetector(
      child: _drawImage(),onScaleStart: _handleScaleStart,);
  }
  //...
}

用户对图像操作时,我们需要跟踪焦点的移动,并重新绘制图像。因此我们需要在_ImageZoomableState类中增加_handleScaleupdate方法作为手势监听器onScaleupdate的回调函数,手势监听器onScaleupdate会监听焦点的变化,并在焦点变化时调用回调处理。

_handleScaleupdate方法的参数details的类型为ScaleupdateDetails,该类型存储手势监听器onScaleupdate的详细信息,其focalPoint属性以全局坐标方式返回与屏幕接触的指针焦点。

void _handleScaleupdate(Size size,ScaleupdateDetails details) {
    if (_image == null) {
      return;
    }
    double newZoom = _prevIoUsZoom * details.scale;
    bool tooZoomedIn = _image.width * _scale / newZoom <= size.width ||
        _image.height * _scale / newZoom <= size.height || newZoom <= 0.8;
    if (tooZoomedIn) {
      return;
    }

    setState(() {
      _zoom = newZoom;
      final Offset normalizedOffset = (_starTingFocalPoint - _prevIoUsOffset) / _prevIoUsZoom;
      _offset = details.focalPoint / _scale - normalizedOffset * _zoom;
    });
  }

上面定义了两个局部变量,newZoom存储最新缩放值,tooZoomedIn变量判断图像是否过于放大或缩小。如果tooZoomedIn变量为真时,则不会重新绘制图像。局部变量normalizedOffset用于确保焦点下方的图像保持在相同位置的前提下放大图像。

现在我们在_ImageZoomableState类的GestureDetector控件中添加一个onScaleupdate监听器,把上面的_handleScaleupdate方法作为回调。

class _ImageZoomableState extends State<ImageZoomable> {
  //...
  @override
  Widget build(BuildContext context) {
    return new GestureDetector(
      child: _drawImage(),onScaleupdate: (d) => _handleScaleupdate(context.size,d),);
  }
  //...
}

Flutter实战一Flutter聊天应用(十一)

目前用户在查看图像时,需要点击系统的后退按钮才能返回到聊天屏幕。在大部分应用程序中,在查看图像时点击即可返回聊天屏幕,我们也可以这么做。在ImageZoomable类定义中声明一个GestureTapCallBACk类型的成员变量onTapGestureTapCallBACk类型表示点击发生时的回调函数

class ImageZoomable extends StatefulWidget {
  ImageZoomable(this.image,this.scale = 2.0,this.onTap}) : super(key: key);

  final ImageProvider image;
  final double scale;
  final GestureTapCallBACk onTap;

  @override
  _ImageZoomableState createState() => new _ImageZoomableState(scalE);
}

然后我们需要在_ImageZoomableState类的GestureDetector控件中添加一个onTap监听器,并把ImageZoomable类的成员变量onTap作为回调。

class _ImageZoomableState extends State<ImageZoomable> {
  //...
  @override
  Widget build(BuildContext context) {
    return new GestureDetector(
      child: _drawImage(),onTap: widget.onTap,);
  }
  //...
}

最后回到@H_901_5@main.dart文件中来,修改ImageZoomable类的调用

class Chatmessage extends StatelessWidget {
  //...
  @override
  Widget build(BuildContext context) {
    return new SizeTransition(
        //...
                      onTap: (){
                        Navigator.of(context).push( new MaterialPageRoute<Null>(
                          builder: (BuildContext context) {
                            return new ImageZoomable(
                              new NetworkImage(snapshot.value['imageUrl']),onTap: (){
                                Navigator.of(context).pop();
                              },);
                          }
                        ));
                      },//...
    );
  }
}

现在图像查看,且查看时可以缩放、移动图像的功能已经完成了!

@H_772_442@

大佬总结

以上是大佬教程为你收集整理的Flutter实战一Flutter聊天应用(十一)全部内容,希望文章能够帮你解决Flutter实战一Flutter聊天应用(十一)所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。