首页 > 解决方案 > Flutter - 我的键盘突然弹出,不知从何而来,什么时候不应该?

问题描述

我的应用程序有问题...

我有一个游戏应用程序需要在应用程序的开头实现玩家。因此,在名为 PlayerSelectionPage 的第一个页面中,您可以将玩家添加到游戏中。然后你可以选择一种游戏模式。无论如何,当我进入设置并切换游戏的语言时,我的键盘无缘无故弹出......我认为这与我的 PlayerPageSelection 以及它与提供程序重建所有以更改语言的事实有关。

这是一个例子:

在此处输入图像描述

这是我的 SettingsPage 代码:

class SettingsPage extends StatelessWidget {
  String _status = '';
  ScrollController _controller = ScrollController();

  @override
  Widget build(BuildContext context) {
    double index = Provider.of<SettingsProvider>(context).getDrinkIntensity();
    if (index == 0) {_status = AppLocalizations.of(context).translate('settings_page_status_1');}
    else if (index == 1) {_status = AppLocalizations.of(context).translate('settings_page_status_2');}
    else if (index == 2) {_status = AppLocalizations.of(context).translate('settings_page_status_3');}
    return Scaffold(
      appBar: AppBar(
        title: Text(AppLocalizations.of(context).translate('settings_page_title')),
        centerTitle: true,
        actions: <Widget>[
          IconButton(
            icon: Icon(Icons.assessment),
            onPressed: () {
              HapticFeedback.mediumImpact();
              Navigator.push(context, MaterialPageRoute(builder: (context) => StatsPage(), settings: RouteSettings(name: 'Stats page')));
            },
            tooltip: AppLocalizations.of(context).translate('settings_page_stat_hint'),
            iconSize: 25,
          )
        ],
      ),
      body: ListView(
        controller: _controller,
        children: [
          SizedBox(height: 10,),
          Center(child: Text(AppLocalizations.of(context).translate('settings_page_drink_text'), style: Theme.of(context).textTheme.subtitle2)),
          Center(child: Text(_status, style: Theme.of(context).textTheme.subtitle2.copyWith(fontSize: 10))),
          Slider(
            value: Provider.of<SettingsProvider>(context).getDrinkIntensity()/2,
            onChanged: (val) {
              HapticFeedback.mediumImpact();
              Provider.of<SettingsProvider>(context, listen: false).setDrinkIntensity(val);
            },
            divisions: 2,
            label: _status,
          ),
          Divider(height: 20),
          Text(AppLocalizations.of(context).translate('settings_page_lang_title'), style: Theme.of(context).textTheme.subtitle2, textAlign: TextAlign.center,),
          LangSelection(langCode: 'fr',),
          LangSelection(langCode: 'en', isBeta: true,),
          LangSelection(langCode: 'de', isEnabled: false,),
          LangSelection(langCode: 'es', isEnabled: false,),
          LangSelection(langCode: 'pl', isEnabled: false,),
          LangSelection(langCode: 'it', isEnabled: false,),
          Text("Flag icons made by Pixel perfect from www.flaticon.com", style: Theme.of(context).textTheme.subtitle2.copyWith(fontSize: 10), textAlign: TextAlign.center,),
          Divider(height: 20),
          ListTile(
            title: Text(AppLocalizations.of(context).translate('settings_page_reinitialize_text'), style: Theme.of(context).textTheme.subtitle2),
            trailing: IconButton(
              icon: Icon(Icons.restore),
              onPressed: () => Provider.of<SettingsProvider>(context, listen: false).resetSharedPreferences(),
            ),
          ),
          Divider(height: 20),
        ],
      )
    );
  }
}

这是我的 PlayerSelectionPage:

class PlayerSelectionPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    int itemCount = Provider.of<PlayerProvider>(context).getPlayerList.length;
    SystemChrome.setPreferredOrientations([
      DeviceOrientation.portraitUp,
    ]);
    return Scaffold(
      appBar: AppBar(
        title: Text(AppLocalizations.of(context).translate('player_selection_page_title')),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: (){
          HapticFeedback.mediumImpact();
          Navigator.push(context, MaterialPageRoute(builder: (context) => HomePage(), settings: RouteSettings(name: 'Home page')));
        },
        child: Icon(
          Icons.chevron_right,
          size: 30,
          color: Colors.white,
        ),
      ),
      body: itemCount > 0 ? ListView.builder(
          itemCount: itemCount,
          itemBuilder: (context, index) {
            return Column(
              children: [
                PlayerDismissible(index),
                Divider(
                  height: 0,
                )
              ],
            );
          }) : Container(
          padding: EdgeInsets.all(20),
          alignment: Alignment.topCenter,
          child: Text(AppLocalizations.of(context).translate('player_selection_page_empty_text'), textAlign: TextAlign.center, style: Theme.of(context).textTheme.subtitle2)
      ),
      bottomSheet: BottomPlayerBar(),
    );
  }
}

