Flutter滑动操作插件flutter_swipe的使用

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

Flutter滑动操作插件flutter_swipe的使用

简介

flutter_swipe 是一个功能强大的Flutter滑动组件库,支持多种布局和无限循环。它兼容Android和iOS平台,并且提供了丰富的自定义选项,如分页、控制按钮、自动播放等。

新特性

  • 分页布局:现在使用 flutter_page_indicator 项目来实现分页效果。
  • 页面转换器(PageTransformer):类似于Android的页面转换器,可以通过设置 transformer 来实现自定义的页面转换效果。目前仅支持 DEFAULT 布局。
  • 多种布局:提供了多种内置布局,如默认布局、堆叠布局(STACK)、Tinder风格布局等。

展示

Horizontal Vertical Custom Pagination Custom Pagination Phone Example

入门指南

安装

pubspec.yaml 文件中添加依赖:

dependencies:
  flutter_swipe: ^latest_version

然后在项目根目录下运行以下命令:

flutter packages get
基本用法

创建一个新的Flutter项目并编辑 lib/main.dart 文件:

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

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

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key? key, this.title}) : super(key: key);

  final String? title;

  [@override](/user/override)
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title ?? ''),
      ),
      body: Swiper(
        itemBuilder: (BuildContext context, int index) {
          return Image.network("http://via.placeholder.com/350x150", fit: BoxFit.fill);
        },
        itemCount: 3,
        pagination: SwiperPagination(),
        control: SwiperControl(),
      ),
    );
  }
}
构造函数参数
参数 默认值 描述
scrollDirection Axis.horizontal 如果为 Axis.horizontal,则子组件水平排列;否则垂直排列。
loop true 设置为 false 以禁用无限循环模式。
index 0 初始滑动项的索引。
autoplay false 设置为 true 以启用自动播放模式。
onIndexChanged void onIndexChanged(int index) 当用户滑动或自动播放时调用,传入新的索引。
onTap void onTap(int index) 当用户点击UI时调用。
duration 300.0 每次动画持续的时间(毫秒)。
pagination null 设置 new SwiperPagination() 以显示默认分页。
control null 设置 new SwiperControl() 以显示默认控制按钮。
分页

分页继承自 SwiperPlugin,提供额外的UI元素。设置 new SwiperPagination() 以显示默认分页。

参数 默认值 描述
alignment Alignment.bottomCenter 改变此值可以将分页放置在其他位置。
margin const EdgeInsets.all(10.0) 内边距,控制分页与父容器内侧的距离。
builder SwiperPagination.dots 两种默认样式:SwiperPagination.dotsSwiperPagination.fraction,均可自定义。
控制按钮

控制按钮也继承自 SwiperPlugin,设置 new SwiperControl() 以显示默认控制按钮。

参数 默认值 描述
iconPrevious Icons.arrow_back_ios 显示“上一页”按钮的图标。
iconNext Icons.arrow_forward_ios 显示“下一页”按钮的图标。
color Theme.of(context).primaryColor 控制按钮的颜色。
size 30.0 控制按钮的大小。
padding const EdgeInsets.all(5.0) 控制按钮的内边距。
控制器

控制器用于控制 Swiper 的索引、启动或停止自动播放。可以通过 new SwiperController() 创建控制器实例。

方法 描述
void move(int index, {bool animation: true}) 移动到指定索引,是否带有动画。
void next({bool animation: true}) 移动到下一项。
void previous({bool animation: true}) 移动到上一项。
void startAutoplay() 启动自动播放。
void stopAutoplay() 停止自动播放。
自动播放
参数 默认值 描述
autoplayDelay 3000 自动播放延迟时间(毫秒)。
autoplayDisableOnInteraction true 如果设置为 true,当用户滑动时禁用自动播放。

内置布局

以下是几种内置布局的示例:

  1. 默认布局

    new Swiper(
      itemBuilder: (BuildContext context, int index) {
        return new Image.network(
          "http://via.placeholder.com/288x188",
          fit: BoxFit.fill,
        );
      },
      itemCount: 10,
      viewportFraction: 0.8,
      scale: 0.9,
    )
    
  2. 堆叠布局(STACK)

    new Swiper(
      itemBuilder: (BuildContext context, int index) {
        return new Image.network(
          "http://via.placeholder.com/288x188",
          fit: BoxFit.fill,
        );
      },
      itemCount: 10,
      itemWidth: 300.0,
      layout: SwiperLayout.STACK,
    )
    
  3. Tinder风格布局

    new Swiper(
      itemBuilder: (BuildContext context, int index) {
        return new Image.network(
          "http://via.placeholder.com/288x188",
          fit: BoxFit.fill,
        );
      },
      itemCount: 10,
      itemWidth: 300.0,
      itemHeight: 400.0,
      layout: SwiperLayout.TINDER,
    )
    
  4. 自定义布局

    new Swiper(
      layout: SwiperLayout.CUSTOM,
      customLayoutOption: new CustomLayoutOption(
        startIndex: -1,
        stateCount: 3
      ).addRotate([
        -45.0 / 180,
        0.0,
        45.0 / 180
      ]).addTranslate([
        new Offset(-370.0, -40.0),
        new Offset(0.0, 0.0),
        new Offset(370.0, -40.0)
      ]),
      itemWidth: 300.0,
      itemHeight: 200.0,
      itemBuilder: (context, index) {
        return new Container(
          color: Colors.grey,
          child: new Center(
            child: new Text("$index"),
          ),
        );
      },
      itemCount: 10
    )
    

