How to horizontally center a Text in flutter? - dart

I’m trying to horizontally center a text. Please check the below code.
import 'package:flutter/material.dart';
class LoginPage extends StatelessWidget {
#override
Widget build(BuildContext context) {
// TODO: implement build
return Container(
color: Colors.black,
child: Row(
children: <Widget>[
Column(
children: <Widget>[_buildTitle()],
),
],
));
}
Widget _buildTitle() {
return
Center(child: Container(
margin: EdgeInsets.only(top: 100),
child: Column(
children: <Widget>[
Text(
"something.xyz",
style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold, fontSize: 25,),
textAlign: TextAlign.center,
),
],
),
),);
}
}
This did not center horizontally, instead gave the following output. The margins etc is fine.
How can I fix this?

try this
import 'package:flutter/material.dart';
void main() => runApp(MaterialApp(home: LoginPage()));
class LoginPage extends StatelessWidget {
#override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
body: Container(
color: Colors.black,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[_buildTitle()],
),
],
)),
);
}
Widget _buildTitle() {
return Center(
child: Container(
margin: EdgeInsets.only(top: 100),
child: Column(
children: <Widget>[
Text(
"something.xyz",
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 25,
),
// textAlign: TextAlign.center,
),
],
),
),
);
}
}

You can also solve it with a Container and TextAlign:
Container(
width: double.infinity,
child: Text(
'something.xyz',
textAlign: TextAlign.center,
),
)
In this case, the container takes up the entire width with double.infinity. The text adapts to the container and can be moved to the middle of the screen with TextAlign.center.

more simple way:
child: Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('Sunday', style: TextStyle(fontSize: 20),),
],
),
), //Center

set
child: Center(
child: Text(
"Hello World",
textAlign: TextAlign.center,
),
),
in program

I added my own widget for this use case which is much shorter than the row solution:
import 'package:flutter/material.dart';
class CenterHorizontal extends StatelessWidget {
CenterHorizontal(this.child);
final Widget child;
#override
Widget build(BuildContext context) =>
Row(mainAxisAlignment: MainAxisAlignment.center,children: [child]);
}
the result is this:
CenterHorizontal(Text('this is horizontal centered'))

Widget textSection = Container(
child: Text(
'This can be several lines centered in the child of a container Widget.',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 15.0,
color: Colors.white,
),
),
);

If I understand, you just want to center horizontally the title, not the other elements that may come after I suppose.
Take a look at the code below:
import 'package:flutter/material.dart';
class LoginPage extends StatelessWidget {
#override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.blueAccent,
title: Text("DEMO"),
),
body: Container(
color: Colors.black,
child: Column(
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[_buildTitle()],
),
Row(
children: <Widget>[
// add other elements that you don't to center horizontally
Text(
"other elements here",
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 25,
),
),
],
),
],
)));
}
Widget _buildTitle() {
return Container(
margin: EdgeInsets.only(top: 100),
child: Text(
"something.xyz",
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 25,
),
),
);
}
}
The result that gives: here

Container(
width: double.infinity,
child: const Text(
"Hello World!",
textAlign: TextAlign.center,
),
);

Flutter now recommends SizedBox for white space
SizedBox(
width: double.infinity,
child: Text('Hello World',
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.White,
fontSize: 16.0,
fontWeight: FontWeight.normal))),

Related

Decide which type to construct during runtime

