Flutter keyboard overlapping issue not solved with resizeToAvoidBottomPadding - dart

Basically I have a login page where I first segement into 2 container with one covers 55% and 45% of the screen. Then on top of these 2 container I add one more container with top 40% of the screen size and in it I have one more container which hold my user name and password text field. So on the design wise I am ok.
Now the issue when the keyboard comes the password field is totally not visible. First I just had stack then I did google and some suggest to put the Scaffold and add this line resizeToAvoidBottomPadding: false, but seems does not work for me either too.
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomPadding: false,
body: Container(
child: Stack(
children: <Widget>[
// The containers in the background
new Column(
children: <Widget>[
new Container(
height: MediaQuery.of(context).size.height * .55,
//color: Colors.blue,
decoration: new BoxDecoration(
image: new DecorationImage(image: new AssetImage("lib/assets/cbg.png"), fit: BoxFit.cover,),
),
),
new Container(
height: MediaQuery.of(context).size.height * .45,
color: Colors.white,
)
],
),
// The card widget with top padding,
// incase if you wanted bottom padding to work,
// set the `alignment` of container to Alignment.bottomCenter
new Container(
alignment: Alignment.topCenter,
padding: new EdgeInsets.only(
top: MediaQuery.of(context).size.height * .40,
right: 20.0,
left: 20.0),
child: new Container(
height: MediaQuery.of(context).size.height * .45,
width: MediaQuery.of(context).size.width,
child: new Card(
color: Colors.white,
elevation: 4.0,
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 40.0),
child: Column(
children: <Widget>[
SizedBox(height: MediaQuery.of(context).size.height * .05),
new TextFormField(
decoration: new InputDecoration(
labelText: "Enter Email",
fillColor: Colors.white,
border: new OutlineInputBorder(
borderRadius: new BorderRadius.circular(10.0),
borderSide: new BorderSide(
color: Colors.blue
),
),
//fillColor: Colors.green
),
validator: (val) {
if(val.length==0) {
return "Email cannot be empty";
}else{
return null;
}
},
keyboardType: TextInputType.emailAddress,
style: new TextStyle(
fontFamily: "Poppins",
),
),
SizedBox(height: MediaQuery.of(context).size.height * .05),
new TextFormField(
decoration: new InputDecoration(
labelText: "Enter Password",
fillColor: Colors.white,
border: new OutlineInputBorder(
borderRadius: new BorderRadius.circular(10.0),
borderSide: new BorderSide(
),
),
//fillColor: Colors.green
),
validator: (val) {
if(val.length==0) {
return "Password cannot be empty";
}else{
return null;
}
},
keyboardType: TextInputType.emailAddress,
style: new TextStyle(
fontFamily: "Poppins",
),
),
],
),
)
),
),
),
new Container(
alignment: Alignment.topCenter,
padding: new EdgeInsets.only(
top: MediaQuery.of(context).size.height * .80,
right: 50.0,
left: 50.0),
child: new FlatButton(
color: Colors.red,
child: Text("Press Me"),
onPressed: () {},
),
),
new Container(
alignment: Alignment.topCenter,
padding: new EdgeInsets.only(
top: MediaQuery.of(context).size.height * .90,
right: 50.0,
left: 50.0),
child: new FlatButton(
color: Colors.red,
child: Text("Forgot Password ?"),
onPressed: () {},
),
)
],
)
)
);
}
}
After the changes the keyboard still appear a slight covering the textfield.
Can I achieve some

You should put all this inside a ListView, then when you open the keyboard the list will scroll up.

Related

How do I absolutely position a badge in a BottomNavigationBarItem

