Flutter图片缩放插件pinch_zoom_release_unzoom的使用

发布于 1周前 作者 h691938207 来自 Flutter

Flutter图片缩放插件pinch_zoom_release_unzoom的使用

Flutter 插件 pinch_zoom_release_unzoom 提供了一种类似于Instagram的图片缩放体验,用户可以通过捏合手势进行缩放,并且在释放屏幕后会平滑地恢复到原始大小。下面将详细介绍该插件的特性、安装和使用方法,并提供一个完整的示例代码。

Features

  • User-friendly Zooming: 使应用程序能够以用户友好的方式显示可缩放的图像。
  • Interactive Viewer: 是一个未裁剪的交互式查看器,允许用户通过捏合手势放大图像,使其占据整个屏幕。
  • Smooth Animation: 当用户释放屏幕并停止捏合操作时,图像/小部件将以平滑动画返回其原始大小。

Getting Started

添加依赖

首先,在您的 pubspec.yaml 文件中添加以下依赖项:

dependencies:
  pinch_zoom_release_unzoom: ^1.0.1

然后执行 flutter pub get 来安装此包。

Usage

基本用法

最简单的用法是直接包裹您想要实现缩放效果的小部件(如Image):

PinchZoomReleaseUnzoomWidget(
  child: Image.network(
    'https://storage.googleapis.com/cms-storage-bucket/70760bf1e88b184bb1bc.png'
  ),
)

高级配置

您可以根据需求调整更多参数来定制化缩放行为:

PinchZoomReleaseUnzoomWidget(
    child: Image.network('https://storage.googleapis.com/cms-storage-bucket/70760bf1e88b184bb1bc.png'),
    minScale: 0.8, // 最小缩放比例
    maxScale: 4,   // 最大缩放比例
    resetDuration: const Duration(milliseconds: 200), // 回弹动画持续时间
    boundaryMargin: const EdgeInsets.only(bottom: 0), // 边界填充
    clipBehavior: Clip.none, // 裁剪行为
    useOverlay: true,        // 是否使用覆盖层
    maxOverlayOpacity: 0.5,  // 覆盖层最大透明度
    overlayColor: Colors.black, // 覆盖层颜色
    fingersRequiredToPinch: 2 // 捏合所需手指数量
)

Making it work well inside a scroll

当在一个滚动视图内使用 PinchZoomReleaseUnzoomWidget 时,需要处理好捏合手势与滚动之间的冲突。一种解决方案是在检测到两个手指触碰屏幕时禁用滚动物理特性:

bool blockScroll = false;
ScrollController controller = ScrollController();

@override
Widget build(BuildContext context) {
  return SingleChildScrollView(
      controller: controller,
      physics: blockScroll ? NeverScrollableScrollPhysics() : ScrollPhysics(),

同时为 PinchZoomReleaseUnzoomWidget 设置回调函数以控制滚动状态:

twoFingersOn: () => setState(() => blockScroll = true),
twoFingersOff: () => Future.delayed(
  PinchZoomReleaseUnzoomWidget.defaultResetDuration,
  () => setState(() => blockScroll = false),
),

完整示例Demo

这里给出一个完整的例子,展示了如何在一个包含多个页面的应用程序中使用 PinchZoomReleaseUnzoomWidget

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

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) => MaterialApp(
        debugShowCheckedModeBanner: false,
        title: 'Flutter Demo',
        theme: ThemeData.dark(),
        home: const HomeScreen(),
      );
}

class HomeScreen extends StatefulWidget {
  const HomeScreen({super.key});

  @override
  State<HomeScreen> createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  int _selectedIndex = 0;
  final PageController _pageController = PageController();

  void onTap(int value) {
    _selectedIndex = value;
    _pageController.animateToPage(
      value,
      duration: const Duration(milliseconds: 200),
      curve: Curves.easeOut,
    );

    setState(() {});
  }

  @override
  Widget build(BuildContext context) => Scaffold(
        appBar: AppBar(
          title: const Text('Pinch zoom release unzoom'),
        ),
        body: PageView(
          controller: _pageController,
          physics: const NeverScrollableScrollPhysics(),
          children: const [
            TestSimpleScroll(),
          ],
        ),
        bottomNavigationBar: BottomNavigationBar(
          currentIndex: _selectedIndex,
          onTap: onTap,
          selectedItemColor: Theme.of(context).colorScheme.primary,
          unselectedItemColor: Theme.of(context).textTheme.bodyMedium?.color,
          items: const [
            BottomNavigationBarItem(
              icon: Icon(Icons.gesture),
              label: 'Test Scroll Block',
            ),
          ],
        ),
      );
}

