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

Flutter如何隐藏键盘下FloatingActionButton且不遮挡TextFormField并解决焦点问题

解决方案

问题1:仅隐藏键盘弹出时的FloatingActionButton,同时保证TextFormField不被遮挡

  • 首先删掉Scaffold上的resizeToAvoidBottomInset: false配置,保留默认的true状态,此时页面会在键盘弹出时自动上移,输入框不会被遮挡
  • 然后通过MediaQuery.of(context).viewInsets.bottom判断键盘是否弹出,动态控制FAB的显示/隐藏:键盘弹出(该值大于0)时隐藏FAB,键盘收起时显示FAB

问题2:TextFormField每次仅聚焦第一个输入框

  • 该问题是因为动态生成的Card和输入框没有配置唯一的Key,Flutter在重绘widget树时无法正确区分不同输入框的状态,导致聚焦错位。只需要给每个动态生成的Card、以及每个TextFormField添加对应index的唯一Key即可解决。

完整修改后代码

import 'package:flutter/material.dart';

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

class App extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: CardWithTextformfield(),
    );
  }
}

class CardWithTextformfield extends StatefulWidget {
  const CardWithTextformfield({Key? key}) : super(key: key);

  @override
  _CardWithTextformfieldState createState() => _CardWithTextformfieldState();
}

class _CardWithTextformfieldState extends State<CardWithTextformfield>  {

  var name =<TextEditingController>[];
  var id =<TextEditingController>[];

  var addCard =1;  
  bool cardOneVisibility=true;
  bool cardTwoVisibility=false;
  bool cardThreeVisibility=false;
  bool cardFourVisibility=false;
  bool cardFiveVisibility=false;
  bool cardSixVisibility=false;

  void incrementcard(){
    setState(() {
      
      if(addCard==0){   
        cardOneVisibility=true;
      }
      else if(addCard==1){ 
        cardOneVisibility=true;
        cardTwoVisibility=true;
      }
      else if(addCard==2){ 
        cardOneVisibility=true;
        cardTwoVisibility=true;
        cardThreeVisibility=true;
      }
      else if(addCard==3){  
        cardOneVisibility=true;
        cardTwoVisibility=true;
        cardThreeVisibility=true;
        cardFourVisibility=true;
      }
      else if(addCard==4){  
        cardOneVisibility=true;
        cardTwoVisibility=true;
        cardThreeVisibility=true;
        cardFourVisibility=true;
        cardFiveVisibility=true;
      }
      else if(addCard==5){  
        cardOneVisibility=true;
        cardTwoVisibility=true;
        cardThreeVisibility=true;
        cardFourVisibility=true;
        cardFiveVisibility=true;
        cardSixVisibility=true;
      }
      addCard++;
    });
  }

  @override
  Widget build(BuildContext context) {
    // 判断键盘是否弹出
    bool isKeyboardShow = MediaQuery.of(context).viewInsets.bottom > 0;
    return Scaffold(
      // 已删除resizeToAvoidBottomInset: false配置,保留默认值
      appBar: AppBar(
        title: Text('Card with TextformField'),
      ),
      // 动态控制FAB显示隐藏
      floatingActionButton: isKeyboardShow ? SizedBox.shrink() : FloatingActionButton(
        onPressed: addCard>=6 ? null : incrementcard, 
        child: Icon(Icons.add),
      ),
      body: Container(
        child:SingleChildScrollView(
          child: Column(
            children: [
              Visibility(visible: cardOneVisibility,child: cardslist(0)),
              Visibility(visible: cardTwoVisibility,child: cardslist(1)),
              Visibility(visible: cardThreeVisibility,child: cardslist(2)),
              Visibility(visible: cardFourVisibility,child: cardslist(3)),
              Visibility(visible: cardFiveVisibility,child: cardslist(4)),
              Visibility(visible: cardSixVisibility,child: cardslist(5)),
            ],
          ),
        ),
      ),
    );
  }
  Widget cardslist(int index){
    if(name.length <= index){
      name.add(TextEditingController());
      id.add(TextEditingController());
    }
    return Card(
      // 给Card添加唯一Key
      key: Key('card_$index'),
      margin: EdgeInsets.all(10),
      child: Container(
        child: Column(
          children: [
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                Container(
                    margin: EdgeInsets.all(10),
                    child: Text('Team Name: ')),
                Expanded(child: TextFormField(
                  // 给名称输入框添加唯一Key
                  key: Key('name_input_$index'),
                  controller: name[index],
                  decoration: InputDecoration(hintText: 'Team Name'),
                ),),
                Container(
                  margin: EdgeInsets.all(10),
                  child: Text('Team Id: '),),
                Expanded(child: TextFormField(
                  // 给ID输入框添加唯一Key
                  key: Key('id_input_$index'),
                  controller: id[index],
                  decoration: InputDecoration(hintText: 'Team Id'),
                ),),
              ],
            ),
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                GestureDetector(
                  child: Container(
                    width: 50,height: 50,
                    margin: EdgeInsets.all(10),
                    decoration: BoxDecoration(
                      shape: BoxShape.rectangle,
                      color:Colors.grey,
                    ),
                    child: Center(child: Text('IT'),),
                  ),
                ),
                GestureDetector(
                  child: Container(
                    width: 50,height: 50,
                    margin: EdgeInsets.all(10),
                    decoration: BoxDecoration(
                      shape: BoxShape.rectangle,
                      color: Colors.grey,
                    ),
                    child: Center(child: Text('DEV'),),
                  ),
                ),
                GestureDetector(
                  child: Container(
                    width: 50,height: 50,
                    margin: EdgeInsets.all(10),
                    decoration: BoxDecoration(
                      shape: BoxShape.rectangle,
                      color: Colors.grey,
                    ),
                    child: Center(child: Text('TEST'),),
                  ),
                ),
                GestureDetector(
                  child: Container(
                    width: 50,height: 50,
                    margin: EdgeInsets.all(10),
                    decoration: BoxDecoration(
                      shape: BoxShape.rectangle,
                      color: Colors.grey,
                    ),
                    child: Center(child: Text('HR'),),
                  ),
                ),
              ],
            )
          ],
        ),
      ),
    );
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 21:45:03