I am using BottomNavigationBarItem to display bottom navigation UI with icons and text. I would like to be able to add badges with numeric values on those. Here is my current attempt:
bottomNavigationBar:
new BottomNavigationBar(items: <BottomNavigationBarItem>[
new BottomNavigationBarItem(
icon: new Stack(
children: <Widget>[
const Icon(Icons.home),
new Positioned(
top: 0.0,
left: 0.0,
child: new Container(
decoration: new BoxDecoration(
borderRadius: new BorderRadius.circular(4.0),
color: Colors.red),
width: 16.0,
child: new Text(
"12",
style: const TextStyle(color: Colors.white),
),
))
],
),
title: new Text("Home")),
new BottomNavigationBarItem(
icon: const Icon(Icons.star), title: new Text("Star")),
],
type: BottomNavigationBarType.fixed),
However, the badge is positioned with the icon's bounding box, so it overlaps heavily with the icon:
What I would like, instead, is something like that:
Is it possible to achieve this using the BottomNavigationBarItem widget? If not, what would be a good workaround?
make sure that the badge position is right, and the overflowing children should be visible
icon: new Stack(
overflow: Overflow.visible,
children: <Widget>[
const Icon(Icons.home),
new Positioned(
top: -1.0,
right: -6.0,
child: new Container(
decoration: new BoxDecoration(
borderRadius: new BorderRadius.circular(4.0), color: Colors.red),
width: 16.0,
child: new Text(
"12",
style: const TextStyle(color: Colors.white),
),
))
],
),
If it is useful to anyone, I made one that works in the AppBar.
static Widget makeIconWithBadge(String badgeText, GestureTapCallback onTap) {
return Container(
padding: EdgeInsets.only(right: 16.0),
child: Center(
child: new Stack(
overflow: Overflow.visible,
children: <Widget>[
const Icon(Icons.inbox),
new Positioned(
top: -6.0,
right: -6.0,
child: Container(
padding: EdgeInsets.all(2.0),
decoration: new BoxDecoration(
borderRadius: new BorderRadius.circular(99.0),
color: Colors.white,
),
child: new Container(
padding: EdgeInsets.symmetric(vertical: 1.0, horizontal: 4.0),
decoration: new BoxDecoration(
borderRadius: new BorderRadius.circular(99.0),
color: Colors.red),
child: Center(
child: new Text(
"12",
textAlign: TextAlign.center,
style: TextStyle(color: Colors.white, fontSize: 12.0,),
),
),
),
),
),
Positioned.fill(
child: Material(
borderRadius: BorderRadius.all(Radius.circular(99.0)),
color: Colors.transparent,
child: InkWell(onTap: onTap),
),
)
],
),
),
);
}

BloC Pattern for Flutter 'provider.bloc' returns null