示例代码

以下是一个完整的示例代码,展示了如何使用 flutter_swipe 实现一个包含多种布局和功能的滑动组件。

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

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

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Swiper Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Swiper Demo'),
      routes: {
        '/example01': (BuildContext context) => ExampleHorizontal(),
        '/example02': (BuildContext context) => ExampleVertical(),
        '/example03': (BuildContext context) => ExampleFraction(),
        '/example04': (BuildContext context) => ExampleCustomPagination(),
        '/example05': (BuildContext context) => ExamplePhone(),
        '/example06': (BuildContext context) => ScaffoldWidget(
          child: ExampleSwiperInScrollView(), 
          title: "ScrollView"
        ),
        '/example07': (BuildContext context) => ScaffoldWidget(
          child: ExampleCustom(), 
          title: "Custom All"
        )
      },
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key? key, this.title}) : super(key: key);

  final String? title;

  [@override](/user/override)
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  List<Widget> render(BuildContext context, List children) {
    return ListTile.divideTiles(
      context: context,
      tiles: children.map((dynamic data) {
        return buildListTile(context, data[0], data[1], data[2]);
      })
    ).toList();
  }

  Widget buildListTile(BuildContext context, String title, String subtitle, String url) {
    return ListTile(
      onTap: () {
        Navigator.of(context).pushNamed(url);
      },
      isThreeLine: true,
      dense: false,
      leading: null,
      title: Text(title),
      subtitle: Text(subtitle),
      trailing: Icon(Icons.arrow_right, color: Colors.blueAccent),
    );
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title ?? ''),
      ),
      body: ListView(
        children: render(context, [
          ["Horizontal", "Scroll Horizontal", "/example01"],
          ["Vertical", "Scroll Vertical", "/example02"],
          ["Fraction", "Fraction style", "/example03"],
          ["Custom Pagination", "Custom Pagination", "/example04"],
          ["Phone", "Phone view", "/example05"],
          ["ScrollView", "In a ScrollView", "/example06"],
          ["Custom", "Custom all properties", "/example07"]
        ]),
      ),
    );
  }
}

const List<String> titles = [
  "Flutter Swiper is awesome",
  "Really nice",
  "Yeap"
];

class ExampleHorizontal extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Horizontal"),
      ),
      body: Swiper(
        itemBuilder: (BuildContext context, int index) {
          return Image.asset(
            images[index],
            fit: BoxFit.fill,
          );
        },
        autoplay: true,
        autoplayDelay: 1000,
        itemCount: images.length,
        pagination: SwiperPagination(),
        control: SwiperControl(),
        fade: 1.0,
        viewportFraction: 0.85,
      ),
    );
  }
}

class ExampleVertical extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Vertical"),
      ),
      body: Swiper(
        itemBuilder: (BuildContext context, int index) {
          return Image.asset(
            images[index],
            fit: BoxFit.fill,
          );
        },
        autoplay: true,
        itemCount: images.length,
        scrollDirection: Axis.vertical,
        pagination: SwiperPagination(alignment: Alignment.centerRight),
        control: SwiperControl(),
      ),
    );
  }
}

class ExampleFraction extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Fraction"),
      ),
      body: Column(
        children: <Widget>[
          Expanded(
            child: Swiper(
              itemBuilder: (BuildContext context, int index) {
                return Image.asset(
                  images[index],
                  fit: BoxFit.fill,
                );
              },
              autoplay: true,
              itemCount: images.length,
              pagination: SwiperPagination(builder: SwiperPagination.fraction),
              control: SwiperControl(),
            ),
          ),
          Expanded(
            child: Swiper(
              itemBuilder: (BuildContext context, int index) {
                return Image.asset(
                  images[index],
                  fit: BoxFit.fill,
                );
              },
              autoplay: true,
              itemCount: images.length,
              scrollDirection: Axis.vertical,
              pagination: SwiperPagination(
                alignment: Alignment.centerRight,
                builder: SwiperPagination.fraction
              ),
            ),
          )
        ],
      ),
    );
  }
}

