I have built a Flutter application using MobX as my state management and am running into a strange issue at the moment that is only present on Android running in release mode.
I'm not sure if the offender is MobX, Hive or just Flutter in Android itself. However, on this specific page in my app, the Obsever will only display the last entry in the list. The other items are present, but the UI will only show the last index of the list. When I turn my phone landscape, the full content of the list is then visible and the page displays exactly as intended. Is there a way I can force the widgets to re-render in MobX when the page has already loaded?
I have tried downgrading my target SDK to 28, downgrading the gradle version, setting shrinkResources & minifyEnabled to false, enabled proguard. I also have ensured to call this in my main.dart;
WidgetsFlutterBinding.ensureInitialized();
Also attached are the outputs of my flutter doctor.
Again, this issue is only present on Android release build of my app. It works perfectly on iOS & Android on debug.
Any help would be greatly appreciated.
Below is the widget in question that has issues rendering in release mode
Widget _carPackageList() {
return ListView.builder(
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemCount: viewModel.customerCars.length,
itemBuilder: (context, index) => _carListItem(index));
}
Widget _carListItem(index) {
var packageDetails = viewModel.getDetailBookingById(
viewModel.customerCars[index].packageGroupId);
return Observer(
builder: (context) {
if (viewModel.isLoading) {
return CustomProgressIndiactor();
} else {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Flexible(
child: Column(
children: [
Text(
viewModel.customerCars[index].makeAndModel,
maxLines: 2,
style: TextStyle(
fontSize: 25,
fontFamily: 'Domus',
color: Color(0xff3c99a0))),
],
),
),
IconButton(
icon: Icon(Icons.highlight_remove, color: Colors.black),
onPressed: () {
viewModel.removeCustomerCar(index);
viewModel.customerCars.removeAt(index);
})
],
),
Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0),
),
child: Container(
width: double.infinity,
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Flexible(
child: Column(
children: [
Padding(
padding: const EdgeInsets.all(15.0),
child: Text(packageDetails.name,
overflow: TextOverflow.ellipsis,
maxLines: 2,
style: TextStyle(
fontSize: 25,
fontFamily: 'Domus',
color: Color(0xff3c99a0))),
),
],
),
),
Padding(
padding: const EdgeInsets.all(15.0),
child: Observer(
builder: (_) {
var groupPrice =
viewModel.calculateCarCost(
viewModel.customerCars[index],
viewModel.customerCars[index]
.packageGroupId);
if (groupPrice == null) {
return Text('£0.00',
style: TextStyle(
color: Color(0xff1A2E35),
fontFamily: 'Aileron',
fontWeight: FontWeight.w700));
} else {
return Text(
'£${groupPrice.toStringAsFixed(2)}',
style: TextStyle(
color: Color(0xff1A2E35),
fontFamily: 'Aileron',
fontWeight: FontWeight.w700),
);
}
},
),
),
],
),
Padding(
padding: const EdgeInsets.only(
left: 15.0, top: 0, right: 15),
child: Text(packageDetails.description,
style: TextStyle(
color: Color(0xff1A2E35),
fontFamily: 'Aileron',
fontSize: 16,
fontWeight: FontWeight.w300)),
),
Padding(
padding: const EdgeInsets.all(15.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text('Optional Extras',
style: GoogleFonts.lato(
fontSize: 16,
color: Colors.black,
fontWeight: FontWeight.bold)),
Observer(
builder: (_) {
var opExtraPrice = viewModel
.calculateOptionalExtrasPrice(viewModel
.customerCars[index]
.optionalExtras);
if (opExtraPrice == null) {
return Text('£0.00',
style: TextStyle(
color: Color(0xff1A2E35),
fontFamily: 'Aileron',
fontWeight: FontWeight.w700));
} else {
return Text(
'£${opExtraPrice.toStringAsFixed(2)}',
style: TextStyle(
color: Color(0xff1A2E35),
fontFamily: 'Aileron',
fontWeight: FontWeight.w700));
}
},
),
],
),
),
Padding(
padding: const EdgeInsets.all(15.0),
child: ListView.builder(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemCount: viewModel.customerCars[index]
.optionalExtras.length,
itemBuilder: (context, innerIndex) {
var detailedOptionalExtra =
viewModel.getOptinalExtraById(viewModel
.customerCars[index]
.optionalExtras[innerIndex]
.packageItemId);
return Text(
detailedOptionalExtra.name,
style: TextStyle(
color: Color(0xff1A2E35),
fontFamily: 'Aileron',
fontSize: 16,
fontWeight: FontWeight.w300),
);
},
)),
Padding(
padding: const EdgeInsets.all(15.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(
'Total Cost:',
style: TextStyle(
color: Color(0xff1A2E35),
fontFamily: 'Aileron',
fontSize: 16,
fontWeight: FontWeight.w700),
),
Observer(
builder: (context) => Text(
'£${viewModel.currentTotalCost.toStringAsFixed(2)}',
style: TextStyle(
color: Color(0xff1A2E35),
fontFamily: 'Aileron',
fontWeight: FontWeight.w700))),
],
),
)
],
),
),
),
],
),
);
}
},
);
}
The solution I found was to generate the list directly from the Hive box using a ValueListenableBuilder to listen to the box and add more elements to the list as soon as they arrive in the box. I can only assume there was some kind of race case going on with MobX attempting to gather the elements in the box from Hive and then serve up to the UI layer. I'll attach some sample code below for anyone else who may run into a similar issue.
Widget buildList() {
var _box = Hive.box("myBox").listenable();
return ValueListenableBuilder(
valueListenable: _box,
builder: (context, box, widget) {
return ListView.builder(
itemCount: box.length,
itemBuilder: (context, index) {
return Container(
decoration: BoxDecoration(
border: Border(bottom: BorderSide(width: 0.1))),
child: ListTile(
title: Text(Hive.box("myBox").getAt(index)),
),
);
},
);
});
}
Related
i'm trying to build a release version of my flutter app using the cmd flutter build apk, the problem is that one page does not show any content. In the debug version it all works fine, but in the release version that page does not work properly.
The 2 images below show the output for the 2 versions.
Debug version:
Release version:
Code of the page in which the bug occurs:
class ProductListPage extends StatefulWidget {
ProductListPage(
{Key? key,
Title? title,
required this.subCatId,
required this.subCatName})
: super(key: key);
final String title = '';
static const String page_id = 'Product List';
int subCatId;
String subCatName;
#override
State<ProductListPage> createState() => _ProductListPageState();
}
class _ProductListPageState extends State<ProductListPage> {
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
elevation: 0,
backgroundColor: Colors.white,
automaticallyImplyLeading: true,
iconTheme: IconThemeData(color: style.appColor),
title: Text(widget.subCatName),
centerTitle: false,
titleTextStyle: style.pageTitle(),
actions: [
IconButton(onPressed: () {}, icon: Icon(Icons.search)),
IconButton(onPressed: () {}, icon: Icon(Icons.share_outlined))
],
),
body:
_buildBody(), // This trailing comma makes auto-formatting nicer for build methods.
);
}
Widget _buildBody() {
return SingleChildScrollView(
child: Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
decoration: style.bottomBorder(),
child: Row(
children: [
Expanded(
child: ElevatedButton.icon(
onPressed: () {},
icon: Icon(Icons.filter_alt_outlined),
label: Text('Filter'),
style: simpleButton(),
)),
Expanded(
child: ElevatedButton.icon(
onPressed: () {},
icon: Icon(Icons.sort_outlined),
label: Text('Sort'),
style: simpleButton(),
)),
],
),
),
GetBuilder<ProductsController>(builder: (prodsBySub) {
Get.find<ProductsController>()
.getProductsBySubCategory(widget.subCatId);
return GridView.count(
crossAxisCount: 2,
shrinkWrap: true,
physics: ScrollPhysics(),
mainAxisSpacing: 16,
crossAxisSpacing: 16,
childAspectRatio: 70 / 100,
padding: EdgeInsets.all(16),
children: List.generate(
prodsBySub.productsListBySubCategory.length, (index) {
return _buildSingleProduct(
index,
ProductModel.fromJson(
prodsBySub.productsListBySubCategory[index]));
}),
);
})
],
),
),
);
}
Widget _buildSingleProduct(int position, ProductModel product) {
return InkWell(
onTap: () {
Get.toNamed(RouteHelper.getProduct(position, product.id));
},
child: Container(
width: double.infinity,
height: double.infinity,
padding: EdgeInsets.all(8),
decoration: style.shadowContainer(),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
width: double.infinity,
height: 140,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/images/mango.png'),
fit: BoxFit.contain)),
),
SizedBox(height: 8),
Text(
product.title,
style: TextStyle(fontSize: 14, fontFamily: 'medium'),
),
Text(
'50g/pack',
style: TextStyle(fontSize: 13, color: Colors.grey),
),
SizedBox(height: 8),
Row(
children: [
Expanded(
child: Row(
children: [
Container(
padding: EdgeInsets.symmetric(horizontal: 6, vertical: 1),
margin: EdgeInsets.only(right: 8),
decoration: style.offContainer(),
child: Text('10%', style: style.offLabel()),
),
Text(
'${product.price} €',
style: TextStyle(fontSize: 16, fontFamily: 'medium'),
),
],
)),
Container(
height: 30,
width: 30,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(5)),
color: style.appColor),
child: Icon(Icons.add, color: Colors.white),
),
],
),
],
),
),
);
}
simpleButton() {
return ElevatedButton.styleFrom(
onPrimary: Colors.grey,
padding: EdgeInsets.symmetric(vertical: 12),
elevation: 0,
primary: Colors.transparent);
}
}
I have tried some solutions found on the internet like adding Internet permission for the APIs, or editing the build.gradle file. None of these solutions worked for me. I would love to get some help, thanks in advance.
just add expanded around the gridview and everything is work
Solved it thanks to #Amanpreet Kaur's comment, actually I used flutter run --release and it showed me where the error was located, fixed it and it's all good now!
Im new in flutter, so i follow someone's tutorial to make music player app, everything normal until my app suddenly crashed, i tried to re-run the app but still it's crashed and i try to remove the code that last time i create and the app run normal, so what's wrong with the code?, sorry for my bad english.
....////
Widget _buildWidgetArtistName(MediaQueryData mediaQuery) {
return SizedBox(
height: mediaQuery.size.height / 1.8,
child: Padding(
padding: const EdgeInsets.only(left: 20.0),
child: LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
return Stack(
children: <Widget>[
Positioned(
child: Text(
'Grande',
style: TextStyle(
color: Colors.white,
fontFamily: 'CoralPen',
fontSize: 72.0,
),
),
top: constraints.maxHeight - 100.0,
),
Positioned(
child: Text(
'Ariana',
style: TextStyle(
color: Colors.white,
fontFamily: 'CoralPen',
fontSize: 72.0,
),
),
top: constraints.maxHeight - 140.0,
),
Positioned(
child: Text(
'Tranding',
style: TextStyle(
color: Color(0xFF7D9AFF),
fontSize: 14.0,
fontFamily: 'Campton_Light',
fontWeight: FontWeight.w800,
),
),
top: constraints.maxHeight - 160.0,
),
],
);
},
),
),
);
}
#override
Widget build(BuildContext context) {
var mediaQuery = MediaQuery.of(context);
return Scaffold(
key: scaffoldState,
body: Stack(
children: [
_buildWidgetAlbumCover(mediaQuery),
_buildWidgetActionAppBar(mediaQuery),
_buildWidgetArtistName(mediaQuery), // This causing crash
],
),
);
}
I am retrieving data fro my Firestore and I can't seem to get my code to work. I want it to display something when it can't find data in the collection I gave it......................................................................................................................................................
Here is my code:
StreamBuilder(
stream: Firestore.instance.collection("payments").where('participants', arrayContains: userActive).snapshots(),
builder: (context, snapshot){
return Container ( child:ListView.builder(
shrinkWrap: true,
itemCount: snapshot.data.documents.length,
padding: EdgeInsets.all(0),
controller: ScrollController(keepScrollOffset: false),
itemBuilder: (context, index){
DocumentSnapshot documentSnapshot = snapshot.data.documents[index].data();
if(snapshot.data.documents.isEmpty){
print("No Data!!!");
}else{
print("Found Data!!!");
}
/* if(documentSnapshot["receiver_name"] == userActive ) {
return Container(
margin: EdgeInsets.symmetric(horizontal: 32,vertical: 5),
padding: EdgeInsets.all(16),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(20))
),
child: Row(
children: <Widget>[
Container(
decoration: BoxDecoration(
color: Colors.grey[100],
borderRadius: BorderRadius.all(Radius.circular(18))
),
child: Icon(Icons.attach_money, color: Colors.lightBlue[900],),
padding: EdgeInsets.all(12),
),
SizedBox(width: 16,),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text("Recieved", style: TextStyle(fontSize: 18, fontWeight: FontWeight.w700, color: Colors.grey[900]),) ,
Text("" + documentSnapshot["currency_received"] + documentSnapshot["amount_received"], style: TextStyle(fontSize: 15, fontWeight: FontWeight.w700, color: Colors.grey[500]),),
],
),
),
Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
Text("+ " + documentSnapshot["currency_sent"] + documentSnapshot["amount_paid"].toString(), style: TextStyle(fontSize: 18, fontWeight: FontWeight.w700, color: Colors.lightGreen),),
Text(documentSnapshot["date"].toDate().toString(), style: TextStyle(fontSize: 15, fontWeight: FontWeight.w700, color: Colors.grey[500]),),
],
),
],
),
);
} else if (documentSnapshot["sender_name"] == userActive){
return Container(
margin: EdgeInsets.symmetric(horizontal: 32,vertical: 5),
padding: EdgeInsets.all(16),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(20))
),
child: Row(
children: <Widget>[
Container(
decoration: BoxDecoration(
color: Colors.grey[100],
borderRadius: BorderRadius.all(Radius.circular(18))
),
child: Icon(Icons.attach_money, color: Colors.lightBlue[900],),
padding: EdgeInsets.all(12),
),
SizedBox(width: 16,),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text("Sent", style: TextStyle(fontSize: 18, fontWeight: FontWeight.w700, color: Colors.grey[900]),) ,
Text("" + documentSnapshot["currency_received"] + documentSnapshot["amount_received"], style: TextStyle(fontSize: 15, fontWeight: FontWeight.w700, color: Colors.grey[500]),),
],
),
),
Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
Text("- " + documentSnapshot["currency_sent"] + documentSnapshot["amount_paid"].toString(), style: TextStyle(fontSize: 18, fontWeight: FontWeight.w700, color: Colors.orange),),
Text(documentSnapshot["date"].toDate().toString(), style: TextStyle(fontSize: 15, fontWeight: FontWeight.w700, color: Colors.grey[500]),),
],
),
],
),
);
}else{
return Text("Nothng found ",style: TextStyle(fontSize: 15, fontWeight: FontWeight.w700, color: Colors.black));
}
*/
},
)
);
}
),
There is a new update to Firestore recently and you have to retrieve the value by using .data().
To make your code work, you would have to change this:
DocumentSnapshot documentSnapshot = snapshot.data.docs[index]; //not working code
Add .data() in the end:
DocumentSnapshot documentSnapshot = snapshot.data.documents[index].data(); //working code
check your cloud_firestore version, if you're using version cloud_firestore: ^0.14.0
DocumentSnapshot documentSnapshot = snapshot.data.documents[index].data();
if not use
DocumentSnapshot documentSnapshot = snapshot.data.documents[index].data; //this is a getter
data is a getter, not a method and should be called without parenthesis (javascript uses them because its a method there, but not in dart) but only before version 0.14.0. If you're not sure you can run pub outdated to check the current versions of your packages.
Also it could be better to change it like this
StreamBuilder<QuerySnapshot>(
stream: Firestore.instance.collection("payments").where('participants', arrayContains: 'userActive').snapshots(),
builder: (context, snapshot){
if(snapshot.connectionState == ConnectionState.active && snapshot.hasData) {
if(snapshot.data.documents.isEmpty) return Center(child: const Text('No Data!'));
print("Found Data!!!");
return Container ( child:ListView.builder(...)); //your listView here
}
return Center(child: const CircularProgressIndicator());
},
);
Hello new to flutter here. I am trying to open phone dialer with a predefined phone number after pressing Call button that is Flatbutton inside Positioned, but it is not working and does not show any error either. I tried printing some values on onpressed as well but it did not print any. I have called this widget in another dart file.
Here i am using url_launcher package to launch the phone dialog.
If any other alternative way please help.
(Removed some unimportant design codes below)
class CallCard extends StatefulWidget {
#override
_CallCardState createState() => _CallCardState();
}
class _CallCardState extends State<CallCard> {
#override
Widget build(BuildContext context) {
return Positioned(
bottom: -170,
child: Container(
child: Column(
children: <Widget>[
SizedBox(
height: 15,
),
Text(
'Are you feeling well today?',
style: TextStyle(
fontSize: 24.0,
),
),
Text(
'Give us a call or visit our website.',
style: TextStyle(
fontSize: 18.0,
fontWeight: FontWeight.w300,
),
),
SizedBox(
height: 23.0,
),
Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
FlatButton(
padding: EdgeInsets.symmetric(horizontal: 20, vertical: 15),
color: Color(0xff9ce47c),
onPressed: () {
final String phone = "01-4441577";
launch(phone);
print('here');
},
shape: RoundedRectangleBorder(
side: BorderSide(color: Colors.black),
borderRadius: BorderRadius.circular(50),
),
child: Row(
children: <Widget>[
Icon(
LineAwesomeIcons.phone,
size: 22,
),
SizedBox(
width: 5.0,
),
Text(
'Call Now',
style: TextStyle(
fontSize: 16,
),
),
],
),
),
SizedBox(
width: 1.0,
),
],
),
),
],
)
],
),
));
}
}
This is the code where I have called this widget (inside Stack)
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Stack(
alignment: Alignment.topCenter,
overflow: Overflow.visible,
children: <Widget>[
_backgroundCover(),
//content inside header
Positioned(
top: 80,
left: 30,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
//crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
'Hello User',
style: TextStyle(
fontSize: 36,
fontWeight: FontWeight.w500,
color: Colors.black,
),
),
SizedBox(width: 10.0,),
// Padding(padding: EdgeInsets.only(right: 200.0)),
IconButton(
icon: Icon(
LineAwesomeIcons.power_off,
size: 40.0,
),
onPressed: () {
DialogHelper.exit(context);
// await _auth.signOut();
}),
],
),
),
CallCard(),
],
),
],
),
),
);
Did you try putting the print before launch? It could be that launch is getting stuck and then the print never gets reached (this has happened to me with certain packages).
I am not sure how launch works with phone numbers but you may want to look into if youre using it properly.
I'm ok with this code.
launch('tel:$yourPhoneNo');
I have a column inside a single child scroll view. I need to make my login screen scroll when I type using the keyboard because the keyboard hides the password text field.
class UserRegistration extends StatefulWidget {
#override
_UserRegistrationState createState() => _UserRegistrationState();
}
class _UserRegistrationState extends State<UserRegistration> {
#override
Widget build(BuildContext context) {
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
statusBarColor: Color(0xFF6C62FF)
));
return SafeArea(
child: GestureDetector(
onTap: () => FocusScope.of(context).requestFocus(FocusNode()),
child: Scaffold(
resizeToAvoidBottomInset: false,
resizeToAvoidBottomPadding: false,
backgroundColor: Color(0xFF6C62FF),
body: SingleChildScrollView(
padding: EdgeInsets.symmetric(horizontal: 30),
child: Column([![enter image description here][1]][1]
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Center(child: FittedBox(child: Text('Welcome', style: TextStyle(fontFamily: 'SourceSans', fontSize: 50, fontWeight: FontWeight.w600, color: Color(0xFFFFD700)),))),
Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Register', style: TextStyle(fontFamily: 'SourceSans', fontSize: 40, fontWeight: FontWeight.w600, color: Colors.white)),
SizedBox(height: 5,),
Text('Start from today', style: TextStyle(fontFamily: 'SourceSans', fontSize: 25, letterSpacing: 1.5,fontWeight: FontWeight.w600, color: Colors.white), overflow: TextOverflow.ellipsis,),
],
),
),
Form(
child: Column(
children: [
EditTextNormal(hintText: 'Email', iconData: Icons.email, textInputType: TextInputType.emailAddress, validate: false, errorText: 'Enter your email',),
SizedBox(height: 20,),
EditTextObscure(hintText: 'Password', iconData: Icons.lock, textInputType: TextInputType.text, validate: false, errorText: 'Enter your password',),
SizedBox(height: 50,),
Container(
height: 50,
width: 180,
child: FlatButton(
splashColor: Colors.transparent,
highlightColor: Colors.transparent,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8)
),
onPressed: () {},
color: Colors.white,
child: Text('Register', style: TextStyle(color: Color(0xFF6C62FF), fontSize: 20), overflow: TextOverflow.ellipsis,),
),
)
],
),
),
Center(
child: RichText(
text: TextSpan(
children: <TextSpan>[
TextSpan(text: 'Login', style: TextStyle(color: Color(0xFFFFD700), letterSpacing: 1, wordSpacing: 1.5))
],
text: 'Have an account? ',
style: TextStyle(fontSize: 18, fontFamily: 'SourceSans', fontWeight: FontWeight.bold, letterSpacing: 1, wordSpacing: 1.5)
),
),
),
],
),
),
),
),
);
}
}
This is my code but here when I use a column inside a single child scroll view space evenly does not work. Please give me a solution.
My output:
Expected Output:
Try This
Widget build(BuildContext context) {
return Scaffold(
body: SingleChildScrollView(
physics: NeverScrollableScrollPhysics(),
child: ConstrainedBox(
constraints: BoxConstraints(
minWidth: MediaQuery.of(context).size.width,
minHeight: MediaQuery.of(context).size.height,
),
child: IntrinsicHeight(
child: Column(
mainAxisSize: MainAxisSize.max,
children: <Widget>[
// CONTENT HERE
],
),
),
),
),
);
}
Add Container inside SingleChildScrollView and assign it height based on your keyboard open or not.
Add Dependency:
dependencies:
keyboard_visibility: ^0.5.6
Initialize keyboard listener in initState() for callback
bool _isKeyBoardShown = false;
#protected
void initState() {
super.initState();
KeyboardVisibilityNotification().addNewListener(
onChange: (bool visible) {
setState(() {
_isKeyBoardShown = visible;
});
},
);
}
Based on _isKeyBoardShown value decide whether to add additional height on the screen or not.
Container(
width: MediaQuery.of(context).size.width,
height: _isKeyBoardShown
? MediaQuery.of(context).size.height +
MediaQuery.of(context).size.height / 2
: MediaQuery.of(context).size.height,
child: Column(....)
)
Note: Use MediaQuery to decide additional height don't use hard-coded values
here I used MediaQuery.of(context).size.height / 2