Flutter捏合缩放滚动插件pinch_scrollable的使用

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

Flutter捏合缩放滚动插件pinch_scrollable的使用

Flutter 插件 pinch_scrollable 可以帮助创建包含图像的可滚动小部件集合,这些图像是具有放大效果的。这种实现方法可以应用于不同类型的滚动。

功能

  • 图像可以通过捏合手势进行放大。当释放时,它们会恢复到原来的位置和大小。
  • 该包有一个特殊的工具可以在图像放大期间关闭列表的滚动功能。

开始使用

添加依赖

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

dependencies:
  pinch_scrollable: ^1.0.5

使用方式

为了实现捏合缩放的效果,需要使用以下组件:

  • PinchScrollableArea:用于展示图像缩放的区域;
  • PinchItemContainer:接受手势并包含需要放大的图像;
  • PinchScrollLockPhysics:特殊物理属性,防止列表在图片放大时滚动。

简化后的代码结构如下所示:

PinchScrollableArea(
  ...
    Builder(
      builder: (context) => ListView(
        physics: PinchScrollLockPhysics.build(context),
        itemBuilder: (context, index) {
          final key = GlobalKey();
          return PinchItemContainer(
            imageWidgetKey: key,
            imageUrl: imageUrl,
            child: CachedNetworkImage(
              key: key,
              imageUrl: imageUrl,
            ),
          );
        },
      ),
    )
)

其中 Builder 小部件用于使 PinchScrollLockPhysics 能够访问 PinchScrollableArea 的状态。key 是必需的,并用于确定图像参数。

示例代码

下面是一个完整的示例demo,演示了如何在Flutter应用中使用 pinch_scrollable 包来创建一个具有捏合缩放功能的页面。这个例子展示了几个博物馆的信息卡片,每个卡片上有一张可以缩放的图片。

import 'package:cached_network_image/cached_network_image.dart';
import 'package:carousel_slider/carousel_slider.dart';
import 'package:flutter/material.dart';
import 'package:pinch_scrollable/pinch_scrollable.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyListPage(),
    );
  }
}

@immutable
class MuseumDetails {
  const MuseumDetails({
    required this.title,
    required this.details,
    required this.imageUrl,
  });

  final String title;
  final String details;
  final String imageUrl;
}

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

  @override
  Widget build(BuildContext context) {
    return PinchScrollableArea(
      child: Scaffold(
        appBar: AppBar(
          title: Text('Pinch scrollable demo'),
        ),
        backgroundColor: Colors.white70,
        body: _MuseumsList(),
      ),
    );
  }
}

class _MuseumsList extends StatelessWidget {
  const _MuseumsList({Key? key}) : super(key: key);

  static const _museums = const <MuseumDetails>[
    const MuseumDetails(
      title: 'Louvre Museum',
      details:
          'The Louvre Museum in Paris is the largest art museum in the world.',
      imageUrl:
          'https://image.wmsm.co/eef1ef270f8045c067c3646caa7047b3/louvre-museum-paris-1.jpg?quality=80&width=1280',
    ),
    const MuseumDetails(
      title: 'Musée Rodin',
      details:
          'Visit the former workshop of the founder of modern sculpting - Auguste Rodin. Opened in 1919, the Musée Rodin museum houses a great collection of his works.',
      imageUrl:
          'https://image.wmsm.co/644942ebccdd976e0a4cf9b86844216b/musee-rodin-paris-1.jpg?quality=80&width=1280',
    ),
    const MuseumDetails(
      title: 'City of Paris Fine Art Museum',
      details:
          'The City of Paris Fine Art Museum is housed in the Petit Palais in Paris, which was built for the 1900 World\'s Fair by the architect Charles Girault.',
      imageUrl:
          'https://image.wmsm.co/a80749b800d2cecffada73c87b236635/city-of-paris-fine-art-museum-1.jpg?quality=80&width=1280',
    ),
  ];

