How to center column and row item in Flutter? - grid

I have a small currency table. I didn't use grid. I used Column and rows. Problem is that items in rows is not showing in center as shown below in the Excel example.
What widget do I have to use to make the items centered?
The Example codes:
return new Center(
child: new Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
new Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Padding(
padding: const EdgeInsets.fromLTRB(15.0, 5.0, 15.0, 5.0),
child: new Icon(
Icons.crop_rotate,
color: Colors.white,
),
),
new Padding(
padding: const EdgeInsets.fromLTRB(15.0, 5.0, 15.0, 5.0),
child: new Text("STG", style: mainHeadTextStyle),
),
new Padding(
padding: const EdgeInsets.fromLTRB(15.0, 5.0, 15.0, 5.0),
child: new Text("EUR", style: mainHeadTextStyle),
),
new Padding(
padding: const EdgeInsets.fromLTRB(15.0, 5.0, 15.0, 5.0),
child: new Text("USD", style: mainHeadTextStyle),
),
],
),
new Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
....
....
....

If you want the whole table to be Centered, use the mainAxisAlignment property of Column.
Column
mainAxisAlignment: MainAxisAlignment.center //Center Column contents vertically,
crossAxisAlignment: CrossAxisAlignment.center //Center Column contents horizontally,
Row
mainAxisAlignment: MainAxisAlignment.center //Center Row contents horizontally,
crossAxisAlignment: CrossAxisAlignment.center //Center Row contents vertically,

You can use Spacer if you want fine grain control.
Column(
children: <Widget>[
Spacer(), // 1st spacer
Widget1(),
Widget2(),
Spacer(), // 2nd spacer
],
)
You can change flex too using Spacer(flex:2)

If you want it to be like in the picture, use
mainAxisAlignment: MainAxisAlignment.spaceEvenly

Related

How to navigate to a specific route in a list full of the same widget?

I have a an app which the user is able to add in books and it upload to the firestore database, and then I use a streamBuilder() to recieve all the data and display it in a list of GestureDetector() with the card() as a child.
Here is the code for the
final bookWidget = GestureDetector(
key: ValueKey(loggedInUser.email),
onTap: () {
print(title);
},
child: Card(
semanticContainer: true,
clipBehavior: Clip.antiAliasWithSaveLayer,
child: Stack(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Container(
width: 100,
height: 140,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
image: DecorationImage(
fit: BoxFit.cover,
image: NetworkImage(bookCoverURL)),
),
),
Container(
width: 230,
//color: Colors.red,
child: Column(
mainAxisAlignment:
MainAxisAlignment.center,
crossAxisAlignment:
CrossAxisAlignment.center,
children: [
Text(
category.toString(),
style: TextStyle(
color: Colors.grey,
fontStyle: FontStyle.italic,
),
),
Container(
margin: EdgeInsets.only(top: 10),
child: Text(
title.toString(),
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 17,
),
),
),
Container(
margin: EdgeInsets.only(top: 10),
child: Text(
(author),
style:
TextStyle(color: Colors.grey),
),
),
],
),
),
Icon(
Icons.arrow_forward_ios,
color: Colors.black,
size: 15,
)
],
),
],
),
//color: Colors.yellowAccent,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
elevation: 5,
margin: EdgeInsets.all(10),
),
);
bookWidgets.add(bookWidget);
And then I display all my code in the screen by :
Column(
children: bookWidgets,
)
But how can I make the app navigate to a new screen when the user pressed on a specific card()? Since all of them are the same widget and have no unique identifier?
Any help is greatly appreciated! Thank you!
GestureDetector(
key: ValueKey(loggedInUser.email),
onTap: () {
Navigator.pushNamed(
context,
'/routeNameHere',
arguments: id,
);
},
)
In parameter arguments: ID - you can change the id by the id of the card that you want to navigate to.
You must create a page for the display detail of the card, which just displays a card with same id in the argument. So on your new page, create a variable for receiving the argument, e.g.:
final cardId = ModalRoute.of(context).settings.arguments as String;
So the page can display the card depending on the cardId.
You will need to create an identifier to pass (in this case “book”). In Flutter, these are necessary when calling or passing an object.
However, in regards to using Named Routes , this can allow you to send the data without the identifier but is considered bad practice in coding as you would not have a reference to the call or be able to back trace through the data.
Keeping the above in mind, it is possible to use the OnTap() inside each child card container so that on handle clicks or tap gestures, the user is taken to a different screen using routes as it is part of the GestureDetector class.