I'm trying to implement a BLoC pattern on a register_page but when i was trying to call the context, seems like the provider.bloc returns null. Tried some of the suggestions here stackoverflow but no luck. Anyone would like to tell me whats the issue on my code? See below:
bloc_provider.dart
class BlocProvider<T extends BlocBase> extends StatefulWidget {
final T bloc;
final Widget child;
static Type _typeOf<T>() => T;
BlocProvider({Key key, #required this.child, this.bloc}) : super(key: key);
#override
_BlocProviderState<T> createState() => _BlocProviderState();
static T of<T extends BlocBase>(BuildContext context) {
final type = _typeOf<BlocProvider<T>>();
BlocProvider<T> provider = context.ancestorWidgetOfExactType(type);
return provider.bloc;
}
}
register_page.dart
Widget _registerButton(BuildContext context) {
final UserBloc userBloc = BlocProvider.of<UserBloc>(context); // having an issue in this line
return Container(
height: 50,
width: MediaQuery.of(context).size.width / 1.1,
child: BlocProvider(
bloc: UserBloc(),
child: RaisedButton(
child: Container(
alignment: Alignment.center,
height: 50,
width: MediaQuery.of(context).size.width,
child: Text(
'register'.toUpperCase(),
style: TextStyle(
color: getColor(ColorList.WhiteCream, 1.0),
fontSize: 20,
),
),
),
onPressed: () {},
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(60),
side: BorderSide(
color: getColor(ColorList.WhiteCream, 1.0),
width: 2.0,
),
),
color: getColor(ColorList.DarkGreen, 1.0),
),
),
);
}
other part
#override
Widget build(BuildContext context) {
return BlocProvider(
bloc: UserBloc(),
child: Scaffold(
appBar: PreferredSize(
preferredSize: Size.fromHeight(50.0),
child: AppBar(
elevation: 0.0,
backgroundColor: getColor(ColorList.DarkGreen, 1.0),
),
),
body: Column(
children: <Widget>[
Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height / 6,
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [
getColor(ColorList.DarkGreen, 1.0),
getColor(ColorList.LightGreen, 1.0),
],
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
),
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(90),
),
),
child: Stack(
children: <Widget>[
Padding(
padding: EdgeInsets.only(left: 40.0, bottom: 15.0),
child: Container(
alignment: Alignment.center,
width: 100,
height: 100,
decoration: BoxDecoration(
shape: BoxShape.circle,
border: Border.all(
color: getColor(ColorList.WhiteCream, 1.0),
width: 2.0)),
margin: const EdgeInsets.only(top: 32.0),
padding: const EdgeInsets.all(3.0),
child: Container(
height: 70,
width: 70,
child: ClipOval(
child: Image.asset(
'assets/images/log-ayuda-black.png',
color: getColor(ColorList.WhiteCream, 1.0),
),
),
),
),
),
Align(
alignment: FractionalOffset.bottomRight,
child: Padding(
padding: EdgeInsets.only(
right: 32,
bottom: 15.0,
),
child: Text(
'Register'.toUpperCase(),
style: TextStyle(
fontFamily: 'OpenSans',
color: getColor(ColorList.WhiteCream, 1.0),
fontSize: 25,
fontWeight: FontWeight.bold),
),
),
),
],
),
),
SizedBox(
height: 10,
),
Container(
height: MediaQuery.of(context).size.height / 1.41,
width: MediaQuery.of(context).size.width,
child: SingleChildScrollView(
padding: EdgeInsets.only(top: 20.0),
physics: const ClampingScrollPhysics(),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
// username
_usernameTextField(context),
_paddingSpace(usernameHasError),
// password
_passwordTextField(context),
_paddingSpace(passwordHasError),
// email address
_emailAddressTextField(context),
_paddingSpace(emailAddressHasError),
// Contact Number
_contactNumberTextField(context),
_paddingSpace(contactNumberHasError),
// First name
_firstNameTextField(context),
_paddingSpace(firstNameHasError),
// middle name
_middleNameTextField(context),
_paddingSpace(false),
// last name
_lastNameTextField(context),
_paddingSpace(lastNameHasError),
// gender
_buildGenderRadioButton(context),
_paddingSpace(selectGenderHasError),
// birthdate
_buildDateTimePicker(context),
selectBirthDateHasError
? Padding(
padding: EdgeInsets.only(top: 10, bottom: 10),
child: Text(
'You must be 18 years old and above',
style: TextStyle(color: Colors.redAccent),
),
)
: _paddingSpace(false),
// register button
_registerButton(widget.context),
_paddingSpace(false),
].where(notNull).toList(),
),
),
),
],
),
),
);
}
It might be the issue here in my MaterialPageRoute function on Navigator.push. See my code below for navigation:
Container(
height: 60,
width: MediaQuery.of(context).size.width,
padding: const EdgeInsets.only(left: 16.0, right: 16.0),
child: FlatButton(
child: Text(
'Not yet a member? Sign up now!',
style: TextStyle(
fontFamily: 'OpenSans',
fontSize: 18.0,
color: getColor(ColorList.WhiteCream, 1.0),
fontWeight: FontWeight.bold,
),
),
highlightColor: Colors.transparent,
splashColor: Colors.transparent,
color: Colors.transparent,
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => RegisterPage(
context: context,
)));
},
),
),
I believed I'm on the right way of wrapping Scaffold with BlocProvider under the register_page.dart ... I don't know why it still returns null value.

How to position elements inside a ListView?

