Screen is reloading every element/api inside when keyboard opens/closes inside a show dialog - flutter

I have a screen, which contains a button, when tapping on that button, a showDialog function is been called, which displays a popup with a textfield, whenever the keyboard appears or disappears, the whole screen reloads, even the api calls, as if I'm calling setState ,
the class is a StatefulWidget
Button trigger:
CustomButton(buttonName: defaultLanguage == "en" ? "Settings" : "Ajustes", backgroundColor:
appVioletColor, onPress: () {
PopupScreen().displayDialog(context, isLargeScreen);
}, isLanguage: true, style: Styles.generateWeightFont(Colors.white, isLargeScreen ? 18 : 9, FontWeight.w400),
image: new AssetImage('assets/Settings/setting.png'), isLargeScreen: isLargeScreen ,),
PopupScreen code:
class PopupScreen {
final pinCodeReader = TextEditingController();
Future displayDialog(BuildContext context, bool isLargeScreen) {
return
showDialog(
barrierDismissible: true,
useSafeArea: false,
context: context,
builder: (BuildContext context) =>
Material(
type: MaterialType.transparency,
child: Center(
child:
Padding(
padding: EdgeInsets.only(
bottom: MediaQuery.of(context).viewInsets.bottom),
child:
Container(
color: Colors.white,
height: MediaQuery.of(context).size.height / 2,
width: MediaQuery.of(context).size.width / 1.5,
child:
ListView(
children:[
Column(
children: [
Container(
alignment: Alignment.topCenter,
height: 12,
width: 411,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/WelcomeScreen/purple-top-rec.png"),
)
),
),
const SizedBox(height: 24,),
Container(
width: 200,
height: 100,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/WelcomeScreen/pin_icon.png"),
)
),
),
const SizedBox(height: 17,),
Container(
padding: EdgeInsets.only(left: 25),
alignment: Alignment.topLeft,
child: Text("Please enter security pin", style:
Styles.generateWeightFont(Colors.black, 24, FontWeight.w400),),
),
const SizedBox(height: 15,),
Container(
padding: EdgeInsets.only(left: 25, right: 25),
child: buildCommonTextField("", pinCodeReader, whiteGrey, TextInputType.number),
),
const SizedBox(height: 12,),
Container(
alignment: Alignment.center,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Container(
width: 100,
height: 50,
alignment: Alignment.center,
decoration: BoxDecoration(
border: Border.all(color: greyColor, width: 1)
),
child: Text("Cancel", style: Styles.generateWeightFont(greyColor, 18, FontWeight.w700),),
),
const SizedBox(width: 10,),
Container(
width: 114,
height: 48,
alignment: Alignment.center,
decoration: BoxDecoration(
color: appVioletColor,
border: Border.all(color: greyColor, width: 1)
),
child: Text("Done", style: Styles.generateWeightFont(Colors.white, 18, FontWeight.w700),),
),
],
),
)
],
),
],
),
),
)
)
)
);
}
}
Anyone has an idea what's going on?
thanks

When the keyboard appears or disappears, it is an animation that can last for a little while. During this, the available screen area for your app is constantly changing: on opening the keyboard it shrinks, on closing the keyboard it grows.
Whenever you use MediaQuery.of(context) in your code, Flutter engine will keep notifying your widget about media changes, causing rebuilds. So in your case the widget is rebuilt on every animation frame caused by opening or closing the keyboard.
This is an intended behaviour, for example if the user rotates the screen, the available MediaQuery.of(context).size will change, and it should result in a rebuild. If you'd like to avoid this, organize you code in a way that it calls MediaQuery.of(context) only in those parts where you want to get updates about media parameters constantly.

Related

How to disable Inkwell image button in flutter

