如何解决Flutter-我的键盘弹出了,什么地方都没弹出,什么时候不应该弹出?
我的应用程序有问题...
我有一个游戏应用程序,需要在该应用程序的开头实现玩家。因此,在名为PlayerSelectionPage的第一页中,可以将玩家添加到游戏中。然后,您可以选择一种游戏模式。无论如何,当我进入设置并切换游戏的语言时,我的键盘会无缘无故地弹出……我认为这与我的PlayerPageSelection以及与提供商重新构建所有内容以更改语言的事实有关。>
这里是一个例子:
这是我的设置页代码:
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',LangSelection(langCode: 'pl',LangSelection(langCode: 'it',Text("Flag icons made by Pixel perfect from www.flaticon.com",style: Theme.of(context).textTheme.subtitle2.copyWith(fontSize: 10),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(),],)
);
}
}
这是我的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'),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'),trailing: isBeta ? Text("(beta)",) :
!isEnabled ? Text("(disabled)",) : null,);
}
}
解决方法
问题出在您的requestFocus()
中调用bottomAppBar's initState()
。每当您重建窗口小部件时,它就会被调用。
尝试删除该行并将其添加到其他位置,或者使小部件实现AutomaticClientKeepAliveMixin
并将keepAlive设置为true。
我自己找到了答案。正如@Crazzygamerr所说
问题在于在bottomAppBar的initState()中调用requestFocus()。每当您重建窗口小部件时,它就会被调用。
所以我做到了:
@override
void initState() {
super.initState();
myFocusNode = FocusNode();
SchedulerBinding.instance.addPostFrameCallback((_) {
if (ModalRoute.of(context).isCurrent) {
myFocusNode.requestFocus();
}
});
}
在我的BottomPlayerBar的initState中。 SchedulerBinding.instance.addPostFrameCallback
的作用是等待类的构建,以便我可以访问context
。然后,使用ModalRoute.of(context).isCurrent
,检查是否为用户显示了BottomPlayerBar,如果显示了,我给了焦点,出现了键盘,如果没有,它什么也没做...所以我的键盘不再出现了当我切换语言时。
谢谢!
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。