Related
I am building a flutter project on both app and web. I am having a couple of issues with the login page. First my column widget fills the whole width on Flutter web but I want it to be more central. Secondly I am trying to center align the Don't have an account? Sign up button which has found itself aligning to the left. Please may someone assist. Here's my code and a couple of screenshots
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.black,
body: Center(
child: Card(
child: Form(
key: _formKey,
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: TextFormField(
validator: (value) =>
value!.isEmpty ? 'Email cannot be empty' : null,
onSaved: (value) => _email = value!,
decoration: const InputDecoration(
filled: true,
fillColor: Colors.white,
labelText: 'Email',
hintText: 'Email',
border: OutlineInputBorder(),
),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextFormField(
validator: (value) =>
value!.isEmpty ? 'Password cannot be empty' : null,
onSaved: (value) => _password = value!,
decoration: const InputDecoration(
filled: true,
fillColor: Colors.white,
labelText: 'Password',
hintText: 'Password',
border: OutlineInputBorder(),
),
obscureText: true,
),
),
Padding(
padding: const EdgeInsets.all(0),
child: TextButton(
onPressed: () {
Navigator.pushNamed(context, '/resetpassword');
},
child: const Text('Forgot Password?'),
style: TextButton.styleFrom(
primary: Colors.black,
),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: ElevatedButton(
onPressed: validateAndSubmit,
child: const Text('Login'),
style: ElevatedButton.styleFrom(
primary: Colors.black,
onSurface: Colors.black,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(15.0)),
),
),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: [
const Text('Dont have an account?'),
TextButton(
onPressed: () {
Navigator.pushNamed(context, '/signup');
},
child: const Text(
'Signup',
style: TextStyle(fontWeight: FontWeight.bold),
),
style: TextButton.styleFrom(
primary: Colors.black,
),
),
],
),
),
],
),
),
),
), // This trailing comma makes auto-formatting nicer for build methods.
);
To center the 'Dont have an account?' text and 'Signup' TextButton,
use mainAxisAlignment in Row.
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,//<-- this
children: [
const Text('Dont have an account?'),
TextButton(
onPressed: () {
Navigator.pushNamed(context, '/signup');
},
child: const Text(
'Signup',
style: TextStyle(fontWeight: FontWeight.bold),
),
style: TextButton.styleFrom(
primary: Colors.black,
),
),
],
),
),
To responsive web and app,
I use this method,
void main() async {
runApp(
const ResponsiveLayout(),
);
}
In my ResponsiveLayout const webScreenSize = 600;
Widget build(BuildContext context) {
return LayoutBuilder(
builder: (context, constraints) {
if (constraints.maxWidth > webScreenSize) {
//webscreen
return widget.webScreenLayout; // <-- send user Web screen
} else {
//mobile screen
return widget.mobileScreenLayout; // <-- send user mobile screen
}
},
);
}
Read more about LayoutBuilder -
https://api.flutter.dev/flutter/widgets/LayoutBuilder-class.html
I am developing a social media app with flutter.
I want to create a screen where users can post new posts, the user will select multi images and videos (10 max), specify the location and write a post caption.
I want to know how to move this bar that contains my action buttons upwards whenever the keyboard is triggered.
besides, I want to add the selected images at the bottom also
so how to do that?
here is the UI I want to approach.
this is what I've done so far
here is the code of the new_post_screen.dart file
import 'package:flutter/material.dart';
import '../widgets/profile_avatar.dart';
class NewPostScreen extends StatefulWidget {
const NewPostScreen({super.key});
static const routeName = '/new-post';
#override
State<NewPostScreen> createState() => _NewPostScreenState();
}
class _NewPostScreenState extends State<NewPostScreen> {
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
title: const Text('New Post'),
leading: TextButton(
child: Text(
'Cancel',
style: Theme.of(context).textTheme.headline6!.copyWith(
color: Theme.of(context).primaryColor,
),
),
onPressed: () {
Navigator.of(context).pop();
},
),
leadingWidth: 80,
actions: [
Container(
margin: const EdgeInsets.all(10),
child: TextButton(
onPressed: () {},
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all<Color>(
Theme.of(context).primaryColor)),
child: const Text(
'Post',
style: TextStyle(color: Colors.white),
),
),
)
],
),
body: SingleChildScrollView(
child: Column(
children: const [
_PostHeader(),
Card(
elevation: 0,
child: Padding(
padding: EdgeInsets.all(8.0),
child: TextField(
maxLines: null,
autofocus: true,
decoration:
InputDecoration.collapsed(hintText: "Type a memory..."),
),
)),
],
),
),
floatingActionButton: Container(
width: double.infinity,
decoration: BoxDecoration(
color: Colors.grey[200],
),
child: Row(mainAxisAlignment: MainAxisAlignment.end, children: [
IconButton(onPressed: () {}, icon: const Icon(Icons.image)),
IconButton(onPressed: () {}, icon: const Icon(Icons.location_on))
]),
),
);
}
}
class _PostHeader extends StatelessWidget {
const _PostHeader({
Key? key,
}) : super(key: key);
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 15),
child: Row(
children: [
const ProfileAvatar(
imageUrl: 'https://picsum.photos/200',
),
const SizedBox(width: 10),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Username', style: Theme.of(context).textTheme.headline6),
const SizedBox(height: 5),
SizedBox(
width: MediaQuery.of(context).size.width * 0.4,
child: DropdownButtonFormField(
decoration: InputDecoration(
isDense: true,
contentPadding: const EdgeInsets.symmetric(
horizontal: 10, vertical: 2),
border: OutlineInputBorder(
borderSide: BorderSide(
width: 1, color: Theme.of(context).primaryColor),
borderRadius:
const BorderRadius.all(Radius.circular(8)),
),
filled: true,
fillColor: Theme.of(context).backgroundColor,
),
icon: const Icon(
Icons.keyboard_arrow_down,
size: 15,
color: Colors.white,
),
items: [
DropdownMenuItem(
value: 'Public',
child: Row(
children: [
const Icon(
Icons.public,
size: 15,
color: Colors.white,
),
const SizedBox(width: 5),
Text('Public',
style: Theme.of(context)
.textTheme
.bodyText1!
.copyWith(color: Colors.white)),
],
),
),
DropdownMenuItem(
value: 'Private',
child: Row(
children: [
const Icon(
Icons.lock,
size: 15,
color: Colors.white,
),
const SizedBox(width: 5),
Text('Private',
style: Theme.of(context)
.textTheme
.bodyText1!
.copyWith(color: Colors.white)),
],
),
),
],
dropdownColor: Theme.of(context).primaryColor,
value: 'Public',
onChanged: (value) {
print(value);
}),
),
],
),
],
),
);
}
}
I tried to put the action buttons bar in the floating action button, but it is not full width, and I don't know how to place the images on top of it.
When the keyboard appears the fab is placed in the middle of the screen instead of staying on board the keyboard
There is a lot of post on this subject on the web, but I cannot find the adequate solution to mine.
Here is the code.
Widget build(BuildContext context) {
final isKeyboard = MediaQuery.of(context).viewInsets.bottom != 0;
return Scaffold(
backgroundColor: backgroundColor,
appBar: AppBar(
iconTheme: const IconThemeData(color: Colors.black),
backgroundColor: Colors.transparent,
//****************************** EDITBUTTON ***************************** */
elevation: 0,
actions: [
IconButton(
onPressed: () async {
await Databahelper.instance.deleteNote(widget.note!.id!);
Navigator.of(context).push(
MaterialPageRoute(builder: (_) => const StickyNote()));
},
icon: const Icon(Icons.delete)),
//*************************** DELETE_BUTTON ***************************** */
],
),
body: Padding(
padding: const EdgeInsets.all(10.0),
child: Column(
children: [
const SizedBox(height: 8),
TextField(
maxLines: 1,
controller: titleController,
decoration: const InputDecoration(
label: Text(
'Title',
style: TextStyle(fontSize: 20),
),
),
),
const SizedBox(
height: 30,
),
Expanded(
child: TextField(
keyboardType: TextInputType.multiline,
controller: descController,
maxLines: null,
decoration: const InputDecoration(
border: InputBorder.none,
contentPadding: EdgeInsets.all(10),
hintText: "Enter Your Text...",
hintStyle: TextStyle(
fontSize: 12,
color: Colors.purple,
fontStyle: FontStyle.italic,
),
),
),
)
],
),
),
//---------------------------bottomNavigation --------------------------------------
bottomNavigationBar: Visibility(
visible: !isKeyboard,
child: BottomAppBar(
elevation: 4,
color: backgroundColor,
child: SizedBox(
height: 50,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
IconButton(
onPressed: () {},
icon: const Icon(Icons.add_box_outlined)),
const Text('July 2050'),
IconButton(
onPressed: () {}, icon: const Icon(Icons.more_vert)),
],
),
),
),
),
floatingActionButton: FloatingActionButton.extended(
onPressed: () {
setState(() {
title = titleController.text;
description = descController.text;
});
NotedB notelocal = NotedB(title: title, description: description);
addNote(notelocal);
Navigator.push(
context, MaterialPageRoute(builder: (_) => const StickyNote()));
},
label: const Text('Save note'),
icon: const Icon(Icons.note_add_outlined),
));
}
screenshot
I have a program written in Flutter and I would like to center the form in the middle of the screen but I can't get it.
I tried to use Align and I don't think I am using it correctly!
Someone can help me? Thanks
class _Defini extends State<Definicoes> {
GlobalKey<FormState> _formkey = GlobalKey<FormState>();
#override
Widget build(BuildContext context) {
return Scaffold(
bottomNavigationBar:
...
body: Container(
color: Colors.amber.withOpacity(0.80),
child: Align(
alignment: Alignment(0, 0),
child: Form(
key: _formkey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Container(
width: 300,
height: 300,
child: TextFormField(
keyboardType: TextInputType.number,
decoration: InputDecoration(
labelText: "RaspberryPi",
labelStyle: TextStyle(color: Colors.white)),
textAlign: TextAlign.center,
style: TextStyle(color: Colors.white, fontSize: 25.0),
validator: (value) {
if (value.isEmpty){
return "Insira";
}
},
),
),
Container(
decoration: BoxDecoration(
boxShadow: [
BoxShadow(
...
),
],
),
child: FlatButton(
color: Colors.white,
textColor: Colors.white,
disabledColor: Colors.grey,
disabledTextColor: Colors.black,
padding: EdgeInsets.all(8.0),
splashColor: Colors.blueAccent,
onPressed: () {
if(_formkey.currentState.validate()){
}
},
child: Text(
"Ligar",
),
),
),
],
),
),
),
),
);
}
}
Align is used if you have only one child.
To make the Form be at the center, set the mainAxisAlignment property of your column to MainAxisAlignment.center
Check the code below:
class _Defini extends State<Definicoes> {
GlobalKey<FormState> _formkey = GlobalKey<FormState>();
#override
Widget build(BuildContext context) {
return Scaffold(
bottomNavigationBar:
...
body: Container(
color: Colors.amber.withOpacity(0.80),
child: Form(
key: _formkey,
child: Column(
// set the mainAxisAlignment property here
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Container(
width: 300,
height: 300,
child: TextFormField(
keyboardType: TextInputType.number,
decoration: InputDecoration(
labelText: "RaspberryPi",
labelStyle: TextStyle(color: Colors.white)),
textAlign: TextAlign.center,
style: TextStyle(color: Colors.white, fontSize: 25.0),
validator: (value) {
if (value.isEmpty){
return "Insira";
}
},
),
),
Container(
decoration: BoxDecoration(
boxShadow: [
BoxShadow(
...
),
],
),
child: FlatButton(
color: Colors.white,
textColor: Colors.white,
disabledColor: Colors.grey,
disabledTextColor: Colors.black,
padding: EdgeInsets.all(8.0),
splashColor: Colors.blueAccent,
onPressed: () {
if(_formkey.currentState.validate()){
}
},
child: Text(
"Ligar",
),
),
),
],
),
),
),
);
}
}
Attached the image of my desired output I need to create an Add Card form page , where there are 2 tabbed appbars. One is Debit Card and other is Credit Card. I need to get the details , so I need to include a form , with a next button at the bottom. The whole form should be overlapped above the appbar. I have attached my desired output screen and my output. Please help me.
import 'package:flutter/material.dart';
import 'package:rewahub/Addcard/form.dart';
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
TextStyle style = TextStyle(fontFamily: 'Montserrat', fontSize: 20.0);
#override
Widget build(BuildContext context) {
final emailField = TextFormField(
//obscureText: true,
style: style,
decoration: InputDecoration(
contentPadding: EdgeInsets.fromLTRB(20.0, 0, 0, 10.0),
labelText: "Card Number",
hintText: 'xxxx xxxx xxxx xxxx',
),
);
final Exp_Date = TextFormField(
obscureText: true,
style: style,
decoration: InputDecoration(
contentPadding: EdgeInsets.fromLTRB(20.0,0,0,10.0),
labelText: "Exp Date",
hintText: "MM/YY",
),
);
final name = TextFormField(
obscureText: true,
style: style,
decoration: InputDecoration(
contentPadding: EdgeInsets.fromLTRB(20.0,0,0,10.0),
labelText: "Name",
hintText: "Name of the card holder",
),
);
final CVV = TextFormField(
obscureText: true,
style: style,
decoration: InputDecoration(
contentPadding: EdgeInsets.fromLTRB(20.0,0,0,10.0),
labelText: "CVV",
hintText: "XXXX",
),
);
final text1=Text("Prototype");
final nextButon = Material(
elevation: 5.0,
borderRadius: BorderRadius.circular(15.0),
color: Color(0XFFab2785),
child: MaterialButton(
minWidth: MediaQuery.of(context).size.width,
padding: EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 15.0),
onPressed: () {},
child: Text("NEXT",
textAlign: TextAlign.center,
style: style.copyWith(
color: Colors.white, fontWeight: FontWeight.bold)),
),
);
return Scaffold(
appBar:PreferredSize(
preferredSize: Size.fromHeight(240.0),
child: new AppBar(
centerTitle: true,
title: Column(children: [
Text(
"rewahub",
),
GestureDetector(
child: Text('PAYMENT METHODS'),
onTap: () {
print("tapped subtitle");
},
)
]),
backgroundColor: Color.fromRGBO(189, 78, 97, 1),
), ),
body: SingleChildScrollView(
child: Center(
child: Container(
color: Colors.white,
child: Padding(
padding: const EdgeInsets.all(40.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
SizedBox(height: 15.0),
emailField,
SizedBox(height: 15.0),
Exp_Date,
SizedBox(height: 15.0),
name,
SizedBox(height: 15.0),
CVV,
SizedBox(height: 15.0,),
text1,
SizedBox(height: 15.0,),
nextButon,
],
),
),
),
),
)
);
}
}
I have made some changes in your code please check below
import 'package:flutter/material.dart';
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
TextStyle style = TextStyle(fontFamily: 'Montserrat', fontSize: 20.0);
int selectedTab = 0;
Widget emailField() {
return TextFormField(
//obscureText: true,
style: style,
decoration: InputDecoration(
contentPadding: EdgeInsets.fromLTRB(20.0, 0, 0, 10.0),
labelText: "Card Number",
hintText: 'xxxx xxxx xxxx xxxx',
),
);
}
Widget Exp_Date() {
return TextFormField(
obscureText: true,
style: style,
decoration: InputDecoration(
contentPadding: EdgeInsets.fromLTRB(20.0, 0, 0, 10.0),
labelText: "Exp Date",
hintText: "MM/YY",
),
);
}
Widget name() {
return TextFormField(
obscureText: true,
style: style,
decoration: InputDecoration(
contentPadding: EdgeInsets.fromLTRB(20.0, 0, 0, 10.0),
labelText: "Name",
hintText: "Name of the card holder",
),
);
}
Widget CVV() {
return TextFormField(
obscureText: true,
style: style,
decoration: InputDecoration(
contentPadding: EdgeInsets.fromLTRB(20.0, 0, 0, 10.0),
labelText: "CVV",
hintText: "XXXX",
),
);
}
final text1 = Text("Prototype");
Widget nextButon() {
return Material(
elevation: 5.0,
borderRadius: BorderRadius.circular(15.0),
color: Color(0XFFab2785),
child: MaterialButton(
minWidth: MediaQuery.of(context).size.width,
padding: EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 15.0),
onPressed: () {},
child: Text(
"NEXT",
textAlign: TextAlign.center,
style: style.copyWith(
color: Colors.white,
fontWeight: FontWeight.bold,
),
),
),
);
}
#override
Widget build(BuildContext context) {
return DefaultTabController(
length: 2,
child: Scaffold(
body: Stack(
children: <Widget>[
Container(
height: 240.0,
color: Color.fromRGBO(189, 78, 97, 1),
),
Column(
children: <Widget>[
AppBar(
elevation: 0,
centerTitle: true,
title: GestureDetector(
child: Text('PAYMENT METHODS'),
onTap: () {
print("tapped subtitle");
},
),
backgroundColor: Color.fromRGBO(189, 78, 97, 1),
),
SizedBox(
height: 20,
),
TabBar(
labelStyle: Theme.of(context).textTheme.body2,
indicator: UnderlineTabIndicator(
borderSide: BorderSide(width: 2, color: Colors.white),
insets: EdgeInsets.symmetric(
horizontal: 0,
),
),
onTap: (int position) {
setState(() {
selectedTab = position;
});
},
tabs: [
Tab(
child: new Text(
"Credit Card",
style: Theme.of(context)
.textTheme
.body1
.apply(color: Colors.white),
),
),
Tab(
child: new Text(
"Debit Card",
style: Theme.of(context)
.textTheme
.body1
.apply(color: Colors.white),
),
),
],
),
selectedTab == 0 ? creditCard() : debitCard(),
],
),
],
),
),
);
}
Widget creditCard() {
return SingleChildScrollView(
child: Container(
margin: EdgeInsets.all(40),
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0),
),
child: Center(
child: Container(
color: Colors.white,
child: Padding(
padding: const EdgeInsets.all(40.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
SizedBox(height: 15.0),
emailField(),
SizedBox(height: 15.0),
Exp_Date(),
SizedBox(height: 15.0),
name(),
SizedBox(height: 15.0),
CVV(),
SizedBox(height: 15.0),
text1,
SizedBox(height: 15.0),
nextButon(),
],
),
),
),
),
),
),
);
}
Widget debitCard() {
return SingleChildScrollView(
child: Container(
margin: EdgeInsets.all(40),
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0),
),
child: Center(
child: Container(
color: Colors.white,
child: Padding(
padding: const EdgeInsets.all(40.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
SizedBox(height: 15.0),
emailField(),
SizedBox(height: 15.0),
Exp_Date(),
SizedBox(height: 15.0),
name(),
SizedBox(height: 15.0),
CVV(),
SizedBox(height: 15.0),
text1,
SizedBox(height: 15.0),
nextButon(),
],
),
),
),
),
),
),
);
}
}