Align buttons below appBar without any space in flutter [duplicate] - button

This question already has answers here:
Unwanted space appearing between RaisedButton widgets in a column
(1 answer)
Flutter: Remove padding in buttons - FlatButton, ElevatedButton, OutlinedButton
(11 answers)
Closed 3 years ago.
I want to align the buttons just below the appBar but I am getting this:
I want to remove the space between buttons and the appBar. How can I achieve this?
This is the code:
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(
'Home',
),
),
body: Column(
children: <Widget>[
Row(
children: <Widget>[
Column(
children: <Widget>[
Container(
width: MediaQuery.of(context).size.width*0.5,
child: RaisedButton(
onPressed: (){},
child: Text('SORT'),
),
)
],
),
Column(
children: <Widget>[
Container(
width: MediaQuery.of(context).size.width*0.5,
child: RaisedButton(
onPressed: (){},
child: Text('FILTER'),
),
)
],
)
],
),
],
),
);
}
}

Inside the RaisedButton, add this argument:
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap

Use a widget Align parent :
appBar: AppBar(
title: Align(
alignment: Alignment.center
Text(
'Home',
),
),
),

Related

flutter :sharedpreference retrieving null value [duplicate]

This question already has answers here:
What is a NoSuchMethod error and how do I fix it?
(2 answers)
Closed 2 years ago.
The method 'getStringList' was called on null.
Receiver: null
Tried calling: getStringList("userCart")
The relevant error-causing widget was:
Consumer .the details are stored in firebase,the error occurs when displaying the no of items the user have added to the cart.
the CartItemCounter dart file is that thrown error when calling consumer.initially useCart is given as garbage value when registering in firebase.
import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
class StoreHome extends StatefulWidget {
#override
_StoreHomeState createState() => _StoreHomeState();
}
class _StoreHomeState extends State<StoreHome> {
SharedPreferences sharedPreferences;
#override
void initState() {
super.initState();
SharedPreferences.getInstance().then((prefs){
setState(() {
sharedPreferences=prefs;
});
});
}
#override
Widget build(BuildContext context) {
final _width=MediaQuery.of(context).size.width;
return SafeArea(
child: Scaffold(
appBar: AppBar(
title: Text("E_shop",style: TextStyle(color:Colors.red,),
),
centerTitle: true,
actions: [
Stack(
children: [
IconButton(icon:Icon(Icons.add_shopping_cart,color: Colors.grey,),
onPressed: (){
Navigator.pushReplacement(context, MaterialPageRoute(builder: (context)=>StoreHome()));
},
),
Positioned(child: Stack(
children: [
Icon(Icons.brightness_1,size: 20.0,
color: Colors.green,),
Positioned(
top: 3.0,
bottom: 4.0,
left:4.0,
child: Consumer<CartItemCounter>(
builder: (context, counter,_){
return Text(
counter.count.toString(),
style:TextStyle(color:Colors.white,fontSize:12.0,fontWeight:FontWeight.w500),
);
},),
),
],
),
),
],
),
],
),
drawer: MyDrawer(),
body: CustomScrollView(
slivers: [
SliverPersistentHeader(
pinned: true,
delegate: SearchBoxDelegate(),
),
StreamBuilder<QuerySnapshot>(
stream: FirebaseFirestore.instance.collection("items").limit(15).orderBy("publishedDate",descending: true).snapshots(),
builder: (context,dataSnapshot){
return !dataSnapshot.hasData
?SliverToBoxAdapter(child: Center(child: circularProgress(),),)
:SliverStaggeredGrid.countBuilder(
crossAxisCount: 1,
itemCount: 5,
staggeredTileBuilder: (c)=>StaggeredTile.fit(1),
itemBuilder: (context,index){
ItemModel model=ItemModel.fromJson(dataSnapshot.data.docs[index].data());
return sourceInfo(model,context);
},
);
},
),
],
),
),
);
}
circularProgress(){
return Container(
alignment: Alignment.center,
padding: EdgeInsets.only(top: 12.0),
child: CircularProgressIndicator(valueColor: AlwaysStoppedAnimation(Colors.lightGreenAccent),),
);
}
Widget sourceInfo(ItemModel model, BuildContext context , {Color background, removeCartFunction}) {
return InkWell(
onTap: (){
Navigator.pushReplacement(context, MaterialPageRoute(builder: (context)=>ProductPage(itemModel:model)));
},
splashColor: Colors.pink,
child: Padding(
padding: EdgeInsets.all(6.0),
child: Container(
height: 300.0,
width: MediaQuery.of(context).size.width,
child: Row(
children: [
Image.network(model.thumbnailUrl ,width:140.0,height: 140.0,),
SizedBox(width: 4.0,),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(height: 16.0,),
Container(
child: Row(
mainAxisSize: MainAxisSize.max,
children: [
Expanded(child: Text(
model?.title ?? '',style: TextStyle(color: Colors.black,fontSize: 14.0),
),
)
],
),
),
SizedBox(height: 5.0,),
Container(
child: Row(
mainAxisSize: MainAxisSize.max,
children: [
Expanded(child: Text(
model?.shortInfo ?? '',style: TextStyle(color: Colors.black54,fontSize: 12.0),
),
)
],
),
),
SizedBox(height: 20.0,),
Row(
children: [
Container(
decoration: BoxDecoration(
shape: BoxShape.rectangle,
color: Colors.pink,
),
alignment: Alignment.topLeft,
width: 40.0,
height: 43.0,
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
"50%",style: TextStyle(
fontSize: 15.0,color: Colors.white,
fontWeight: FontWeight.bold,
),
),
Text(
"OFF",style: TextStyle(
fontSize: 12.0,color: Colors.white,
fontWeight: FontWeight.bold,
),
),
],
),
),
),
SizedBox(width: 10.0,),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: EdgeInsets.only(top: 0.0),
child: Row(
children: [
Text(
"Original Price :%",
style: TextStyle(
fontSize: 14.0,
color: Colors.grey
),
),
Text(
(model?.price??'').toString(),
style: TextStyle(
fontSize: 15.0,
color: Colors.grey,
decoration: TextDecoration.lineThrough,
),
)
],
),
),
Padding(
padding: EdgeInsets.only(top: 5.0),
child: Row(
children: [
Text(
"New Price :%",
style: TextStyle(
fontSize: 16.0,
color: Colors.red,
),
),
Text(
"%",
style: TextStyle(
fontSize: 15.0,
color: Colors.grey,
),
),
Text(
(model.price+model.price).toString(),
style: TextStyle(
fontSize: 15.0,
color: Colors.grey
),
),
],
),
),
],
),
],
),
Flexible(child: Container(
),
),
//to implement cart add/remove remove
Align(
alignment: Alignment.centerRight,
child: removeCartFunction==null
?IconButton(
icon: Icon(Icons.add_shopping_cart,color: Colors.pinkAccent,),
onPressed: (){
checkItemInCart(model.shortInfo,context);
},)
:IconButton(
icon: Icon(Icons.delete),
onPressed: null)
)
],
))
],
),
),
),
);
}
void checkItemInCart(String shortInfoAsId, BuildContext context) {
sharedPreferences.getStringList(EcommerceApp.userCartList).contains(shortInfoAsId)
?Fluttertoast.showToast(msg: "item already in cart")
:addItemToCart(shortInfoAsId,context);
}
addItemToCart(String shortInfoAsId, BuildContext context) {
List tempCartList=sharedPreferences.getStringList(EcommerceApp.userCartList);
tempCartList.add(shortInfoAsId);
FirebaseFirestore.instance.collection("users").doc(sharedPreferences.getString(EcommerceApp.userUID))
.update({
EcommerceApp.userCartList: tempCartList,
}).then((value){
Fluttertoast.showToast(msg: "Item added to cart successfully");
sharedPreferences.setStringList(EcommerceApp.userCartList, tempCartList);
Provider.of<CartItemCounter>(context,listen: false).displayResult();
});
}
}```
the CartItemCounter dart file is that thrown error when calling consumer<cartitemcounter>.initially useCart is given as garbage value when registering in firebase.
```class CartItemCounter extends ChangeNotifier{
static SharedPreferences sharedPreferences;
int _counter=sharedPreferences.getStringList("userCart").length-1;
int get count=>_counter;
Future<void> displayResult() async{
int _counter=sharedPreferences.getStringList("userCart").length-1;
await Future.delayed(const Duration(milliseconds: 100),(){
notifyListeners();
});
}
}```
The method 'getStringList' was called on null.
Receiver: null
Tried calling: getStringList("userCart")
The relevant error-causing widget was:
Consumer<CartItemCounter> .the details are stored in firebase,the error occurs when displaying the no of items the user have added to the cart.
The error:
getStringList("...") was called on null
implies that the method was called on a null object which means that you are trying to call sharedPrefs.getStringList()
but, sharedPrefs is null at the moment as it has not been loaded yet. Hence, you encounter the problem. A simple hack to solve this problem:
#override
Widget build(BuildContext context) {
final _width=MediaQuery.of(context).size.width;
return SafeArea(
child:
sharedPrefs == null? // If sharedPrefs is not retreived yet
Scaffold(body: Center(child: Text("Hold on :)"))): // Show this widget
Scaffold( // Else do your normal job
appBar: AppBar(
title: Text("E_shop",style: TextStyle(color:Colors.red,),
),
......... and so on..

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 have a Flutter button be as wide as possible up to a maximum width?

In the following layout, I'd like the button to be able to grow to be as wide as possible on the screen, up to a maximum width. I've tried the following, which doesn't work (the button is always as wide as possible):
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: SafeArea(
child: Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
TextFormField(),
TextFormField(),
ConstrainedBox(
constraints: BoxConstraints(maxWidth: 200),
child: RaisedButton(child: Text("button"), onPressed: () {}),
),
],
),
),
),
),
);
}
}
To expand on the layout I'm looking for: the button must be the same width as the smaller of the following two quantities: 1) the width of the screen, 2) a given fixed maximum width.
Example scenarios:
A) the screen is 1000 pixels wide, and the given fixed maximum width is 600 pixels, then the button will be 600 pixels wide.
B) the screen is 400 pixels wide, and the given fixed maximum width is 600 pixels, then the button will be 400 pixels wide.
The solution is pretty simple, simply wrap your ConstrainedBox in Align and instead of using maxWidth use minWidth.
Align(
child: ConstrainedBox(
constraints: BoxConstraints(minWidth: 200),
child: RaisedButton(child: Text("button"), onPressed: () {}),
),
)
Output:
If screen width > 200, button takes up 200 width
If screen width < 200, button takes up screen width
You can remove crossAxisAlignment: CrossAxisAlignment.stretch, because TextFormField is stretching anyway. This code will make the button width to be of a max width size, but no bigger than screen width:
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) => MaterialApp(
home: Scaffold(
body: SafeArea(
child: Center(
child: Column(
children: [
TextFormField(),
TextFormField(),
Container(
width: 200,
child: RaisedButton(
onPressed: () {},
child: Text('button'),
),
),
Container(
width: 200,
child: RaisedButton(
onPressed: () {},
child: Text(
'Button with long text asf sadf sdf as df s df as '
'dfas dfsd f asfauhiusg isdugfisudgfi asudgk usgkdu'
'ksdfhk sudfhk sudhfk',
),
),
),
],
),
),
),
),
);
}
You can put the RaisedButton in a Row:
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: SafeArea(
child: Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
TextFormField(),
TextFormField(),
ConstrainedBox(
constraints: BoxConstraints(maxWidth: 250),
child: Row(
children: <Widget>[
Expanded(
child: RaisedButton(child: Text('test')),
),
],
),
),
],
),
),
),
),
);
}
}
The Row will create a horizontal row, and the RaisedButton widget will only take as much room as its own size.
first wrap with container and add width to infinity to be responsive:
Container(
width: double.infinity,
child: ElevatedButton(
child: Text("button"),
onPressed: (){}
),
),
you can add padding too..
known that RaisedButton is deprecated and migrated to ElevatedButton..

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;

Flutter Change height of an OutlineButton inside an AppBar?

Just wondering how I would change the height of an OutlineButton? I suppose this would likely apply to other button types as well.
return Scaffold(
appBar: AppBar(
title: Text('Test'),
actions: <Widget> [
SizedBox(
width: 100.0,
height: 8.0,
child: OutlineButton(
borderSide: BorderSide(width: 4.0)
child: Text('Hi'),
onPressed: (){},
),
),
],
),
body: Container(),
);
I am finding the button just about 8px too high for my case, and want to squish it a bit.
SizedBox should do the work. Wrap your button by a SizedBox.
From the document:
If given a child, this widget forces its child to have a specific width and/or height (assuming values are permitted by this widget's parent). If either the width or height is null, this widget will size itself to match the child's size in that dimension.
If not given a child, this widget will size itself to the given width and height, treating nulls as zero.
This will work for RaisedButton also
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'My Layout',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("SizedBox Demo"),
),
body: new Center(
child: new SizedBox(
width: 200.0,
height: 80.0,
child: new OutlineButton(
borderSide: BorderSide(width: 4.0),
child: Text('I am a button'),
onPressed: (() {})),
),
),
);
}
}
UPDATED (2018/05/26):
If you want to reduce the height of OutlineButton inside AppBar, use Padding
return Scaffold(
appBar: AppBar(
title: Text('Test'),
actions: <Widget> [
Padding(
child: OutlineButton(
borderSide: BorderSide(width: 4.0)
child: Text('Hi'),
onPressed: (){},
padding: EdgeInsets.all(10.0),
),
),
],
),
body: Container(),
);
Flutter 2.5
OutlineButton is deprecated. Instead, use the Material button.
Put the Material Button inside Padding.
The padding property of Padding will control the height and width of the button.
AppBar(
title: Text("Stack Overflow"),
actions: [
Padding(
padding: EdgeInsets.all(8.0),
child: MaterialButton(
color: Colors.yellow,
onPressed: () {
},
child: Text('SUBMIT'),
),
)
],
)
Thanks #phuc-tran, I've made a small fix:
return Scaffold(
appBar: AppBar(
title: Text('Test'),
actions: <Widget> [
Padding(
padding: EdgeInsets.all(10.0),
child: OutlineButton(
borderSide: BorderSide(color: Colors.blue),
child: Text('Hi'),
onPressed: (){},
),
),
],
),
body: Container(),
);

Resources