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

Flutter:软键盘弹出时如何实现屏幕可滚动?

解决Flutter TextField弹出键盘时屏幕无法滚动的问题

你的代码里有两个核心问题导致滚动失效:

  • Scaffold的resizeToAvoidBottomInset被设为false,这会阻止Scaffold调整布局以避开软键盘,滚动视图自然无法响应键盘弹出事件。
  • 外层Column未设置自适应高度,可能导致SingleChildScrollView无法正确计算滚动范围。

修改方案:

  1. 移除或修改Scaffold的resizeToAvoidBottomInset属性,将其设为true(默认值,也可直接删除该属性)。
  2. 给外层Column添加mainAxisSize: MainAxisSize.min,让它根据子组件高度自适应,确保SingleChildScrollView能正常滚动。

修改后的完整代码:

import 'dart:io';
import 'package:flutter/material.dart';
import 'package:graffiti_app3/controller/controllerlistview.dart';

import 'package:graffiti_app3/view/screens/homepage/homepage.dart';

import '../../../model/modellistview.dart';
import '../homepage/dummyhomepage.dart';

class MyPostPage extends StatefulWidget {
  final File? image;

  MyPostPage({required this.image, Key? key}) : super(key: key);

  @override
  State<MyPostPage> createState() => _MyPostPageState();
}

class _MyPostPageState extends State<MyPostPage> {
  File? image;
  final myController = TextEditingController();

  @override
  void dispose() {
    myController.dispose();
    super.dispose();
  }

  void callAddCard() {
    MyDummyHomePageState? myWidgetState =
        context.findAncestorStateOfType<MyDummyHomePageState>();
    myWidgetState?.addCard();
  }

  @override
  void initState() {
    super.initState();
    image = widget.image!;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      // 关键修改:恢复默认的true值,或直接删除该行
      resizeToAvoidBottomInset: true,
      appBar: AppBar(
          automaticallyImplyLeading: false,
          elevation: 0,
          backgroundColor: Colors.white,
          title: Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: [
              Padding(
                padding: const EdgeInsets.only(left: 15.0),
                child: Text(
                  '<  Add more details',
                  style: TextStyle(
                      color: Colors.blue.shade800,
                      fontWeight: FontWeight.normal),
                ),
              ),
              IconButton(
                icon: const Icon(
                  Icons.close,
                  color: Colors.black,
                ),
                onPressed: () {
                  Navigator.push(
                    context,
                    MaterialPageRoute(
                      builder: (context) => MyHomePage(),
                    ),
                  );
                },
              ),
            ],
          )),
      body: SingleChildScrollView(
        child: Center(
          // 关键修改:让Column自适应内容高度
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              Container(
                decoration: BoxDecoration(
                  boxShadow: [
                    BoxShadow(
                        color: Colors.grey.withOpacity(0.2),
                        blurRadius: 7,
                        spreadRadius: 5,
                        offset: const Offset(0, 3)),
                  ],
                  borderRadius: BorderRadius.circular(10),
                  color: Colors.white,
                ),
                margin: const EdgeInsets.all(10),
                width: 360,
                height: 550,
                child: Column(
                  children: [
                    Padding(
                      padding: const EdgeInsets.only(left: 10, top: 10),
                      child: Row(
                        children: [
                          const CircleAvatar(
                            backgroundImage:
                                AssetImage('assets/images/userprofile.png'),
                            radius: 20,
                          ),
                          const SizedBox(
                            width: 5,
                          ),
                          Column(
                            crossAxisAlignment: CrossAxisAlignment.start,
                            children: [
                              const Text(
                                "Maddy Perez",
                                style: TextStyle(
                                  color: Colors.black,
                                ),
                              ),
                              Text(
                                "Choose location",
                                style: TextStyle(
                                  color: Colors.blue.shade800,
                                  fontWeight: FontWeight.bold,
                                ),
                              )
                            ],
                          )
                        ],
                      ),
                    ),
                    const SizedBox(
                      height: 10,
                    ),
                    ClipRRect(
                      borderRadius: BorderRadius.circular(8.0),
                      child: Image.file(
                        image!,
                        width: 330,
                        height: 330,
                        fit: BoxFit.cover,
                      ),
                    ),
                    const SizedBox(
                      height: 20,
                    ),
                    SizedBox(
                      width: 340,
                      height: 120,
                      child: TextField(
                        autofocus: true,
                        controller: myController,
                        style: TextStyle(color: Colors.black),
                        maxLines: null,
                        expands: true,
                        keyboardType: TextInputType.multiline,
                        decoration: const InputDecoration(
                            filled: true, hintText: 'Enter a message'),
                      ),
                    ),
                  ],
                ),
              ),
              const SizedBox(
                height: 20,
              ),
              Row(
                mainAxisAlignment: MainAxisAlignment.center,
                crossAxisAlignment: CrossAxisAlignment.center,
                children: [
                  OutlinedButton(
                    onPressed: () {},
                    style: OutlinedButton.styleFrom(
                        side:
                            BorderSide(width: 1, color: Colors.pink.shade800)),
                    child: Text(
                      "Save as draft",
                      style: TextStyle(
                          color: Colors.pink.shade800,
                          fontWeight: FontWeight.normal),
                    ),
                  ),
                  const SizedBox(
                    width: 10,
                  ),
                  ElevatedButton(
                    onPressed: () {
                      Graffiti graffiti = Graffiti(
                        author: 'Alice Smith',
                        location: 'Miami',
                        image: image!,
                        description: myController,
                      );
                      GraffitiController graffitiController =
                          GraffitiController();
                      graffitiController.addGraffiti(graffiti);
                      Navigator.push(
                        context,
                        MaterialPageRoute(
                          builder: (context) => MyHomePage(),
                        ),
                      );
                    },
                    style: ElevatedButton.styleFrom(
                      backgroundColor: Colors.pink.shade800,
                    ),
                    child: const Text(
                      "POST NOW",
                      style: TextStyle(fontWeight: FontWeight.bold),
                    ),
                  )
                ],
              ),
            ],
          ),
        ),
      ),
    );
  }
}

额外说明:

如果修改后仍存在滚动问题,可以检查:

  • 是否有其他固定高度的父组件限制了滚动范围
  • 可给SingleChildScrollView添加padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),确保内容不会被键盘完全遮挡

内容的提问来源于stack exchange,提问作者Mark John

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 10:42:48