import 'package:flutter/material.dart'; // This is an example of a bottom sheet with a text field inside a tab // and a footer with another text field. // Please use a tablet simulator on landscape mode to better see the issue. // When the text field of tab 1 is pressed and focused, the keyboard appears and // resizes the bottom sheet correctly. However, the footer go over the whole content of tab 1 which // causes the user to not see what's being written. // I came up with several workarounds but I don't feel it's the right way to handle that kind of situation. // It really felt too "hacky" // My current workarounds: // 1- I tried switching the visibility off of the footer when the tab1's text field is focused. // 2- I tried addind a "resizeToAvoidBottomInset: false" to the Scaffold of the bottom sheet and // adding a listener to the focus node of the footer text field. // Whenever it is focused, I set the bottom padding to MediaQuery.viewInsetsOf(context).bottom // This way, only when the footer text field is focused, the footer is "lifted up" to avoid the keyboard. // When the tab1's text field is focused, nothing is being resized. // Any suggestions or pointers would be appreciated. Thank you void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData.dark(), home: const MyHomePage(title: 'Bottom sheet demo'), ); } } class MyHomePage extends StatefulWidget { const MyHomePage({super.key, required this.title}); final String title; @override State createState() => _MyHomePageState(); } class _MyHomePageState extends State { void _onPressed() { showModalBottomSheet( context: context, useSafeArea: true, isScrollControlled: true, isDismissible: true, builder: (context) => SomeBottomSheet(), ); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text(widget.title)), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ ElevatedButton( onPressed: _onPressed, child: Text("Open bottom sheet"), ), ], ), ), ); } } class SomeBottomSheet extends StatelessWidget { const SomeBottomSheet({super.key}); @override Widget build(BuildContext context) { return GestureDetector( onTap: () => FocusManager.instance.primaryFocus?.unfocus(), child: Scaffold( body: SafeArea( child: Padding( padding: const EdgeInsets.all(16.0), child: Column( mainAxisSize: MainAxisSize.min, children: [ Expanded(child: SomeBody()), SomeFooter(), ], ), ), ), ), ); } } class SomeBody extends StatelessWidget { const SomeBody({super.key}); @override Widget build(BuildContext context) { return DefaultTabController( length: 2, child: Column( children: [ TabBar( tabs: [ Tab(text: "Tab 1"), Tab(text: "Tab 2"), ], ), Expanded( child: Padding( padding: const EdgeInsets.all(8.0), child: TabBarView(children: [Tab1Content(), Tab2Content()]), ), ), ], ), ); } } class Tab1Content extends StatelessWidget { const Tab1Content({super.key}); @override Widget build(BuildContext context) { return SingleChildScrollView( child: Column( spacing: 20, children: [ TextField(decoration: InputDecoration(labelText: "Some label")), ElevatedButton(onPressed: () {}, child: Text("Submit")), ], ), ); } } /// Demonstration purposes only - close to my real use case class Tab2Content extends StatelessWidget { const Tab2Content({super.key}); @override Widget build(BuildContext context) { return ListView.separated( itemCount: 20, separatorBuilder: (context, index) => Divider(), itemBuilder: (context, index) => ListTile(title: Text("Item ${index + 1}")), ); } } class SomeFooter extends StatelessWidget { const SomeFooter({super.key}); @override Widget build(BuildContext context) { return DecoratedBox( decoration: BoxDecoration( color: Colors.black45, borderRadius: BorderRadius.circular(12), ), child: Padding( padding: const EdgeInsets.all(8.0), child: Column( children: [ TextField(decoration: InputDecoration(labelText: "Footer input")), SizedBox(height: 75), // This is a placeholder for any content. ElevatedButton(onPressed: () {}, child: Text("Footer button")), ], ), ), ); } }