Flutter - Textfield not showing up when keyboard appears on android
Solution 1
android/app/src/main/res/values/styles.xml
For me changing below item property from true to false
<item name="android:windowFullscreen">false</item>
I had this issue, too. This line was added as a result of using the flutter_native_splash package.
Solution 2
You can wrap your BottomPlayerBar widget with the Transform Widget as shown below.
Transform.translate(
offset: Offset(0.0, -1 * MediaQuery.of(context).viewInsets.bottom),
child: BottomPlayerBar(),
);
Solution 3
Resizing the page when the soft keyboard appears is handled through the android:windowSoftInputMode
activity parameter in AndroidManifest. See the official documnetation
If you have android:windowSoftInputMode="adjustResize"
in your AndroidManifest.xml, the textfield will automatically reposition when the softkeyboard appears. The same behaviour will not happen if the parameter is not there in AndroidManifest.xml
Could you recheck this by modifying your AndroidManifest. That will also explain why it is not working only in Android but works in iOS (Because iOS handles this implicitly)
P.S: When modifying the AndoridManifest.xml, hot reload may not work. You will need an actual stop and start running the app.
Simon B
Updated on December 23, 2022Comments
-
Simon B over 1 year
My problem is that when I focus on the textfield, the keyboard appears but the layout doesn't resize to keep it in the view. This problem is only with android and not iOS: Here a screenshot of what I mean:
Before and after on android:
Before and after on iOS:
Here is my class :
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(), ); } }
And here is my 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(); SchedulerBinding.instance.addPostFrameCallback((_) { if (ModalRoute.of(context).isCurrent) { 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(); } }
Here is my android manifest:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="myApp"> <application android:name="io.flutter.app.FlutterApplication" android:label="myApp !" android:icon="@mipmap/ic_launcher"> <activity android:name=".MainActivity" android:launchMode="singleTop" android:theme="@style/LaunchTheme" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode" android:hardwareAccelerated="true" android:windowSoftInputMode="adjustResize"> <meta-data android:name="io.flutter.embedding.android.LaunchTheme" android:resource="@style/LaunchTheme" /> <meta-data android:name="io.flutter.embedding.android.SplashScreenDrawable" android:resource="@drawable/launch_background" /> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> <intent-filter> <action android:name="FLUTTER_NOTIFICATION_CLICK" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity> <meta-data android:name="flutterEmbedding" android:value="2" /> </application> </manifest>
-
Nemi Shah over 3 yearsCan you post the setup in the android manifest file
-
Simon B over 3 yearsHere it is, but I don't really know how it'll help.
-
Rod over 3 yearsBecause of your 'android:windowSoftInputMode="adjustResize"'. It should be doing what you want.
-
Simon B over 3 yearsShould I delete this line ?
-
Simon B over 3 yearsIt didn't work...
-
-
Simon B over 3 yearsThanks a lot, this was exactly the problem !