I am trying to get more into Flutter.
I have a button class that either builds a FlatButton or an OutlineButton depending on a parameter
import 'package:flutter/material.dart';
class Button extends StatelessWidget {
final String text;
final VoidCallback onPressed;
final Color backgroundColor;
final Color textColor;
final bool isOutline;
Button(
{#required this.text,
#required this.onPressed,
this.backgroundColor = Colors.deepOrange,
this.textColor = Colors.white,
this.isOutline = false});
#override
Widget build(BuildContext context) {
return this.isOutline
? _buildOutlineButton(context)
: _buildFlatButton(context);
}
FlatButton _buildFlatButton(BuildContext context) {
return FlatButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30.0),
),
color: this.backgroundColor,
onPressed: this.onPressed,
child: Container(
padding: const EdgeInsets.symmetric(
vertical: 20.0,
horizontal: 20.0,
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Expanded(
child: Text(
this.text,
textAlign: TextAlign.center,
style:
TextStyle(color: this.textColor, fontWeight: FontWeight.bold),
),
),
],
),
),
);
}
OutlineButton _buildOutlineButton(BuildContext context) {
return OutlineButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30.0),
),
color: this.backgroundColor,
onPressed: this.onPressed,
child: Container(
padding: const EdgeInsets.symmetric(
vertical: 20.0,
horizontal: 20.0,
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Expanded(
child: Text(
this.text,
textAlign: TextAlign.center,
style:
TextStyle(color: this.textColor, fontWeight: FontWeight.bold),
),
),
],
),
),
);
}
}
As you can see, both _build*Button functions look similar. Is there a way to simply the code? Something like that (pseudo-code ahead):
final type = this.isOutline ? OutlineButton : FlatButton;
return type(shape: ..., color: ..., ...);
You can share much of the common code like this:
MaterialButton _buildButton(bool flat, BuildContext context) {
Container container = Container(
padding: const EdgeInsets.symmetric(
vertical: 20.0,
horizontal: 20.0,
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Expanded(
child: Text(
text,
textAlign: TextAlign.center,
style: TextStyle(color: textColor, fontWeight: FontWeight.bold),
),
),
],
),
);
RoundedRectangleBorder border = RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30.0),
);
return flat
? FlatButton(
shape: border,
color: backgroundColor,
onPressed: onPressed,
child: container,
)
: RaisedButton(
shape: border,
color: backgroundColor,
onPressed: onPressed,
child: container,
);
}

Is there a way i can use my refresh indicator to refresh a fututre builder after an error snapshot

I'm fetching data from Newsapi.org, i need to be able to reload the futurebuilder() after a snapshot error, i'm very new to flutter so this might sound strange.
I've already been able to fetch my data, and also tried putting the call back into the
if(snapshot.hasError) {}
but i just cant't get it to work
Widget build(BuildContext context) {
var refreshIndicator = RefreshIndicator(
key: refreshKey,
child: FutureBuilder<List<Source>>(
future: list_sources,
builder: (context, snapshot) {
if (snapshot.hasError) {
return Text(
'An error occured, check your internet connection and try again');
}
if (snapshot.hasData) {
if (snapshot.data != null) {
List<Source> sources = snapshot.data;
return new ListView(
children: sources
.map((source) => GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
ArticleScreen(source: source)));
},
child: Card(
elevation: 1.0,
color: Colors.white,
margin: const EdgeInsets.symmetric(
vertical: 8.0, horizontal: 14.0),
child: Row(
crossAxisAlignment:
CrossAxisAlignment.start,
children: <Widget>[
Container(
margin: const EdgeInsets.symmetric(
vertical: 20.0, horizontal: 4.0),
width: 100.0,
height: 140.0,
child: Image.asset(
"lib/images/newspaper 2.png"),
),
Expanded(
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: <Widget>[
Row(
children: <Widget>[
Expanded(
child: Container(
margin:
const EdgeInsets.only(
top: 20.0,
bottom: 10.0),
child: Text(
'${source.name}',
style: TextStyle(
fontSize: 18.0,
fontWeight:
FontWeight
.bold),
),
),
),
],
),
Container(
child: Text(
'${source.description}',
style: TextStyle(
fontSize: 12.0,
fontWeight:
FontWeight.bold,
color: Colors.grey),
),
),
Container(
child: Text(
'${source.category}',
style: TextStyle(
fontSize: 14.0,
fontWeight:
FontWeight.bold,
color: Colors.black),
),
),
],
),
),
],
),
),
))
.toList());
}
} else {
return CircularProgressIndicator();
}
},
),
onRefresh: refreshListSource,
);
I expected slididng from the top on the screen with the error to try to reload the data
#Sebastian put refreshKey outside the build method, the screen won't get back to top when it rebuilds.
var refreshKey = GlobalKey<RefreshIndicatorState>();
#override
Widget build(BuildContext context) {
...
}

Flutter stateful widgets - issue with saving states on button click

