I have several TextFormField on a screen. If I tap one of the fields the keyboard opens as expected however if I then select a new screen from the Drawer menu the keyboard closes and as soon as the new screen finishes loading the keyboard automatically opens again. More than that if I type something the text field is updated in the background if I return to the screen with the TextFormField it shows the correct input.
I would expect the screen/widget to be disposed of when navigating to another screen(widget) from the navigation menu, and I definitely should not be able to update the content of a widget's text field while in another widget.
// Form Field
Form(key: _constructionFormKey,
child: Column(children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const SizedBox(
width: 100,
child: Text(
'Homes',
style: regularBoldText,
),
),
SizedBox(
width: 75,
child: Text(
'${widget.tribe.homes} (${calculatePercent(widget.tribe.land, widget.tribe.homes)}%)',
style: regularText,
),
),
SizedBox(
height: 18,
width: MediaQuery.of(context).size.width / 3,
child: TextFormField(
autovalidateMode:
AutovalidateMode.onUserInteraction,
onChanged: (String? newValue) {
if (newValue != null && isNumber(newValue)) {
setState(() {
buildHomes = int.parse(newValue);
});
// Requiered or variable will not clear properly
// when the user deletes input content
} else if (newValue == null || newValue.isEmpty) {
setState(() {
buildHomes = 0;
});
}
},
inputFormatters: <TextInputFormatter>[
FilteringTextInputFormatter.digitsOnly
],
style: const TextStyle(fontSize: 10),
decoration: const InputDecoration(
border: OutlineInputBorder()),
keyboardType: TextInputType.number,
),
),
],
),));
// Home Screen where I have the navigation logic.
class HomeScreen extends StatefulWidget {
const HomeScreen({Key? key}) : super(key: key);
@override
State<HomeScreen> createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
//! Default to tribe overview screen - 1 -, 0 is mail screen
int _drawerNavIndex = 3;
/// [setSelectedTab] will update the current screen based on the tapped option
/// from [DrawerContentWidget]
void setSelectedTab(index) {
// if the [_drawerNavIndex] is not the same as [index] update it to [index]
// value
if (_drawerNavIndex != index) {
setState(() {
_drawerNavIndex = index;
});
}
}
/// [selectedTabContent] will return the screen selected from the
/// [DrawerContentWidget] based on [_drawerNavIndex]
Widget selectedTabContent() {
List<Widget> pages = [
// Tribe Screens
const TribeMailScreen(),
const TribeHomeScreen(),
const TribeAdvisorScreen(),
const ConstructionScreen()
// Alliance
];
return IndexedStack(
index: _drawerNavIndex,
children: pages,
);
}
@override
Widget build(BuildContext context) {
TribeSummary tribe = Provider.of<TribeSummary>(context, listen: true);
// If the tribe uid value is `placeHolderTribe` assume that there is no
// existing or active tribe for this account
if (tribe.uid == 'placeHolderTribe') {
return Scaffold(
/// TODO: create a proper drawer or appBar for the [StartTribeWidget]
appBar: AppBar(
title: const Text('Orkfia'),
),
body: const StartTribeWidget(),
);
// If the tribe `uid` value is `placeHolderTribe` assume that an error
// occurred while trying to get the tribe stream or while the tribe stream
// is parsed to [TribeSummary], log should give more information
} else if (tribe.uid == 'placeHolderErrorTribe') {
// TODO: create a bettter error screen for this situation
return const Center(
child: Text('Unable to retrieve tribe data'),
);
}
// This Scaffold wraps the entire app, anything here will be avilable
// globally
return Scaffold(
// App Bar
appBar: const AppBarContent(),
// [DrawerContentWidget] holds all the drawer content, it requires
// [selectedTab] function to handle the navigation between screens
drawer: DrawerContentWidget(
setSelectedTab: setSelectedTab,
selectedTabIndex: _drawerNavIndex,
),
// Display the contents of the selected screen
body: selectedTabContent(),
// Reserved
bottomNavigationBar: SizedBox(
height: 50,
child: Container(
color: Colors.red[100],
child: const Center(child: Text('Reserved space')),
)),
);
}
}