flutter中背景图片(动态图片)

发布时间 2023-12-25 14:59:32作者: 鲤斌

单页面设置背景图片

使用 Container 组件和 decoration 属性:

优点:简单易用,适用于大多数情况下的页面背景设置。

缺点:无法控制背景图片的位置和层级。

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

  @override
  Widget build(BuildContext context) {
    return Container(
      width: MediaQuery.of(context).size.width, // 指定图片的宽度
      height: MediaQuery.of(context).size.height,
      decoration: const BoxDecoration(
        image: DecorationImage(
          // image: AssetImage('images/backbode/back1.png'), //静态
           image: AssetImage('images/backbode/gif/game_back3.webp'), //动态
          fit: BoxFit.cover,
        ),
      ),
      child: const Text("我的书籍"),
    );
  }
}
使用 Stack 组件将背景图片放在页面最底层:

优点:可以将背景图片置于页面最底层,不会被其他组件遮挡。

缺点:需要使用 Positioned.fill 或自定义位置来调整背景图片的尺寸和位置。

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Stack(
        children: [
          Positioned.fill(
            child: Image.asset(
              'images/backbode/gif/game_back3.webp',
              fit: BoxFit.cover,
            ),
          ),
          const Align(//必须加背景才全屏
              // alignment: Alignment.center,
              child: Text("我的书籍")),
        ],
      ),
    );
  }
}
自定义页面的 Scaffold 组件的 body 属性,并设置 Container 组件作为背景:

优点:直接在页面的 Scaffold 中设置背景图片,方便管理页面布局。

缺点:在较复杂的页面布局中可能需要调整 Stack 的层级。

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        width: double.infinity,
        height: double.infinity,
        decoration: const BoxDecoration(
          image: DecorationImage(
            image: AssetImage('images/backbode/gif/game_back3.webp'),
            fit: BoxFit.cover,
          ),
        ),
        child: const Text("我的书籍"),
      ),
    );
  }
}

全局设置背景图片

使用Flutter中的Stack小部件实现了全局背景图片的效果:

优点:灵活性高:通过使用Stack小部件,您可以将背景图片放置在整个屏幕下面,并在其上方叠加其他小部件。这样,您可以更自由地控制页面的布局和结构。可扩展性强:由于背景图片是作为Stack的一部分添加的,所以您可以随时添加更多的小部件到Stack中,来增强页面的功能和交互。

缺点:性能影响:由于背景图片会覆盖整个屏幕,所以对于较大分辨率的屏幕或包含大量小部件的页面,图片加载和布局可能会影响性能。在这种情况下,建议对图片进行优化,避免使用过大的图片以及尽可能减少布局计算等操作。需要额外的布局层级:由于需要使用Stack来放置背景图片和其他小部件,这意味着页面会增加一个额外的布局层级。对于简单页面来说,这可能不是一个问题,但对于复杂的页面结构,可能需要更多的布局层级来实现所需的效果。

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

  @override
  Widget build(BuildContext context) {
    // 禁用状态栏和导航栏
    SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: []);

    // 强制横屏
    SystemChrome.setPreferredOrientations(
        [DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight]);

    return MaterialApp(
        debugShowCheckedModeBanner: false, //去除debug图标
        home: Scaffold(
          body: Stack(
            children: [
              Container(
                decoration: const BoxDecoration(
                  image: DecorationImage(
                    // image: AssetImage('images/backbode/back1.png'), // 全局设置背景图片
                    image: AssetImage(
                        'images/backbode/gif/game_back3.webp'), // 全局设置动态背景图片
                    fit: BoxFit.cover,
                  ),
                ),
              ),
              // 在这里添加其他小部件
              MyHome()
            ],
          ),
        ));
  }
}
使用 MaterialApp 组件的 builder 属性和 Navigator 的 Observer 在路由跳转时统一设置背景图片:

优点:可以实现在路由跳转时统一设置背景图片,适用于需要动态更改背景图片的场景。

缺点:需要实现自定义的路由管理器,相对复杂。

 

 

BoxFit的不同值以及它们的用法说明

  • BoxFit.contain: 图像将等比例缩放以适应容器的尺寸,同时保持图像的完整性。这意味着图像可能会在容器内留有空白区域,图像的某些部分可能不会完全显示。
  • BoxFit.cover: 图像将等比例缩放以填充整个容器的尺寸,然后将超出部分裁剪掉。这意味着图像可能会在容器中进行裁剪,以适应容器的尺寸。
  • BoxFit.fill: 图像将拉伸和变形以填充整个容器的尺寸。这意味着图像可能会拉伸或压缩,以适应容器的尺寸,导致图像可能失真。
  • BoxFit.fitHeight: 图像将等比例缩放以在垂直方向上填充整个容器的高度,然后根据原始图像的宽高比来调整宽度。这意味着图像可能会在容器中进行裁剪,以适应容器的尺寸。
  • BoxFit.fitWidth: 图像将等比例缩放以在水平方向上填充整个容器的宽度,然后根据原始图像的宽高比来调整高度。这意味着图像可能会在容器中进行裁剪,以适应容器的尺寸。
  • BoxFit.none: 图像将不进行缩放,而是根据容器的尺寸进行定位显示。如果图像的尺寸大于容器的尺寸,图像可能会被裁剪掉。
  • BoxFit.scaleDown: 图像将等比例缩放以适应容器的尺寸,但只有在图像的大小大于容器的尺寸时才会缩放。如果图像的大小小于或等于容器的大小,图像将被原样显示。