Flutter,如何实现轮播图

0 阅读3分钟

说到这个 Flutter 项目配置,我发现 flutter_swiper_view 这个库用起来还挺顺手的。最近在做一个首页轮播图的功能,记录一下实现过程。

对了,先说说项目的基本配置吧。在 pubspec.yaml 里除了基础依赖,主要加了三个关键库:

  • flutter_swiper_view 负责轮播图
  • oktoast 用于提示消息
  • flutter_screenutil 做屏幕适配

关于 flutter_screenutil 的详细说明,flutter_screenutil 这个库真的太重要了!它帮我们解决了不同设备屏幕适配的大问题。说到屏幕适配,Android 和 iOS 设备那么多不同尺寸,要是手动适配简直要疯掉。

这个库主要提供了几个超好用的功能:

  1. .w - 宽度适配单位
  2. .h - 高度适配单位
  3. .r - 圆角/边距适配单位
  4. .sp - 字体大小适配单位

初始化的时候需要设置 designSize,这个要根据 UI 设计稿的尺寸来定。比如设计稿是 375x812(iPhone X 尺寸),那就这样设置:

主应用入口设置

主应用入口的代码挺有意思的。我注意到这里用 OKToast 包裹了整个应用,这样在任何地方都可以调用 toast 提示了。ScreenUtilInit 则是用来初始化屏幕适配的,designSize 需要提前定义好设计稿尺寸。

return OKToast(
  child: ScreenUtilInit(
    designSize: designSize,
    builder: (context, child) {
      return MaterialApp(
        title: 'Flutter Demo',
        theme: ThemeData(
          colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
          useMaterial3: true
        ),
        home: HomePage()
      );
    },
  )
);
void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ScreenUtilInit(
      designSize: Size(375, 812),
      minTextAdapt: true,
      splitScreenMode: true,
      builder: (context, child) {
        return MaterialApp(
          title: 'Flutter Demo',
          theme: ThemeData(),
          home: child,
        );
      },
      child: HomePage(),
    );
  }
}

使用起来特别简单,比如:

Container(
  width: 100.w,  // 相当于设计稿上的100px
  height: 200.h, // 相当于设计稿上的200px
  margin: EdgeInsets.all(10.r), // 圆角适配
  child: Text(
    'Hello', 
    style: TextStyle(fontSize: 16.sp) // 字体大小适配
  ),
)

首页轮播图实现

说到轮播图,在 HomePage 里我用 Swiper 组件实现了一个简单的版本。这里有几个关键点:

  1. 容器高度设为了 150.h - 这个 .hScreenUtil 提供的适配单位
  2. 宽度设为 double.infinity 让它撑满父容器
  3. 加了 15.r 的边距 - .r 也是适配单位
Container(
  height: 150.h,
  width: double.infinity,
  child: Swiper(
    indicatorLayout: PageIndicatorLayout.COLOR,
    autoplay: true,
    control: const SwiperControl(),
    itemCount: 3,
    itemBuilder: (context, index){
      return Container(
        width: double.infinity,
        margin: EdgeInsets.all(15.r),
        height: 150.h,
        color: Colors.lightBlue
      );
    }
  )
)

对了,Swiper 的配置项也挺丰富的:

  • autoplay: true 开启自动轮播
  • control 显示左右箭头控制器
  • indicatorLayout 设置指示器样式

遇到的坑

还有一个有意思的事,刚开始我没用 SafeArea,结果在 iPhone 上轮播图被刘海挡住了。后来加上了 SafeArea 才解决这个问题。所以现在代码是这样的:

Scaffold(
  body: SafeArea(child: Column(children: [
    // 轮播图和其他内容
  ]))
)

说到这个,Flutter 的布局系统有时候确实需要点时间适应,特别是从原生开发转过来的同学。不过一旦熟悉了,写起来还是挺爽的!

效果

1.gif

总结

总的来说,实现一个基础轮播图并不复杂,但要注意:

  • 屏幕适配问题
  • 不同设备的显示安全区域
  • 轮播图的各种配置选项

下次我打算给轮播图加上真实的图片和点击事件,到时候再分享更多心得!