【问题标题】:InteractiveViewer inside PageViewPageView 中的 InteractiveViewer
【发布时间】:2021-02-21 04:19:52
【问题描述】:

我正在创建一个带有图像列表的 PageView,并且我想将 interactiveViewer 添加到每个图像,以便调整其大小以查看详细信息。

这是我写的:

PageView.builder(
              dragStartBehavior: DragStartBehavior.start,
              physics: _viewing ?  NeverScrollableScrollPhysics() : ClampingScrollPhysics(),
              controller: _pageController,
              itemBuilder: (context, index) {
                return Container(
                    child: Expanded(
                      child: Image.network(widget.snapshotList[index].imgUrl),
                    )
                );
              },
              onPageChanged: (index) {
                setState(() {
                  this.position = index;
                  _transformationController.value = Matrix4.identity();
                });
              },
              itemCount: widget.snapshotList.length,
          )

但是这两个scrollables似乎相互竞争,行为混乱。

例如一旦图像被放大,滚动手势也会触发页面移动, 似乎是因为视口没有随图像本身放大。

有什么解决办法吗?谢谢大家。

【问题讨论】:

    标签: flutter flutter-pageview


    【解决方案1】:

    在我的例子中,我想创建一个简单的可滑动图片库:水平滑动以在图像之间切换,并使用捏合和缩放来放大和缩小。问题是这样的:当我放大时,我无法平移放大的图像。相反,PageView 接管并分页到下一个图像。

    我能够通过使用TransformatinController 并在InteractiveViewer 上收听onInteractionEnd 事件来解决它。在该回调中,我检查图像是否放大。如果放大,我会在PageView 中停用分页。

    这是一个完整的示例应用程序,展示了如何实现它:

    import 'package:flutter/material.dart';
    
    void main() => runApp(MyApp());
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'InteractiveViewer inside PageView Demo',
          debugShowCheckedModeBanner: false,
          theme: ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: const MyHomePage(title: 'Flutter Demo Home Page'),
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
      final String title;
    
      const MyHomePage({
        Key? key,
        required this.title,
      }) : super(key: key);
    
      @override
      _MyHomePageState createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
      final List<ImageProvider> _imageProviders = [
        Image.network("https://picsum.photos/id/1001/5616/3744").image,
        Image.network("https://picsum.photos/id/1003/1181/1772").image,
        Image.network("https://picsum.photos/id/1004/5616/3744").image,
        Image.network("https://picsum.photos/id/1005/5760/3840").image
      ];
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text(widget.title),
          ),
          body: Center(
            child: EasyImageViewPager(imageProviders: _imageProviders)
          ),
        );
      }
    }
    
    /// PageView for swiping through a list of images
    class EasyImageViewPager extends StatefulWidget {
      
      final List<ImageProvider> imageProviders;
    
      /// Create new instance, using the [imageProviders] to populate the [PageView]
      const EasyImageViewPager({ Key? key, required this.imageProviders }) : super(key: key);
    
      @override
      _EasyImageViewPagerState createState() => _EasyImageViewPagerState();
    }
    
    class _EasyImageViewPagerState extends State<EasyImageViewPager> {
    
      final PageController _pageController = PageController();
      bool _pagingEnabled = true;
      
      @override
      void dispose() {
        _pageController.dispose();
        super.dispose();
      }
    
      @override
      Widget build(BuildContext context) {
        return PageView.builder(
          physics: _pagingEnabled ? const PageScrollPhysics() : const NeverScrollableScrollPhysics(),
          itemCount: widget.imageProviders.length,
          controller: _pageController,
          itemBuilder: (context, index) {
            final image = widget.imageProviders[index];
            return EasyImageView(
              imageProvider: image,
              onScaleChanged: (scale) {
                setState(() {
                  // Disable paging when image is zoomed-in
                  _pagingEnabled = scale <= 1.0;
                });
              },
            );
          }, 
        );
      }
    }
    
    /// A full-sized view that displays the given image, supporting pinch & zoom
    class EasyImageView extends StatefulWidget {
    
      /// The image to display
      final ImageProvider imageProvider;
      /// Minimum scale factor
      final double minScale;
      /// Maximum scale factor
      final double maxScale;
      /// Callback for when the scale has changed, only invoked at the end of
      /// an interaction.
      final void Function(double)? onScaleChanged;
      /// Create a new instance
      const EasyImageView({
        Key? key,
        required this.imageProvider,
        this.minScale = 1.0,
        this.maxScale = 5.0,
        this.onScaleChanged,
      }) : super(key: key);
    
      @override
      _EasyImageViewState createState() => _EasyImageViewState();
    }
    
    class _EasyImageViewState extends State<EasyImageView> {
    
      final TransformationController _transformationController = TransformationController();
      
      @override
      Widget build(BuildContext context) {
        return SizedBox(
          width: MediaQuery.of(context).size.width,
          height: MediaQuery.of(context).size.height, 
          child: InteractiveViewer(
            transformationController: _transformationController,
            minScale: widget.minScale,
            maxScale: widget.maxScale,
            child: Image(image: widget.imageProvider),
            onInteractionEnd: (scaleEndDetails) {
              double scale = _transformationController.value.getMaxScaleOnAxis();
    
              if (widget.onScaleChanged != null) {
                widget.onScaleChanged!(scale);
              }
            },
          )
        );
      }
    }
    

    【讨论】:

      猜你喜欢
      • 2021-04-06
      • 1970-01-01
      • 1970-01-01
      • 2019-09-06
      • 1970-01-01
      • 2021-11-19
      • 2021-11-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多