  @override
  Widget build(BuildContext context) {
    return Center(
      child: CarouselSlider.builder(
          itemCount: _museums.length,
          itemBuilder: (BuildContext context, int itemIndex, int pageViewIndex) {
            final details = _museums.elementAt(itemIndex);
            final imageKey = GlobalKey();
            return PinchItemContainer(
              imageWidgetKey: imageKey,
              imageUrl: details.imageUrl,
              child: MuseumDetailsWidgetMuseum(
                museum: details,
                imageKey: imageKey,
              ),
            );
          },
          options: CarouselOptions(
            height: 500,
            aspectRatio: 16 / 9,
            viewportFraction: 0.8,
            initialPage: 0,
            scrollPhysics: PinchScrollLockPhysics.build(context),
            enableInfiniteScroll: true,
            reverse: false,
            autoPlay: false,
            enlargeCenterPage: true,
            enlargeFactor: 0.3,
            scrollDirection: Axis.horizontal,
          )),
    );
  }
}

class MuseumDetailsWidgetMuseum extends StatelessWidget {
  const MuseumDetailsWidgetMuseum({
    Key? key,
    required this.museum,
    required this.imageKey,
  }) : super(key: key);

  final MuseumDetails museum;
  final GlobalKey imageKey;

  @override
  Widget build(BuildContext context) {
    return DecoratedBox(
      decoration: BoxDecoration(
        color: Colors.white,
        borderRadius: BorderRadius.circular(16),
      ),
      child: Padding(
        padding: EdgeInsets.all(16),
        child: Column(
          mainAxisSize: MainAxisSize.min,
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            CachedNetworkImage(
              key: imageKey,
              imageUrl: museum.imageUrl,
            ),
            const SizedBox(height: 8),
            Text(
              museum.title,
              textAlign: TextAlign.start,
              style: Theme.of(context).textTheme.headlineSmall,
            ),
            const SizedBox(height: 8),
            Text(
              museum.details,
              textAlign: TextAlign.start,
            ),
          ],
        ),
      ),
    );
  }
}

这段代码实现了如下的交互效果:

  • 用户可以在水平方向上滑动查看不同的博物馆信息卡片。
  • 每个卡片上的图片支持捏合缩放操作。
  • 在图片放大过程中,列表不会响应滚动事件,确保用户体验良好。

通过以上步骤,您就可以在自己的Flutter项目中集成 pinch_scrollable 插件,为用户提供更加丰富的交互体验。


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

1 回复

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


当然,以下是如何在Flutter项目中使用pinch_scrollable插件来实现捏合缩放和滚动的代码示例。pinch_scrollable插件允许你创建一个可以捏合缩放和滚动的Widget。

首先,确保你的pubspec.yaml文件中已经添加了pinch_scrollable依赖:

dependencies:
  flutter:
    sdk: flutter
  pinch_scrollable: ^0.1.0  # 请检查最新版本号

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

接下来,在你的Dart文件中,你可以按照以下示例来使用PinchScrollable

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

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

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

class PinchScrollableDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Pinch Scrollable Demo'),
      ),
      body: Center(
        child: PinchScrollable(
          // 子Widget,可以是你希望缩放和滚动的任何内容
          child: Container(
            color: Colors.grey[200],
            width: 500,
            height: 500,
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              crossAxisAlignment: CrossAxisAlignment.center,
              children: <Widget>[
                Text(
                  'Pinch to zoom and scroll',
                  style: TextStyle(fontSize: 24),
                ),
                SizedBox(height: 20),
                Image.network(
                  'https://via.placeholder.com/400',
                  fit: BoxFit.cover,
                ),
              ],
            ),
          ),
          // 可选参数:设置初始缩放比例
          initialScale: 1.0,
          // 可选参数:设置最小缩放比例
          minScale: 0.5,
          // 可选参数:设置最大缩放比例
          maxScale: 3.0,
          // 可选参数:设置缩放动画的持续时间
          scaleAnimationDuration: Duration(milliseconds: 200),
        ),
      ),
    );
  }
}

解释

  1. 依赖引入:在pubspec.yaml中添加pinch_scrollable依赖。
  2. 示例应用:创建了一个简单的Flutter应用,包含一个PinchScrollable Widget。
  3. PinchScrollable
    • child:这是你想要缩放和滚动的Widget,可以是任何Widget,例如图片、文本或其他复杂的布局。
    • initialScale:初始缩放比例,默认为1.0(即不缩放)。
    • minScale:最小缩放比例,防止用户过度缩小。
    • maxScale:最大缩放比例,防止用户过度放大。
    • scaleAnimationDuration:缩放动画的持续时间。

这段代码展示了如何在Flutter应用中使用pinch_scrollable插件来实现捏合缩放和滚动功能。你可以根据需要调整参数和子Widget来实现更复杂的UI效果。

回到顶部