How to add a date header for my chat module in flutter with firebase?

I want to add a sticky date header for my chat module just like how WhatsApp has. I tried sticky headers dependency, but it didn't work out.
Chat Page Code:
Column(
crossAxisAlignment:
snapshot['senderUid'] == _senderuid
? CrossAxisAlignment.end
: CrossAxisAlignment.end,
children: [
new Text(
snapshot['message'],
style: TextStyle(
color: Colors.white, fontSize: 15.0),
),
Padding(
padding: const EdgeInsets.only(top: 5),
child: new Text(
snapshot['timestamp']
.toDate()
.toString()
.substring(10, 16),
style: TextStyle(
color: Colors.white.withOpacity(0.5),
fontSize: 9.0),
),
),
],
),
You can try with this package
https://pub.dev/packages/flutter_sticky_header
Or with Slivers and SliverPersistentHeaderDelegate

Flutter: aligning buttons edge to edge to other components

I found it difficult to layout buttons in a way that their visual representation is harmonic with other widgets, yet their touchable area has additional extra space for users' fingers.
Please have a look at the attached picture.
Code:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Material(child: HomePage()),
);
}
}
class HomePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Column(
children: <Widget>[
Container(
color: Colors.yellow,
padding: EdgeInsets.all(16),
child: Column(
children: <Widget>[
Row(
children: <Widget>[
Text('Top Left'),
Spacer(),
Text('Top right')
],
),
Row(
children: <Widget>[
Text('Middle Left'),
Spacer(),
Text('Middle right')
],
),
Row(
children: <Widget>[
Text('Bottom Left'),
Spacer(),
Text('Bottom right')
],
),
],
),
),
Container(
color: Colors.orange,
padding: EdgeInsets.all(16),
child: Column(
children: <Widget>[
Row(
children: <Widget>[
Text('Top Left'),
Spacer(),
FlatButton(
child: Text('Top right'),
onPressed: () {},
)
],
),
Row(
children: <Widget>[
Text('Middle Left'),
Spacer(),
Text('Middle right')
],
),
Row(
children: <Widget>[
IconButton(
icon: Icon(Icons.print),
onPressed: () {},
alignment: Alignment.bottomLeft,
),
Spacer(),
Text('Bottom right')
],
),
],
),
),
],
),
);
}
}
The "all texts" widgets are beautifully aligned. But when I add interactive widgets, it starts getting ugly.
The Flat button has the same font as Text. But it's touchable area is expanding it. I am aware of materialTapTargetSize but it shrinks the clickable area which has its inflated size to make it easy to tap it. Is there an easy way to render it exactly as the "Top right" text widget and still have the same touchable area? In that case, the touchable area should expand further out of 16px padding, because I would link the Ink to be distributed evently around the button.
IconButton is higher than text, but the problem is that it doesn't start where the texts starts (left edge). Even if I add the alignment: Alignment.centerLeft, it is slightly moved to the left but still not edge to edge with other texts. On top of that after changing this alignment it's no longer centred within its InkWell.
For now, I solve all these issues using Stack and Positioned widgets. With this approach, I can control exactly where the items are, and the InkWell keeps the content exactly in the centre. But I believe it's not a correct solution.
Appreciate your feedback.
Try this code,
For the flat button:
Container(
alignment: Alignment.centerRight,
width: 60,
child: FlatButton(
padding: EdgeInsets.all(0),
child: Text('Top right'),
onPressed: () {},
),
)
For the icon button:
IconButton(
padding: EdgeInsets.all(0),
icon: Icon(Icons.print),
onPressed: () {},
alignment: Alignment.bottomLeft,
),