Following is a simple code(in main.dart) I was trying to use to revisit the flutter basics which I was doing few months back.
Here, in the following code setState() is not working as expected and the reason is with the wrong state.
I can get it usable by creating separate statefulwidget withs states constituting the following elements for button and text change.
But here I wanted to know is it possible to do it anonymously with minimal changes in below code
import 'package:flutter/material.dart';
var textStrings = ["Hello", "Hi", "Hey", "Aloha"];
var counter = 0;
void main() => runApp(MaterialApp(
title: "Hello",
home: Scaffold(
appBar: AppBar(
title: Text(
"First App",
style: TextStyle(
color: Colors.white70,
fontSize: 20,
fontStyle: FontStyle.normal),
),
),
body: Container(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Padding(padding: EdgeInsets.only(top: 20)),
Card(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Padding(padding: EdgeInsets.only(bottom: 20)),
Center(
child: Text("With Flutter, Spread Fluttery",
style: TextStyle(
color: Colors.redAccent,
fontStyle: FontStyle.italic,
fontSize: 30)),
),
Padding(padding: EdgeInsets.only(bottom: 20)),
Icon(
Icons.refresh,
size: 50,
color: Colors.amberAccent,
),
Padding(padding: EdgeInsets.only(bottom: 20)),
Text(textStrings[counter % 4],
style: TextStyle(
color: Colors.black38,
fontSize: 30,
fontStyle: FontStyle.normal)),
Padding(padding: EdgeInsets.only(bottom: 20)),
RaisedButton(
onPressed: () {
setState() {
counter++;
}
},
child: Text("Enter",
style: TextStyle(
color: Colors.teal,
fontSize: 30,
)),
)
],
),
)
],
),
),
),
),
));
Sure you can do it adding a few lines of code, you can use the StatefulBuilder.
Wrap your container inside StatefulBuilder and change your setState(() {} ) inside the onPressed method of your button.
void main() => runApp(MaterialApp(
title: "Hello",
home: Scaffold(
appBar: AppBar(
title: Text(
"First App",
style: TextStyle(
color: Colors.white70,
fontSize: 20,
fontStyle: FontStyle.normal),
),
),
body: StatefulBuilder(
builder: (context, setState) {
return Container(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Padding(padding: EdgeInsets.only(top: 20)),
Card(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Padding(padding: EdgeInsets.only(bottom: 20)),
Center(
child: Text("With Flutter, Spread Fluttery",
style: TextStyle(
color: Colors.redAccent,
fontStyle: FontStyle.italic,
fontSize: 30)),
),
Padding(padding: EdgeInsets.only(bottom: 20)),
Icon(
Icons.refresh,
size: 50,
color: Colors.amberAccent,
),
Padding(padding: EdgeInsets.only(bottom: 20)),
Text(textStrings[counter % 4],
style: TextStyle(
color: Colors.black38,
fontSize: 30,
fontStyle: FontStyle.normal)),
Padding(padding: EdgeInsets.only(bottom: 20)),
RaisedButton(
onPressed: () {
setState(() {
counter++;
});
},
child: Text("Enter : $counter",
style: TextStyle(
color: Colors.teal,
fontSize: 30,
)),
)
],
),
)
],
),
),
);
},
)),
));
First, you need to understand that, whenever you call setState() method, It will just rebuild the Stateful Widget, and build() method of the State class of Stateful widget gets executed.
In your code, there is no such stateful widget is available so setState() method is of no use.
Here is the code:
void main() => runApp(MaterialApp(
title: "Hello",
home: Scaffold(
appBar: AppBar(
title: Text(
"First App",
style: TextStyle(
color: Colors.white70,
fontSize: 20,
fontStyle: FontStyle.normal),
),
),
body: MyAppWidgets(),
),
)
);
class MyAppWidgets extends StatefulWidget {
#override
_MyAppWidgetsState createState() => _MyAppWidgetsState();
}
class _MyAppWidgetsState extends State<MyAppWidgets> {
var textStrings = ["Hello", "Hi", "Hey", "Aloha"];
var counter = 0;
#override
Widget build(BuildContext context) {
return Container(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Padding(padding: EdgeInsets.only(top: 20)),
Card(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Padding(padding: EdgeInsets.only(bottom: 20)),
Center(
child: Text("With Flutter, Spread Fluttery",
style: TextStyle(
color: Colors.redAccent,
fontStyle: FontStyle.italic,
fontSize: 30)),
),
Padding(padding: EdgeInsets.only(bottom: 20)),
Icon(
Icons.refresh,
size: 50,
color: Colors.amberAccent,
),
Padding(padding: EdgeInsets.only(bottom: 20)),
Text(textStrings[counter % 4],
style: TextStyle(
color: Colors.black38,
fontSize: 30,
fontStyle: FontStyle.normal)),
Padding(padding: EdgeInsets.only(bottom: 20)),
RaisedButton(
onPressed: () {
setState(() {
counter++;
});
},
child: Text("Enter",
style: TextStyle(
color: Colors.teal,
fontSize: 30,
)),
)
],
),
)
],
),
),
);
}
}
i think that there is no way to do so, because runApp is can not redraw using statefull widget. it is just starting point of your application.
just change the title of your application in main method and use hot reload it will not reflated in you result and use play button(run button) it will work.