class TestSimpleScroll extends StatefulWidget {
  const TestSimpleScroll({super.key});

  @override
  State<TestSimpleScroll> createState() => _TestSimpleScrollState();
}

class _TestSimpleScrollState extends State<TestSimpleScroll> {
  bool blockScroll = false;
  final ScrollController controller = ScrollController();

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

  @override
  Widget build(BuildContext context) => SingleChildScrollView(
        controller: controller,
        physics: blockScroll
            ? const NeverScrollableScrollPhysics()
            : const ScrollPhysics(),
        child: SizedBox(
          width: MediaQuery.of(context).size.width,
          child: Container(
            padding: const EdgeInsets.all(20),
            child: Column(
              children: <Widget>[
                const SizedBox(height: 150),
                const Text(
                  'This widget tries to show the difference between a normal scroll and a scroll with the pinch zoom, and a block scroll approach',
                ),
                SizedBox(
                  width: 300,
                  height: 250,
                  child: PinchZoomReleaseUnzoomWidget(
                    child: Image.network(
                      'https://www.animalfriends.co.uk/siteassets/media/images/article-images/cat-articles/38_afi_article1_caring-for-a-kitten-tips-for-the-first-month.png',
                    ),
                    twoFingersOn: () => setState(() => blockScroll = true),
                    twoFingersOff: () => Future.delayed(
                      PinchZoomReleaseUnzoomWidget.defaultResetDuration,
                      () => setState(() => blockScroll = false),
                    ),
                  ),
                ),
                const SizedBox(height: 50),
                const Text('Scroll'),
                const SizedBox(height: 5000),
              ],
            ),
          ),
        ),
      );
}

这个例子创建了一个简单的应用程序,其中包含一个可以测试捏合缩放功能的页面。通过点击底部导航栏可以在不同类型的页面之间切换。希望这对您有所帮助!如果您有任何问题或需要进一步的帮助,请随时提问。


更多关于Flutter图片缩放插件pinch_zoom_release_unzoom的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter图片缩放插件pinch_zoom_release_unzoom的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter项目中使用pinch_zoom_release_unzoom插件来实现图片缩放功能的示例代码。

首先,你需要在你的pubspec.yaml文件中添加依赖:

dependencies:
  flutter:
    sdk: flutter
  pinch_zoom_release_unzoom: ^最新版本号  # 请确保使用最新版本

然后运行flutter pub get来安装依赖。

接下来,在你的Flutter项目中,你可以创建一个包含图片缩放功能的页面。以下是一个完整的示例:

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

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Pinch Zoom Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: ZoomImageScreen(),
    );
  }
}

class ZoomImageScreen extends StatefulWidget {
  @override
  _ZoomImageScreenState createState() => _ZoomImageScreenState();
}

class _ZoomImageScreenState extends State<ZoomImageScreen> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Pinch Zoom Example'),
      ),
      body: Center(
        child: PinchZoomReleaseUnzoom(
          image: NetworkImage('https://example.com/your-image.jpg'),  // 替换为你的图片URL
          scaleFactor: 1.0,
          minScale: 1.0,
          maxScale: 5.0,
          initialScale: 1.0,
          duration: 200,
          onScaleChanged: (scale) {
            print('Current scale: $scale');
          },
        ),
      ),
    );
  }
}

// 如果图片来自本地资源,可以使用 AssetImage 代替 NetworkImage
// import 'package:flutter/widgets.dart' show AssetImage;
//
// PinchZoomReleaseUnzoom(
//   image: AssetImage('assets/your_image.jpg'),  // 替换为你的本地图片路径
//   ...
// )

在这个示例中,我们创建了一个简单的Flutter应用,其中包含一个可以缩放的图片。我们使用了PinchZoomReleaseUnzoom组件,并配置了相关的属性:

  • image: 图片的来源,可以是网络图片(NetworkImage)或本地图片(AssetImage)。
  • scaleFactor: 当前的缩放比例。
  • minScale: 最小缩放比例。
  • maxScale: 最大缩放比例。
  • initialScale: 初始缩放比例。
  • duration: 缩放动画的持续时间。
  • onScaleChanged: 缩放比例改变时的回调函数。

请确保你已经将图片资源链接或本地图片路径替换为有效的值。

运行这个应用后,你应该能够通过捏合手势来缩放图片,并且在释放手势后图片会恢复到初始缩放比例(如果你需要其他行为,可以自定义)。

回到顶部