How to make changes at the particular index of a list whose data is fetched from cloud Firestore in flutter?

In my flutter application, i fetched my data in a list from Firestore and now want to an ADD or REMOVE option for increasing or decreasing the number of units of that particular item on the list but after several tries not able to do that as the count on the entire list gets updated not that particular element in that index. Can anyone help me in this
CustomScrollView(
physics: BouncingScrollPhysics(),
slivers: <Widget>[
SliverList(
delegate: SliverChildBuilderDelegate((context, index){
return Container(
margin: EdgeInsets.only(top: 15.0,left: 15.0,right: 15.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Container(
child: Text(snapshot.data.documents[index].documentID,style: TextStyle(fontFamily: "DelishN", fontSize: 15.0),),
),
Container(
decoration: BoxDecoration(
border: Border.all(
width: 2.0,
color: Colors.black
),
borderRadius: BorderRadius.circular(23.0)
),
child: Row(
children: <Widget>[
FloatingActionButton(
onPressed: (){
add();
},
mini: true,
child: Icon(Icons.add, color: Colors.black,),
backgroundColor: Colors.white,
),
SizedBox(
width: 7.0,
),
Text(_n.toString(), style: TextStyle(fontFamily: 'DelishN',),),
SizedBox(
width: 7.0,
),
FloatingActionButton(
onPressed: (){
minus();
},
mini: true,
child: Icon(Icons.remove, color: Colors.black,),
backgroundColor: Colors.white,)
],
),
)
],
)
);
},
childCount: snapshot.data.documents.length))],
)

How do I generate a list of widgets from firebase firestore database?

I'm trying to figure out how to iterate through documents in firestore and create a text widget for each one.
I've figured out how to access those elements. I used debugPrint() and got the results I'm expecting, but I can't get it to display below my other widgets. I get a red screen with a ton of errors (on phone).Below is my code for what I've tried so far.
QuerySnapshot querySnapshot = await
Firestore.instance.collection("users").document(user.uid).collection("trails").getDocuments();
var list = querySnapshot.documents;
list.forEach((doc) => debugPrint(doc.data["Trail Name"].toString()));//works
final topContentText = Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
//these widgets are generating correctly
Text(
"First Name: $firstName",
style: TextStyle(color: Colors.white, ),
),
Text(
"Last Name: $lastName",
textAlign: TextAlign.left,
style: TextStyle(color: Colors.white,),
),
Text(
"Email: $email",
style: TextStyle(color: Colors.white, ),
),
//these ones are causing my errors.
list.forEach((doc) => Text(
"Trail Name: ${doc.data["Trail Name"].toString()}",
style: TextStyle(color: Colors.white, ),
),)
],
);
final topContent = Stack(
children: <Widget>[
Container(
height: MediaQuery.of(context).size.height * 0.40,
padding: EdgeInsets.all(40.0),
width: MediaQuery.of(context).size.width,
decoration: BoxDecoration(color: Color.fromRGBO(58, 66, 86, .9)),
child: Center(
child: topContentText,
),
),
Positioned(
left: 8.0,
top: 60.0,
child: InkWell(
onTap: () {
Navigator.pop(context);
},
child: Icon(Icons.arrow_back, color: Colors.white),
),
)
],
);
return Scaffold(
body: Column(
children: <Widget>[topContent, bottomContent],
),
);
The screen on my device lights up red with errors on creating child widgets, when I'm expecting it to display the Trail Name(s) below the other info. I only included necessary code, but could include more (such as the widget's build method) if needed. Thanks for any assistance. I'm new to flutter.
Try using the map function:
List<Widget> _widgets = list.map((doc) => Text(
"Trail Name: ${doc.data["Trail Name"].toString()}",
style: TextStyle(color: Colors.white, ),
),).toList();
And then for the children of the column, just add that list to the list you specify, like:
children: [ ... ] + _widgets;

Resources