How can do card buttons fit together like Reddit App in Flutter?

I want to my card button fit together like Reddit App. How can do that?
Outside the main Row has a Container and Container' has padding height 15.0 . How can Row's widget fit that height 15.0 responsively.
Reddit card buttons
My app card buttons
This is my code;
#override
Widget build(BuildContext context) {
return new SafeArea(
top: false,
bottom: false,
child: new Card(
child: new Column(
children: <Widget>[
new Container(
padding: EdgeInsets.fromLTRB(5.0, 15.0, 5.0, 3.0),
child: new Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
new Container(
color: Colors.blueGrey,
child: new Row(
children: <Widget>[
new Icon(Icons.arrow_drop_up),
new Text('Vote'),
new Icon(Icons.arrow_drop_down),
],
),
),
new Container(
color: Colors.blueGrey,
child: new Row(
children: <Widget>[
new Icon(Icons.mode_comment),
new Text('Comment'),
],
),
),
new Container(
color: Colors.blueGrey,
child: new Row(
children: <Widget>[
new Icon(Icons.share),
new Text('Share'),
],
),
),
],
),
)
],
),
),
);
}
Hello and welcome to Flutter :)
First of all you have used too much padding i.e. 15.0 so that is why your grey boxes are smaller than that of Reddit example.
I have taken a simpler approach and designed a sample control for you. Hope you like it.
import 'package:flutter/material.dart';
void main() {
runApp(RedditButtonsExample());
}
class RedditButtonsExample extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: "Reddit Buttons Example",
home: HomePage(),
theme: ThemeData(
primaryColor: Colors.white,
accentColor: Colors.white,
),
);
}
}
class HomePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Reddit Buttons Example'),
),
body: Column(
children: <Widget>[
Expanded(child: Icon(Icons.insert_emoticon)),
RedditButtonsCard(), //Example widget.
],
),
);
}
}
//This is the example control that you need.
class RedditButtonsCard extends StatelessWidget {
const RedditButtonsCard({
Key key,
}) : super(key: key);
#override
Widget build(BuildContext context) {
return Card(
color: Colors.black,
child: Padding(
padding: const EdgeInsets.all(2.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
FlatButton.icon(
textColor: Colors.white,
icon: Icon(
Icons.thumbs_up_down,
color: Colors.white,
),
label: Text('Vote'),
onPressed: () {},
),
FlatButton.icon(
color: Colors.white30,
textColor: Colors.white,
icon: Icon(
Icons.mode_comment,
color: Colors.white,
),
label: Text('Comment'),
onPressed: () {},
),
FlatButton.icon(
textColor: Colors.white,
icon: Icon(
Icons.share,
color: Colors.white,
),
label: Text('Share'),
onPressed: () {},
),
],
),
),
);
}
}
I used Table and TableRow and I found what I wanted. Off the topic but I want to say this; I found this solution in my dream. I said my self "you have to use DataTable or something then you got what you want." My subconscious full of with Flutter I guess. :D
#override
Widget build(BuildContext context) {
return new SafeArea(
top: false,
bottom: false,
child: new Card(
child: new Column(
children: <Widget>[
new Table(
children: [
new TableRow(
children: [
new InkWell(
onTap: () {},
child: Padding(
padding: const EdgeInsets.fromLTRB(5.0, 15.0, 5.0, 15.0),
child: new Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Icon(FontAwesomeIcons.arrowAltCircleUp, color: Colors.white),
Padding(
padding: const EdgeInsets.only(left: 8.0, right: 8.0),
child: new Text('Vote', style: TextStyle(color: Colors.white)),
),
new Icon(FontAwesomeIcons.arrowAltCircleDown, color: Colors.white),
],
),
),
),
new InkWell(
onTap: () {},
child: Padding(
padding: const EdgeInsets.fromLTRB(5.0, 15.0, 5.0, 15.0),
child: new Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Icon(Icons.mode_comment, color: Colors.white),
Padding(
padding: const EdgeInsets.only(left: 8.0),
child: new Text('Comment', style: TextStyle(color: Colors.white)),
),
],
),
),
),
new InkWell(
onTap: () {},
child: Padding(
padding: const EdgeInsets.fromLTRB(5.0, 15.0, 5.0, 15.0),
child: new Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Icon(Icons.share, color: Colors.white),
Padding(
padding: const EdgeInsets.only(left: 8.0),
child: new Text('Share', style: TextStyle(color: Colors.white)),
),
],
),
),
),
],
),
],
),
],
),
),
);
}

