如何检测图像是否平移到边缘,而放大与Flutter交互式视图?

bvjveswy  于 2023-06-24  发布在  Flutter
关注(0)|答案(1)|浏览(168)

我有一个图像从文件作为一个InteractiveView的子。交互式视图本身是PageView的子视图。由于页面控制器,我不得不在图像放大时禁用分页,以便用户可以平移图像而不会转到下一页。
但是,当图像被放大并一直平移到左侧或右侧时,我希望再次启用分页。我该怎么做?

import 'dart:io';

import 'package:flutter/material.dart';

class PhotoViewer extends StatefulWidget {
  final List<String> photoPaths;
  final int startIndex;

  const PhotoViewer({
    super.key,
    required this.photoPaths,
    this.startIndex = 0
  });

  @override
  State<StatefulWidget> createState() => _PhotoViewerState();
}

class _PhotoViewerState extends State<PhotoViewer> {
  late PageController _pageController;
  int _selectedPageIndex = 0;
  bool _pagingEnabled = true;

  @override
  void initState() {
    super.initState();
    _selectedPageIndex = widget.startIndex;
    _pageController = PageController(initialPage: _selectedPageIndex);
  }

  @override
  void dispose() {
    super.dispose();
    _pageController.dispose();
  }

  void _pageChanged(int index) {
    if (_selectedPageIndex != index) {
      _pageController.jumpToPage(index);
      setState(() {
        _selectedPageIndex = index;
      });
    }
    FocusScope.of(context).unfocus();
  }

  void _onScaleChanged(double scale) {
    setState(() {
      _pagingEnabled = scale <= 1.0;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("Trip Photos"), backgroundColor: Colors.black, foregroundColor: Colors.white,),
      body: Container(
        color: Colors.black,
        child: PageView(
          physics: _pagingEnabled ? const PageScrollPhysics() : const NeverScrollableScrollPhysics(),
          controller: _pageController,
          onPageChanged: _pageChanged,
          children: widget.photoPaths.map((path) => _InteractiveImage(path, _onScaleChanged)).toList(),
        ),
      ),
    );
  }
}

class _InteractiveImage extends StatefulWidget {
  String imgPath;
  Function(double) onScaleChanged;

  _InteractiveImage(this.imgPath, this.onScaleChanged);

  @override
  State<StatefulWidget> createState() => _InteractiveImageState();
}

class _InteractiveImageState extends State<_InteractiveImage> {
  late TransformationController _transformationController;

  @override
  void initState() {
    super.initState();
    _transformationController = TransformationController();
  }

  @override
  void dispose() {
    super.dispose();
    _transformationController.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return InteractiveViewer(
      onInteractionEnd: (ScaleEndDetails? details) {
        double scale = _transformationController.value.getMaxScaleOnAxis();
        widget.onScaleChanged(scale);
      },
      transformationController: _transformationController,
      child: Image.file(
          File(widget.imgPath
          )
      ),
    );
  }
}
tjjdgumg

tjjdgumg1#

我遇到了一个类似的问题,当我发现“extended_image”包(https://pub.dev/packages/extended_image)时,它允许用户缩放,只有当图像边界到达其末端时才会滑动到下一页。
这里的关键参数是GestureConfig,它有很多属性,但我们需要的是inPageView。如果它被设置为true,我们得到我们想要的输出。您可以在其官方页面上了解更多信息。
验证码:

import 'package:extended_image/extended_image.dart';
import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Image',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      debugShowCheckedModeBanner: false,
      home: const Image(),
    );
  }
}

class Image extends StatefulWidget {
  const Image({Key? key}) : super(key: key);
  @override
  _CubeState createState() => _CubeState();
}

class _CubeState extends State<Image> {
  List images = [
    "https://img.freepik.com/free-vector/space-game-background-neon-night-alien-landscape_107791-1624.jpg?w=1060&t=st=1673067224~exp=1673067824~hmac=f4f13bff7718874c4b643212bf53455221893a3796885adffd501d231286f651",
    "https://img.freepik.com/free-vector/abstract-splashed-watercolor-textured-background_53876-8725.jpg?w=1060&t=st=1673067234~exp=1673067834~hmac=dbe96266a3b906deb91e91abe19eee18d9e8d6591e25bdbc7ba8264198d6df4b"
  ];
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: ExtendedImageGesturePageView.builder(
          itemBuilder: (BuildContext context, int index) {
            return ExtendedImage.network(
              images[index],
              fit: BoxFit.contain,
              mode: ExtendedImageMode.gesture,
              initGestureConfigHandler: (ExtendedImageState state) {
                return GestureConfig(
                  minScale: 0.9,
                  animationMinScale: 0.7,
                  maxScale: 4.0,
                  animationMaxScale: 4.5,
                  speed: 1.0,
                  inertialSpeed: 100.0,
                  initialScale: 1.0,
                  inPageView: true,
                  initialAlignment: InitialAlignment.center,
                  reverseMousePointerScrollDirection: true,
                  gestureDetailsIsChanged: (GestureDetails? details) {},
                );
              },
            );
          },
          itemCount: images.length,
          onPageChanged: (int index) {},
          scrollDirection: Axis.horizontal,
        ),
      ),
    );
  }
}

输出:-

相关问题