I would like to make the inkwell image button to be disabled. I can disable onTap event, but can't make gray like disabled button. I tried with adding this code
decoration: new BoxDecoration(color:Colors.grey.withOpacity(0.6)),
But it doesn't work as I want.
My code:
child: Container(
decoration:
new BoxDecoration(color: Colors.grey.withOpacity(0.6)),
child: Material(
//elevation: 4.0,
clipBehavior: Clip.none,
color: Colors.black,
child: Stack(
alignment: Alignment.center,
fit: StackFit.passthrough,
children: [
Ink.image(
image: AssetImage(ihaveheard_imagepath),
fit: BoxFit.cover,
width: MediaQuery.of(context).size.width / 4 * 3,
height: MediaQuery.of(context).size.width / 6,
child: InkWell(onTap: () {}),
),
Align(
alignment: Alignment.center,
child: Padding(
padding: EdgeInsets.all(8.0),
child: InkWell(
child: Text(
LocaleKeys.ihaveheard,
style: TextStyle(
fontSize:
MediaQuery.of(context).size.width / 30,
color: Colors.white),
).tr(),
onTap: () {
ihaveheard_imagepath =
"assets/images/greenbutton.png";
setState(() {});
},
),
),
)
],
),
),
),
child:
IgnorePointer(
ignoring: disableBtn, //true or false
child: Container(
foregroundDecoration: disableBtn
? BoxDecoration( //this can make disabled effect
color: Colors.grey,
backgroundBlendMode: BlendMode.lighten)
: null,
child: ...
You can use IgnorePointer as parent widget to prevent tab event.
IgnorePointer(
ignoring: disableBtn, //true, false
child: yourWidget()
You can pass null to decoration to show default based on tappable state
Container(
decoration: disableBtn? BoxDecoration(...): null,
.....
)

Not click on Container in Stack

I have a problem with the Stack Widget.
I have a Stack that contains two children: an Image wrapped with GestureDetector and a Container
. When i click anywhere on the Container, whoever is last on the Stack children list his onTap
I am extremely new to flutter.
Screenshot of the screen
this code
sonItem(dynamic icon ,String text,Color color){
return GestureDetector(
onTap: () {
print("dddddddddddddddd");
},
child: Container(
width: 70,
height: 100,
margin: EdgeInsets.all(2),
padding: EdgeInsets.all(2),
child: Column(
children: [
Icon(icon ,color: color,),
Text(text)
],
),
),
);
}
I Have a problem with the Stack Widget.
I have a Stack that contains two children: an Image wrapped with GestureDetector and an Container
. When i click anywhere on the Container , whoever is last on the Stack children list his onTap
body: Container(
color: Colors.white,
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Container(
color: Color(0xffF0F0F0),
height: 200,
child: Stack(
overflow: Overflow.visible,
alignment: Alignment.center,
children: [
Positioned(
bottom: -170.0,
child: Container(
padding: EdgeInsets.only(top: 40 , right: 10, left: 10),
height: 250,
decoration: BoxDecoration(
color: Color(0xffFFFFFF),
borderRadius: BorderRadius.circular(30),
border: Border.all(
width: 1,
color: Colors.black,
style: BorderStyle.solid,
),
),
child: Column(
children: [
Text('company',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 24,
color: Colors.black,
),
),
Text("The number 2000"),
RatingBar(
rating: 3,
icon:Icon(Icons.star,size:20,color: Colors.grey,),
starCount: 5,
spacing: 5.0,
size: 20,
isIndicator: false,
allowHalfRating: true,
onRatingCallback: (double value,ValueNotifier<bool> isIndicator){
print('Number of stars--> $value');
//change the isIndicator from false to true ,the RatingBar cannot support touch event;
isIndicator.value=true;
},
color: Colors.amber,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
sonItem(Icons.phone,"call us",Colors.green),
sonItem(Icons.location_on_outlined,"location",Colors.red),
sonItem(Icons.facebook,"FaceBook",Colors.blue),
sonItem(Icons.add_ic_call_outlined,"whatsapp",Colors.green)
],
)
],),
)),
Try below code hope its help to you
Stack(
children: <Widget>[
//your InkWell or GestureDetector Widget
InkWell(
child: Container(
// your child Widget
),
onTap: () {},
),
Positioned(),
]
),
The problem is solved when I delete bottom: -170.0,
But I need it in the design

Ripple does not cover text

I figured I can draw ripple over an image by enclosing the image in Ink(decoration: BoxDecoration(image: ...)), but how can I do the same for Text?
This is supposed to be a card with an image on top and a title and some other information at the bottom:
#override
Widget build(BuildContext context) {
final theme = Theme.of(context);
final post = _postModel.post;
return Material(
color: theme.colorScheme.background,
child: InkWell(
onTap: () {},
splashColor: Colors.red,
child: Container(
padding: EdgeInsets.symmetric(horizontal: 10, vertical: 5),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
if (post.imageUri != null)
// This image IS covered by the ripple (what I need)
AspectRatio(
aspectRatio: 5 / 3,
child: Ink(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(3),
image: DecorationImage(
image: NetworkImage('https://picsum.photos/700'),
fit: BoxFit.cover,
),
),
),
),
// This must be underneath the ripple, but isn't.
Text(post.title, style: theme.textTheme.headline5),
Container(
padding: EdgeInsets.symmetric(horizontal: 0, vertical: 5),
color: Colors.transparent,
height: 60,
child: Row(
children: <Widget>[
// This is also covered by the ripple
Ink(
height: 35,
width: 35,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(3),
image: DecorationImage(
fit: BoxFit.cover,
image: NetworkImage('https://picsum.photos/100'),
),
),
),
SizedBox(width: 5),
// This must be underneath the ripple but isn't
Ink(
// decoration: Decoration,
child: Text(
post.author,
style: theme.textTheme.caption,
),
),
Spacer(),
],
),
),
],
),
),
),
);
}
When I press, the ripple covers both images as expected, however, I can't figure out how to make the ripple cover the text widgets as well. I tried wrapping the text in an Ink widget (the last one), but it doesn't work - the text is still displayed over the ripple.
Unpressed:
Pressed (the text is visible):

Cant added flutter onPress

I'm beginner to flutter , I tried to added my flutter Press navigation code to 'accountWidget' , but its cant be added on this anyone know how to do that correctly
Thanks
my code here
press: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return HomePage();
},
),
);
},
Account.dart
Widget _accountWidget() {
return Container(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
ListView.builder(
itemCount: accounts.length,
padding: EdgeInsets.only(left: 16, right: 16, top: 18, bottom: 29),
itemBuilder: (context, index) {
return Container(
height: 76,
margin: EdgeInsets.only(bottom: 13),
padding:
EdgeInsets.only(left: 24, top: 12, bottom: 12, right: 22),
decoration: BoxDecoration(
color: kWhiteColor,
borderRadius: BorderRadius.circular(15),
boxShadow: [
BoxShadow(
color: kTenBlackColor,
blurRadius: 10,
spreadRadius: 5,
offset: Offset(8.0, 8.0),
)
],
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Row(
children: <Widget>[
Container(
height: 57,
width: 57,
decoration: BoxDecoration(
shape: BoxShape.circle,
image: DecorationImage(
image: AssetImage(accounts[index].photo),
),
),
),
SizedBox(
width: 13,
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
padding: new EdgeInsets.only(top:15.0),
child: Center(
child: Text(
accounts[index].name,
style: GoogleFonts.inter(
fontSize: 16,
fontWeight: FontWeight.w700,
color: kBlackColor),
),
),
),
Text(
accounts[index].version,
style: GoogleFonts.inter(
fontSize: 14,
fontWeight: FontWeight.w400,
color: kGreyColor),
)
],
)
],
),
],
),
);
},
shrinkWrap: true,
controller: ScrollController(keepScrollOffset: false),
)
],
),
);
}
As far as I can see, you are missing a widget which has a onPressed or onTap property, none of your widgets is configured to be press-able. Easiest way to achieve this, is making use of the GestureDetector widget, which can listen to various kinds of gestures, including onTap. Just Wrap it around the part of your widget tree which should be press-able - syntax for this use case goes like:
GestureDetector(
/// This makes sure the whole area is clickable and not only the actual widgets inside
behavior: HitTestBehavior.translucent,
/// Your press function
onTap: press,
/// The rest of your widget tree
child: ...
)
There are quite some widgets which have interaction properties like onPressed on their own, like FlatButton or ListTile. I would recommend to take a look at the Flutter widget catalog where you can see different kind of existing widgets which solve common problems like touch events, input etc.