Good morning. I made this screen and it works like a charm on high resolutions. Problem is, I want to support lower resolutions like Nexus 4 (768x1280).
So when I run this on an emulator (Nexus 4 size) and I touch the input fields, the keyboard either: blocks the inputs, or moves the two buttons at the bottom and overlaps them on something else.
So, to solve it I wrapped the entire layout on a ListView(), but now the bottom buttons, which are wrapped on a Row(), just won't stay at the bottom.
This is my code without the ListView and working on high res, but not on low:
return Form(
Stack(
Center(
Column(
...
),
),
Align(
alignment: Alignment.bottomCenter,
child: Row(
...
),
),
),
);
This is how it looks with resizeToAvoidBottomPadding: false
And this is how it looks with the value set to true
Thanks, everyone.
Did you try to use SingleChildScrollView ?
It is a widget for making the page able to resize the height and as well scrolling , for the listview thats not what is the listview for , you should add listview when you get an unknown amount of data,
We don't normally use it to just adjust the view.
ok so i edited the code as in here and i can scroll normally after the keyboard pop up and the view is good and i can click on the button normally try it.
Widget formWidget(){
return new Scaffold(
// appBar: AppBar(
// // Here we take the value from the MyHomePage object that was created by
// // the App.build method, and use it to set our appbar title.
// title: Text(widget.title),
// ),
body:Column(
children: <Widget> [
Expanded(
child:SingleChildScrollView(
child: Form(
child:
// Stack(
// children: <Widget>[
// Center(
// child: SingleChildScrollView(
// child:
Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
children: [
Padding(
padding: (MediaQuery.of(context).size.height) > 600
? const EdgeInsets.only(top: 0.0)
: const EdgeInsets.only(top: 30.0),
child: Image(
image: AssetImage('assets/favIcon.png'),
width: 88.0,
height: 88.0,
),
),
Padding(
padding: const EdgeInsets.fromLTRB(0, 28.0, 0, 12.0),
child: Text(
'Delegados',
style: TextStyle(
fontFamily: 'Archia',
fontSize: 32.0,
),
),
),
Text(
'Introduce tus datos de acceso aquí.',
style: TextStyle(
color: Color(0xff83868F),
fontFamily: 'Brutal',
fontSize: 14.0,
),
),
Padding(
padding:
const EdgeInsets.fromLTRB(16.0, 26.0, 16.0, 12.0),
child: TextFormField(
decoration: InputDecoration(
labelText: 'Correo',
filled: true,
fillColor: Color(0xffF0F1F5),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8.0),
borderSide: BorderSide(
width: 0,
style: BorderStyle.none,
),
),
),
style: TextStyle(
fontFamily: 'Brutal',
color: Color(0xff1A1B1F),
),
controller: TextEditingController() ,
textInputAction: TextInputAction.next,
),
),
Padding(
padding: const EdgeInsets.fromLTRB(16.0, 0, 16.0, 12.0),
child: TextFormField(
keyboardType: TextInputType.emailAddress,
decoration: InputDecoration(
labelText: 'Contraseña',
filled: true,
fillColor: Color(0xffF0F1F5),
suffixIcon: Icon(Icons.remove_red_eye),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8.0),
borderSide: BorderSide(
width: 0,
style: BorderStyle.none,
),
),
),
style: TextStyle(
fontFamily: 'Brutal',
color: Color(0xff1A1B1F),
),
controller: TextEditingController() ,
//focusNode:FocusNode(),
obscureText: true,
),
),
Align(
alignment: Alignment.centerRight,
child: Padding(
padding: const EdgeInsets.fromLTRB(0, 0, 0, 26.0),
child: CupertinoButton(
onPressed: () {},
child: Text(
'Olvidé mi Contraseña',
style: TextStyle(
color: Color(0xff565A66),
fontFamily: 'Brutal',
fontSize: 14.0,
),
),
),
),
),
Padding(
padding: const EdgeInsets.fromLTRB(16.0, 0, 16.0, 0),
child: ButtonTheme(
minWidth: double.infinity,
child: InkWell(
// onTap: state is! LoginLoading
// ? _onLoginButtonPressed
// : null,
child: Container(
height: 48.0,
width: 500.0,
decoration: BoxDecoration(
color: Color(0xff00CC36),
borderRadius: BorderRadius.circular(8.0),
),
child: Align(
alignment: Alignment.center,
child: Container(
child:
// state is LoginLoading
// ? CircularProgressIndicator():
Text(
'INGRESAR AHORA ›',
style: TextStyle(
color: Colors.white,
fontFamily: 'Brutal',
fontSize: 14.0,
),
),
)),
),
),
),
),
],
),
// ),
)
,
// aqui va <<<<<<<<<<<<
// ],
// ),
)
),
Align(
alignment: Alignment.bottomCenter,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
CupertinoButton(
onPressed: () {},
child: Text(
'¿No tienes cuenta?',
style: TextStyle(
color: Color(0xff83868F),
fontFamily: 'Brutal',
fontSize: 14.0,
),
),
),
InkWell(
onTap: null,
child: Container(
height: 32.0,
width: 112.0,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(6.0),
border: Border.all(
color: Color(0xffD7D9E0),
width: 1.0,
),
),
child: Align(
alignment: Alignment.center,
child: Text(
'CONTACTANOS',
style: TextStyle(
color: Color(0xff565A66),
fontFamily: 'Brutal',
fontSize: 11.0),
),
),
),
),
],
),
),
]
)
,
// )
);
}
In your Scaffold can you try this.
Scaffold(
resizeToAvoidBottomInset: false,
...
);