还有 BottomPlayerBar(我在哪里显示键盘:

class BottomPlayerBar extends StatefulWidget {
  @override
  _BottomPlayerBarState createState() => _BottomPlayerBarState();
}

class _BottomPlayerBarState extends State<BottomPlayerBar> {
  String playerName;
  FocusNode myFocusNode;


  @override
  void initState() {
    super.initState();
    myFocusNode = FocusNode();
    myFocusNode.requestFocus();
  }

  @override
  Widget build(BuildContext context) {
    return Container(
        height: 80, color: Theme.of(context).primaryColor,
        padding: EdgeInsets.only(top: 20, bottom: 25, left: 20, right: 70),
        child: TextField(
          focusNode: myFocusNode,
          textCapitalization: TextCapitalization.words,
          onChanged: (val) => playerName = val.trim(),
          onSubmitted: (val) {
            if (playerName != null && playerName != '') {
              Provider.of<PlayerProvider>(context, listen: false).addPlayer(playerName);
              HapticFeedback.lightImpact();
              myFocusNode.requestFocus();
            } else {
              myFocusNode.unfocus();
            }
          },
          maxLength: 19,
          autocorrect: false,
          decoration: new InputDecoration(
              counterText: "",
              border: new OutlineInputBorder(
                borderSide: BorderSide.none,
                borderRadius: const BorderRadius.all(
                  const Radius.circular(30.0),
                ),
              ),
              filled: true,
              contentPadding: EdgeInsets.symmetric(vertical: 0, horizontal: 20),
              hintStyle: GoogleFonts.rubik(color: Colors.grey[500], fontWeight: FontWeight.bold),
              hintText: AppLocalizations.of(context).translate('player_selection_page_hint'),
              fillColor: Colors.white),
        )
    );
  }

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

欢迎任何帮助!

谢谢 !

编辑:这是我的 LangSelection() 类:

class LangSelection extends StatelessWidget {
  String langCode;
  bool isBeta, isEnabled;

  LangSelection({@required this.langCode, this.isBeta = false, this.isEnabled = true});

  @override
  Widget build(BuildContext context) {
    return InkWell(
      highlightColor: Colors.transparent,
      onTap: () {
        if (isBeta) {
          Provider.of<AppLanguageProvider>(context, listen: false).changeLanguage(Locale(langCode));
          Future.delayed(Duration(milliseconds: 100)).then((value) => EasyDialog.showInfoDialog(
            context: context,
            title: AppLocalizations.of(context).translate('settings_page_beta_dialog_title'),
            content: AppLocalizations.of(context).translate('settings_page_beta_dialog_content'),
          ));
        } else if (!isEnabled) {
          EasyDialog.showInfoDialog(
            context: navigatorKey.currentState.overlay.context,
            title: AppLocalizations.of(navigatorKey.currentContext).translate('settings_page_disabled_dialog_title'),
            content: AppLocalizations.of(navigatorKey.currentContext).translate('settings_page_disabled_dialog_content'),
          );
        } else {
          Provider.of<AppLanguageProvider>(context, listen: false).changeLanguage(Locale(langCode));
        }
      },
      child: ListTile(
        leading: Image.asset('assets/images/flags/$langCode.png'),
        title: Text(AppLocalizations.of(context).translate('lang_$langCode'), style: Theme.of(context).textTheme.subtitle2),
        trailing: isBeta ? Text("(beta)", style: Theme.of(context).textTheme.subtitle2.copyWith(fontSize: 10),) :
        !isEnabled ? Text("(disabled)", style: Theme.of(context).textTheme.subtitle2.copyWith(fontSize: 10),) : null,
      ),
    );
  }
}

标签: iosflutterkeyboardprovider

解决方案


问题在于调用requestFocus()您的bottomAppBar's initState(). 每当您重建小部件时,它都会被调用。

尝试删除该行并将其添加到其他位置,或者使小部件实现AutomaticClientKeepAliveMixin并将 keepAlive 设置为 true。


推荐阅读