You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter开发:如何用Stack将背景图定位至屏幕底部

Flutter背景图底部定位解决方案

你当前的背景图全屏拉伸问题,是因为用了占满全屏的SizedBox包裹图片,且未设置定位规则。只需调整Stack中背景图的布局方式,就能实现将背景图固定在屏幕底部的效果:

修改步骤:

  1. 替换原来全屏的SizedBox为Align组件,通过alignment: Alignment.bottomCenter将图片定位到屏幕底部
  2. 给Image设置合适的fit属性,避免图片被强制拉伸(根据素材选择BoxFit.contain保持原图比例,或BoxFit.fitWidth让宽度适配屏幕)

修改后的背景图代码片段:

Align(
  alignment: Alignment.bottomCenter,
  child: Image(
    image: AssetImage('assets/background.png'),
    fit: BoxFit.contain, // 保持图片原有尺寸,不拉伸变形
  ),
),

完整的build方法修改后:

@override
Widget build(BuildContext context) {
  return Scaffold(
    body: Stack(
      fit: StackFit.expand,
      children: <Widget>[
        // 替换此处的背景图布局
        Align(
          alignment: Alignment.bottomCenter,
          child: Image(
            image: AssetImage('assets/background.png'),
            fit: BoxFit.contain,
          ),
        ),
        CustomScrollView(
          // 原有CustomScrollView内容保持不变
          slivers: <Widget>[
            SliverAppBar(
              pinned: true,
              flexibleSpace: Container(
                decoration: const BoxDecoration(
                  gradient: LinearGradient(
                    colors: [
                      AuditTheme.primaryColor,
                      AuditTheme.secondaryColor,
                    ],
                  ),
                ),
              ),
              leadingWidth: 100,
              leading: Padding(
                padding: const EdgeInsets.fromLTRB(10, 0, 0, 0),
                child: Row(
                  children: const [
                    Expanded(
                      child: ImageIcon(
                        AssetImage('assets/logo/white_logo.png'),
                      ),
                    ),
                    Text(
                      'Audit',
                      style: TextStyle(fontSize: 20),
                    ),
                  ],
                ),
              ),
              title: const Text('Sign In'),
              centerTitle: true,
              actions: [
                Transform(
                  alignment: Alignment.center,
                  transform: Matrix4.rotationY(math.pi),
                  child: IconButton(
                    onPressed: () {},
                    icon: const Icon(Icons.sort),
                  ),
                ),
              ],
            ),
            SliverList(
              delegate: SliverChildListDelegate(
                [
                  Column(
                    mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                    crossAxisAlignment: CrossAxisAlignment.center,
                    children: [
                      Widgets().sixedBoxHeight(50),
                      Column(
                        children: [
                          const CircleAvatar(
                            radius: 35,
                            backgroundImage:
                                AssetImage('assets/logo/audit_logo.png'),
                          ),
                          Widgets().sixedBoxHeight(10),
                          const Text(
                            'Ledjoric Vermont',
                            style: TextStyle(fontSize: 20),
                          ),
                        ],
                      ),
                      Row(
                        mainAxisAlignment: MainAxisAlignment.center,
                        children: [
                          pinIconTest(inputPass.isNotEmpty
                              ? Colors.black
                              : Colors.grey),
                          pinIconTest(inputPass.length >= 2
                              ? Colors.black
                              : Colors.grey),
                          pinIconTest(inputPass.length >= 3
                              ? Colors.black
                              : Colors.grey),
                          pinIconTest(inputPass.length == 4
                              ? Colors.black
                              : Colors.grey),
                        ],
                      ),
                      Card(
                        child: Column(
                          children: [
                            Row(
                              mainAxisSize: MainAxisSize.min,
                              mainAxisAlignment: MainAxisAlignment.center,
                              children: [
                                numPad(const Text('1'), () => inputPin('1')),
                                numPad(const Text('2'), () => inputPin('2')),
                                numPad(const Text('3'), () => inputPin('3')),
                              ],
                            ),
                            Row(
                              mainAxisSize: MainAxisSize.min,
                              mainAxisAlignment: MainAxisAlignment.center,
                              children: [
                                numPad(const Text('4'), () => inputPin('4')),
                                numPad(const Text('5'), () => inputPin('5')),
                                numPad(const Text('6'), () => inputPin('6')),
                              ],
                            ),
                            Row(
                              mainAxisSize: MainAxisSize.min,
                              mainAxisAlignment: MainAxisAlignment.center,
                              children: [
                                numPad(const Text('7'), () => inputPin('7')),
                                numPad(const Text('8'), () => inputPin('8')),
                                numPad(const Text('9'), () => inputPin('9')),
                              ],
                            ),
                            Row(
                              mainAxisSize: MainAxisSize.min,
                              mainAxisAlignment: MainAxisAlignment.end,
                              children: [
                                const SizedBox(
                                  width: 100,
                                  height: 100,
                                ),
                                numPad(const Text('0'), () => inputPin('0')),
                                numPad(
                                  const Icon(Icons.backspace_sharp),
                                  () => deletePin(),
                                ),
                              ],
                            ),
                          ],
                        ),
                      ),
                    ],
                  ),
                ],
              ),
            ),
          ],
        ),
      ],
    ),
  );
}

这样修改后,背景图会自动对齐屏幕底部,同时保留自身尺寸比例,完全符合预期效果。

内容的提问来源于stack exchange,提问作者Ledjoric Libiran

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 02:36:31