Custom AppBar Flutter

Im trying to achieve something like the following,
I'm very new to flutter so I couldn't figure it out.
I need a custom AppBar with drawer and actions but arranged like the image.
I tried a StackView in the title widget
appBar: AppBar(
title: Stack(
children: <Widget>[
Container(
width: double.infinity,
color: CustomColors.accentColor,
),
Text(
'Title',
style: TextStyle(fontSize: 22.0, color: CustomColors.primaryDark),
),
],
),
),
But I get something like this
Can someone help me out? Thank you.
As I mentioned in the comment , you can create a Custom widget like your Image attached, there are many ways to do it, this is just an example :
class CustomBarWidget extends StatelessWidget {
GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey();
#override
Widget build(BuildContext context) {
return Scaffold(
key: _scaffoldKey,
body: Container(
height: 160.0,
child: Stack(
children: <Widget>[
Container(
color: Colors.red,
width: MediaQuery.of(context).size.width,
height: 100.0,
child: Center(
child: Text(
"Home",
style: TextStyle(color: Colors.white, fontSize: 18.0),
),
),
),
Positioned(
top: 80.0,
left: 0.0,
right: 0.0,
child: Container(
padding: EdgeInsets.symmetric(horizontal: 20.0),
child: DecoratedBox(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(1.0),
border: Border.all(
color: Colors.grey.withOpacity(0.5), width: 1.0),
color: Colors.white),
child: Row(
children: [
IconButton(
icon: Icon(
Icons.menu,
color: Colors.red,
),
onPressed: () {
print("your menu action here");
_scaffoldKey.currentState.openDrawer();
},
),
Expanded(
child: TextField(
decoration: InputDecoration(
hintText: "Search",
),
),
),
IconButton(
icon: Icon(
Icons.search,
color: Colors.red,
),
onPressed: () {
print("your menu action here");
},
),
IconButton(
icon: Icon(
Icons.notifications,
color: Colors.red,
),
onPressed: () {
print("your menu action here");
},
),
],
),
),
),
)
],
),
),
);
}
}

Flutter: Responsive design with a fixed height