class ExampleCustomPagination extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Custom Pagination"),
      ),
      body: Column(
        children: <Widget>[
          Expanded(
            child: Swiper(
              itemBuilder: (BuildContext context, int index) {
                return Image.asset(
                  images[index],
                  fit: BoxFit.fill,
                );
              },
              autoplay: true,
              itemCount: images.length,
              pagination: SwiperPagination(
                margin: EdgeInsets.all(0.0),
                builder: SwiperCustomPagination(
                  builder: (BuildContext context, SwiperPluginConfig config) {
                    return ConstrainedBox(
                      child: Container(
                        color: Colors.white,
                        child: Text(
                          "${titles[config.activeIndex]} ${config.activeIndex + 1}/${config.itemCount}",
                          style: TextStyle(fontSize: 20.0),
                        ),
                      ),
                      constraints: BoxConstraints.expand(height: 50.0),
                    );
                  }
                )
              ),
              control: SwiperControl(),
            ),
          ),
          Expanded(
            child: Swiper(
              itemBuilder: (BuildContext context, int index) {
                return Image.asset(
                  images[index],
                  fit: BoxFit.fill,
                );
              },
              autoplay: true,
              itemCount: images.length,
              pagination: SwiperPagination(
                margin: EdgeInsets.all(0.0),
                builder: SwiperCustomPagination(
                  builder: (BuildContext context, SwiperPluginConfig config) {
                    return ConstrainedBox(
                      child: Row(
                        children: <Widget>[
                          Text(
                            "${titles[config.activeIndex]} ${config.activeIndex + 1}/${config.itemCount}",
                            style: TextStyle(fontSize: 20.0),
                          ),
                          Expanded(
                            child: Align(
                              alignment: Alignment.centerRight,
                              child: DotSwiperPaginationBuilder(
                                color: Colors.black12,
                                activeColor: Colors.black,
                                size: 10.0,
                                activeSize: 20.0
                              ).build(context, config),
                            ),
                          )
                        ],
                      ),
                      constraints: BoxConstraints.expand(height: 50.0),
                    );
                  }
                )
              ),
              control: SwiperControl(color: Colors.redAccent),
            ),
          )
        ],
      ),
    );
  }
}

class ExamplePhone extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Phone"),
      ),
      body: Stack(
        children: <Widget>[
          ConstrainedBox(
            constraints: BoxConstraints.expand(),
            child: Image.asset(
              "images/bg.jpeg",
              fit: BoxFit.fill,
            ),
          ),
          Swiper.children(
            autoplay: true,
            pagination: SwiperPagination(
              margin: EdgeInsets.fromLTRB(0.0, 0.0, 0.0, 30.0),
              builder: DotSwiperPaginationBuilder(
                color: Colors.white30,
                activeColor: Colors.white,
                size: 20.0,
                activeSize: 20.0
              )
            ),
            children: <Widget>[
              Image.asset("images/1.png", fit: BoxFit.contain),
              Image.asset("images/2.png", fit: BoxFit.contain),
              Image.asset("images/3.png", fit: BoxFit.contain)
            ],
          )
        ],
      ),
    );
  }
}

class ScaffoldWidget extends StatelessWidget {
  final Widget? child;
  final String? title;
  final List<Widget>? actions;

  ScaffoldWidget({this.child, this.title, this.actions});

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(title ?? ''),
        actions: actions,
      ),
      body: child,
    );
  }
}

更多关于Flutter滑动操作插件flutter_swipe的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter滑动操作插件flutter_swipe的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个关于如何使用flutter_swipe插件来实现滑动操作的代码示例。flutter_swipe插件允许你在Flutter应用中轻松实现滑动卡片或列表项的功能。

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

dependencies:
  flutter:
    sdk: flutter
  flutter_swipe: ^1.2.0  # 请检查最新版本号

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

接下来,在你的Dart文件中,你可以使用Swipe组件来实现滑动操作。以下是一个简单的示例,展示如何使用Swipe来创建一个可以左右滑动的卡片列表:

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

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

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

class SwipeExample extends StatefulWidget {
  @override
  _SwipeExampleState createState() => _SwipeExampleState();
}

class _SwipeExampleState extends State<SwipeExample> {
  final List<String> cardTexts = [
    'Card 1',
    'Card 2',
    'Card 3',
    'Card 4',
    'Card 5',
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Swipe Example'),
      ),
      body: Swipe(
        scrollDirection: Axis.horizontal,
        key: UniqueKey(),
        children: cardTexts.map((text) {
          return Card(
            child: Center(
              child: Text(
                text,
                style: TextStyle(fontSize: 24),
              ),
            ),
          );
        }).toList(),
        onSwiped: (index) {
          print("Swiped card at index: $index");
        },
      ),
    );
  }
}

在这个示例中,我们做了以下几件事:

  1. 引入依赖:引入了flutter/material.dartflutter_swipe/flutter_swipe.dart
  2. 创建应用:定义了一个简单的Flutter应用,其中包含一个主页面SwipeExample
  3. 定义数据:在_SwipeExampleState中定义了一个字符串列表cardTexts,作为卡片的文本内容。
  4. 构建UI:在build方法中,使用ScaffoldAppBar创建了一个基本的页面结构。主体部分使用Swipe组件,将卡片列表作为子组件传递。
  5. 处理滑动事件:通过onSwiped回调,打印出被滑动的卡片的索引。

这个示例展示了如何使用flutter_swipe插件创建一个基本的水平滑动卡片列表。你可以根据需要自定义卡片的内容和样式,或者处理更多的滑动事件(如左滑、右滑等)。

回到顶部