Flutter : How to disable drag down to close showModalBottomSheet

I want to disable drag down to close the showModalBottomSheet
I have already tried using enableDrag:false,
When i'm using enableDrag:false, is showing me below error
Below is my code
modal(BuildContext context) {
showModalBottomSheet(
context: context,
enableDrag:false,
isDismissible: false,
backgroundColor: Colors.transparent,
builder: (context) {
return Container(
width: MediaQuery.of(context).size.width,
child: Stack(
alignment: Alignment.topCenter,
children: <Widget>[
Container(
width: MediaQuery.of(context).size.width,
padding: EdgeInsets.only(top: 30),
child: Stack(
alignment: Alignment.topCenter,
children: <Widget>[
ClipPath(
clipper: OvalTopBorderClipper(),
child: Container(
width: MediaQuery.of(context).size.width,
padding: EdgeInsets.only(top: 80),
color: Colors.white,
height: 440,
child: Text("This is a modal bottom sheet !"),
),
),
],
),
),
Positioned(
top: 5,
child: Container(
width: 50.0,
height: 53.0,
child: Center(
child: Text(
"K",
style: TextStyle(
color: AppColors.textColor, fontSize: 20.0),
),
),
padding:
EdgeInsets.symmetric(horizontal: 10.0, vertical: 10.0),
decoration: BoxDecoration(
border:
Border.all(color: AppColors.textColor, width: 2)),
),
),
],
),
);
});
}
I have already check this post
Disable drag down to close showModalBottomSheet
If need more information please do let me know. Thanks in advance. Your efforts will be appreciated.
enableDrag is not available in showModalBottomSheet. I don't think it was ever available in stable channel. According to comments from the link at that time it was available in Master channel. But second answer from that link works well
builder: (context) => GestureDetector(
onVerticalDragDown: (_) {},
child: ...,
here is documentation to showModalBottomSheet . You can always tap into the showModalBottomSheet and customise it.. According to doc
BottomSheet, which becomes the parent of the widget returned by the function passed as the builder argument to showModalBottomSheet.
and BottomSheet has enableDrag parameter.
As of 2020-05-06 and flutter v1.17.1 enableDrag is available on showModalBottomSheet