I am creating a section where to administer the club.
The problem that I have is related to the design.
I try to indicate that it has the same vertical height on the horizontal side, but I still do not understand why the bots are not adapted according to their size ratio.
I have been thinking about how to do it for more than 4 hours and I have not been able to do it, I hope someone can help me.
My goal: That the design of the vertical side be the same as the horizontal
Here I show you my code
return Scaffold(
key: _scaffoldKey,
appBar: new AppBar(
title: new Text("LINE UP"),
centerTitle: true,
backgroundColor: Colors.lightBlue[500],
),
body: LayoutBuilder(
builder: (context, constraints) {
return new Container(
color: Colors.blue[800],
child: new Stack(
children: <Widget>[
new Positioned.fill(
child: new SingleChildScrollView(
scrollDirection: Axis.vertical,
child: new Column(
children: <Widget>[
new Container(
decoration: new BoxDecoration(
image: new DecorationImage(
image: new AssetImage(imgStadium),
fit: BoxFit.fitWidth
),
),
height: 411.4,
width: constraints.maxWidth,
child: new Stack(
children: <Widget>[
// BOT1
Positioned(
top: 120.0,
left: 168.0,
child: new GestureDetector(
child: new Column(
children: <Widget>[
new Container(
decoration: BoxDecoration(
image: new DecorationImage(
image: new AssetImage(
imgPlayer1),
fit: BoxFit.fill,
),
),
height: 40.0,
width: 30.0,
),
new Container(
width: 70.0,
decoration: BoxDecoration(
shape: BoxShape
.rectangle,
color: Colors.black
.withOpacity(0.5),
),
child: new Text(
"${textPlayer1}",
style: new TextStyle(
color: Colors
.white,
fontWeight: FontWeight
.bold,
fontSize: 12.0),
textAlign: TextAlign
.center,),
)
],
),
onTap: () {
setState(() {
_showModalSheet(1);
});
},
)
),
//BOT2
Positioned(
top: topPositionPlayer2,
left: leftPositionPlayer2,
child: new GestureDetector(
child: new Column(
children: <Widget>[
new Container(
decoration: BoxDecoration(
image: new DecorationImage(
image: new AssetImage(
imgPlayer2),
fit: BoxFit.fill,
),
),
height: 40.0,
width: 30.0,
),
new Container(
width: 70.0,
decoration: BoxDecoration(
shape: BoxShape
.rectangle,
color: Colors.black
.withOpacity(0.5),
),
child: new Text(
"${textPlayer2}",
style: new TextStyle(
color: Colors
.white,
fontWeight: FontWeight
.bold,
fontSize: 12.0),
textAlign: TextAlign
.center,),
)
],
),
onTap: () {
setState(() {
_showModalSheet(2);
});
},
)
),
//BOT3
Positioned(
top: topPositionPlayer3,
left: leftPositionPlayer3,
child: new GestureDetector(
child: new Column(
children: <Widget>[
new Container(
decoration: BoxDecoration(
image: new DecorationImage(
image: new AssetImage(
imgPlayer3),
fit: BoxFit.fill,
),
),
height: 40.0,
width: 30.0,
),
new Container(
width: 70.0,
decoration: BoxDecoration(
shape: BoxShape
.rectangle,
color: Colors.black
.withOpacity(0.5),
),
child: new Text(
"${textPlayer3}",
style: new TextStyle(
color: Colors
.white,
fontWeight: FontWeight
.bold,
fontSize: 12.0),
textAlign: TextAlign
.center,),
)
],
),
onTap: () {
setState(() {
_showModalSheet(3);
});
},
)
),
],
)
)
]
)
)
)
]
)
);
}
)
);
Here I show you some screenshots.
Vertical mode - Perfect.
Horizontal mode - I move it and the background image does not adapt.
You are providing all height and width related to vertical mode so their is problem in horizontal view.
I think that you have to try MediaQuery.of(context).size.width and get width And set whatever ratio you want to set for padding or to get player image to center so it works for both horizontal and vertical to.
Generally, at the moment you're indenting halfway across the screen, I would refactor that to a separate method, or even a separate Widget class.

Resources