Navigation Undefined name Context

I am currently looking at Navigating withing different screens in my app and so far I can Navigate from LoginScreen to EventsScreen successfully. The problem is in EventsScreen there is a button if clicked it should take me to LoginScreen and this is the code I have.
in my events_screen.dart file
and in my app.dart file MaterialApp widget I have my routes as
The Holiday flatbutton when clicked it does not take me to the "/HolidayScreen" route.
How can I solve the [dart] Undefined name 'context'?
events_screen.dart
import 'package:flutter/material.dart';
import 'holiday.dart';
class EventsScreen extends StatelessWidget {
Widget build(context) {
return MaterialApp(
home: Scaffold(
backgroundColor: Colors.white,
body: Container(
alignment: Alignment.center,
margin: EdgeInsets.all(20.0),
child: ListView(
children: <Widget>[
Container(margin: EdgeInsets.only(bottom: 20.0)),
eventsButton(),
Container(margin: EdgeInsets.only(bottom: 20.0)),
],
),
),
),
);
}
Widget eventsButton() {
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
FlatButton(
color: Colors.red[800],
onPressed: () {},
child: Text(
'Events',
style: new TextStyle(color: Colors.white, fontWeight: FontWeight.normal),
),
),
Container(margin: EdgeInsets.only(right: 20.0)),
FlatButton(
color: Colors.red[800],
child: Text(
'Holidays',
style: new TextStyle(color: Colors.white, fontWeight: FontWeight.normal),
),
onPressed: () {
Navigator.pushNamed(context, "/Holiday");
},
),
Container(margin: EdgeInsets.only(right: 20.0)),
FlatButton(
color: Colors.red[800],
onPressed: () {},
child: Text(
'Flights',
style: new TextStyle(color: Colors.white, fontWeight: FontWeight.normal),
),
),
],
);
}
}
Easy, just pass the BuildContext into your eventsButton method
Widget build(context) {
return MaterialApp(
home: Scaffold(
backgroundColor: Colors.white,
body: Container(
alignment: Alignment.center,
margin: EdgeInsets.all(20.0),
child: ListView(
children: <Widget>[
Container(margin: EdgeInsets.only(bottom: 20.0)),
eventsButton(context),
Container(margin: EdgeInsets.only(bottom: 20.0)),
],
),
),
),
);
}
And add a parameter in your method
Widget eventsButton(BuildContext context) {
return Row(
mainAxisAlignment: MainAxisAlignment
//...
UPDATED
And change this :
Navigator.pushNamed(context, "/Holiday");
To this:
Navigator.pushNamed(context, "/HolidayScreen");
Because your route name is HolidayScreen not Holiday
Make your method accept your context as a parameters
Widget eventsButton(BuildContext context)
and call it with the context: eventsButton(context),

Resources