How to implement a SliverAppBar with a collapsable search bar - flutter

This is what I'm trying to do, it's a pretty common Widget on iOS. This is my code:
return Scaffold(
backgroundColor: Colors.white,
body: CustomScrollView(
slivers: <Widget>[
SliverAppBar(
automaticallyImplyLeading: false,
pinned: true,
titleSpacing: 0,
backgroundColor: Colors.white,
elevation: 1.0,
title: Container(
width: double.infinity,
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceAround,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
CupertinoButton(
padding: EdgeInsets.all(0),
onPressed: () {},
child: AutoSizeText(
'Ordenar',
style: TextStyle(
color: Color(0xff16161F),
fontFamily: 'Brutal',
fontSize: 17.0,
),
),
),
AutoSizeText(
'Equipos 14',
style: TextStyle(
color: Color(0xff16161F),
fontFamily: 'Archia',
fontSize: 22.0,
),
),
CupertinoButton(
padding: EdgeInsets.all(0),
onPressed: () {},
child: AutoSizeText(
'Editar',
style: TextStyle(
color: Color(0xff16161F),
fontFamily: 'Brutal',
fontSize: 17.0,
),
),
),
],
),
),
centerTitle: true,
),
SliverFillRemaining(
child: Center(
child: CupertinoButton(
onPressed: () {
setState(() {
(isBottom) ? isBottom = false : isBottom = true;
});
},
child: Text('YESSS'),
),
),
),
],
),
bottomNavigationBar: (isBottom) ? _toolBar() : _tabBar(),
);
I've tried adding a CupertinoTextField() to the bottom property, but it gets into my Row() and messes up everything. Has anyone done this, or knows how to achieve it?
Thanks.

I managed to solve it. SliverAppBar has a property called flexibleSpace. In here you put a FlexibleSpaceBar, which contains a background property. Now, don't be fooled, this is not limited to a solid color or an image. It can take any Widget you want. In my case, I wanted to add a search bar. And because this property will fill the entire expandedHeight property, you want to add a small blank space so your custom widgets don't get drawn over your SliverAppBar. Here's the relevant piece of code:
flexibleSpace: FlexibleSpaceBar(
background: Column(
children: <Widget>[
SizedBox(height: 90.0),
Padding(
padding: const EdgeInsets.fromLTRB(16.0, 6.0, 16.0, 16.0),
child: Container(
height: 36.0,
width: double.infinity,
child: CupertinoTextField(
keyboardType: TextInputType.text,
placeholder: 'Filtrar por nombre o nombre corto',
placeholderStyle: TextStyle(
color: Color(0xffC4C6CC),
fontSize: 14.0,
fontFamily: 'Brutal',
),
prefix: Padding(
padding:
const EdgeInsets.fromLTRB(9.0, 6.0, 9.0, 6.0),
child: Icon(
Icons.search,
color: Color(0xffC4C6CC),
),
),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8.0),
color: Color(0xffF0F1F5),
),
),
),
),
],
),
),
),
And here is the result. The search bar will disappear when the scroll goes up. Hope this helps anyone wanting to do this.

Related

Flutter - Remove padding from Circular Elevated Button

I have a simple view with a Column and two Rows, the second row has a list of circular buttons, which I would like to be aligned with the beginning of the first row.
Unfortunately, probably because of the CircularBorder I can't do it... Any idea how to make it work?
Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.start,
children: [
const Padding(
padding: EdgeInsets.only(
bottom: 12.0,
top: 20.0,
),
child: Align(
alignment: Alignment.centerLeft,
child: Text("Select preferred options",
textAlign: TextAlign.left,
style: TextStyle(
color: Color(0XFF8E8E8E),
fontSize: 15.0,
fontWeight: FontWeight.w200,
)),
),
),
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
...TransportModes.publicTransport.options.map(
(e) => Container(
color: Colors.blue,
child: Column(
children: [
Container(
color: Colors.red,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
shape: const CircleBorder(),
padding: const EdgeInsets.all(0),
primary: Theme.of(context).colorScheme.tertiary,
),
onPressed: () {},
child: ImageIcon(
AssetImage(iconPath),
size: 20.0,
color: Theme.of(context).colorScheme.onTertiary,
),
),
),
Text(
text,
style: const TextStyle(
color: Color(0XFF8E8E8E),
fontSize: 13.0,
fontWeight: FontWeight.w200,
),
)
],
),
),
),
],
),
],
),
The result looks like this:
I would like the first circle to start aligned with the text above...
The space around the circle is caused by minimumSize: property in the default style of elevated button.
Add minimumSize: Size(40, 40) or (your preferred height and width) inside style: ElevatedButton.styleFrom().

How to align widgets in a Row using crossAxisAlignment Flutter

I am trying to replicate the AppBar widget as shown in the image below. I tried using Row widget and added the required widgets inside it's children and added crossAxisAlignment: CrossAxisAlignment.center in order to align all the widgets in center (horizontally, as it is a Row widget). But I'm unable to achieve the results, getting A RenderFlex overflowed by 26 pixels on the right. error, (obviously because it is flowing out of the appBar area).
Required:
Mine:
Code:
Scaffold(
appBar: AppBar(
elevation: 0.0,
backgroundColor: Colors.transparent,
actions: [
IconButton(
onPressed: () {},
icon: const Icon(Icons.search),
color: Colors.black,
)
],
leading: InkWell(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Container(
height: 40,
width: 40,
decoration: const BoxDecoration(
color: Colors.grey,
shape: BoxShape.circle,
),
),
Column(
mainAxisAlignment: MainAxisAlignment.start,
children: const [
Text(
"Welcome",
style: TextStyle(
fontSize: 10,
fontWeight: FontWeight.normal,
color: Colors.grey,
),
),
Text(
"John",
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.bold,
color: Colors.black,
),
),
],
),
],
),
onTap: () { // open drawer },
),
),
);
If anyone could guide me what I'm doing wrong, I would really appreciate it!
Thanks!
Lets try title
Scaffold(
appBar: AppBar(
elevation: 0.0,
backgroundColor: Colors.transparent,
actions: [
IconButton(
onPressed: () {},
icon: const Icon(Icons.search),
color: Colors.black,
)
],
title: InkWell(
onTap: (){},
child: Row(
children: [
Container(
width: 40,
height: 40,
decoration: const BoxDecoration(
color: Colors.grey,
shape: BoxShape.circle,
),
),
SizedBox(width: 10,),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: const [
Text(
"Welcome",
style: TextStyle(
fontSize: 10,
fontWeight: FontWeight.normal,
color: Colors.grey,
),
),
Text(
"John",
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.bold,
color: Colors.black,
),
),
],
),
],
),
),
),
body: Container(
))
with leading
leadingWidth: double.infinity,
leading: InkWell(-------)
output:
The reason why this is happening is that you are using leading property, which has width limitation defined by leadingWidth properly of AppBar, which is 56.0 by default. You can try setting leadingWidth with value double.infinity and that would work.
Alternatively you should re-consider using leading, as its main purpose is some icon or small widget coming before title.
you can replace my source code, please it will work 100%. best of luck!
Scaffold(
appBar: AppBar(
elevation: 0.0,
backgroundColor: Colors.transparent,
actions: [
IconButton(
onPressed: () {},
icon: const Icon(Icons.search),
color: Colors.black,
)
],
leading: InkWell(
child: FittedBox(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Container(
height: 40,
width: 40,
decoration: const BoxDecoration(
color: Colors.grey,
shape: BoxShape.circle,
),
),
Column(
mainAxisAlignment: MainAxisAlignment.start,
children: const [
Text(
"Welcome",
style: TextStyle(
fontSize: 10,
fontWeight: FontWeight.normal,
color: Colors.grey,
),
),
Text(
"John",
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.bold,
color: Colors.black,
),
),
],
),
],
),
),
),
));

TextButton Icon with Two Line Label/Text, Is it possible?

Trying to make a card menu that is a quick link to app's main sections. I tried using TextButton.Icon ( but since the word count varies too much from 8-letter word to 19-letter word, the font size becomes too small for the shorter word, so the aesthetics looks weird.
I'm thinking to make the label of the button to two lines as shown in the JPEG attached.
Wondering if this is possible with a container inside a material button instead?
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
class QuickMenu extends StatelessWidget {
const QuickMenu({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
automaticallyImplyLeading: false, //to remove back button
backgroundColor: Colors.white,
flexibleSpace: Container(
margin: EdgeInsets.fromLTRB(4.0, 25.0, 4.0, 3.0),
height: 55.0,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Image(
image: AssetImage('images/logo.png'),
),
IconButton(
onPressed: () {},
icon: Icon(
Icons.notifications_outlined,
size: 35.0,
color: Color(0xFF959DA8),
),
),
],
),
),
),
body: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Card(
margin: EdgeInsets.fromLTRB(15.0, 15.0, 15.0, 15.0),
clipBehavior: Clip.antiAlias,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Padding(
padding:
const EdgeInsets.fromLTRB(10.0, 5.0, 15.0, 3.0),
child: Text(
'MENU BUTTONS',
style: TextStyle(
fontFamily: "Roboto",
fontSize: 20.0,
color: Color(0xFFD4D7DA),
),
),
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Expanded(
child: Row(
children: [
TextButton.icon(
onPressed: () {},
icon: Icon(Icons.home,
color: Colors.white, size: 30.0),
label: Text(
'Text Button 1',
style: TextStyle(
fontFamily: 'Roboto',
fontSize: 15.0,
color: Colors.white),
),
style: TextButton.styleFrom(
padding:
EdgeInsets.fromLTRB(10.0, 8.0, 20.0, 8.0),
backgroundColor: Color(0xFFD4D7DA),
),
),
SizedBox(
width: 10.0,
),
TextButton.icon(
onPressed: () {},
icon: Icon(Icons.home,
color: Colors.white, size: 30.0),
label: Text(
'Text Button 2',
style: TextStyle(
fontFamily: 'Roboto',
fontSize: 15.0,
color: Colors.white),
),
style: TextButton.styleFrom(
padding:
EdgeInsets.fromLTRB(10.0, 8.0, 75.0, 8.0),
backgroundColor: Color(0xFFD4D7DA),
),
),
],
),
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.fromLTRB(2.0, 2.0, 2.0, 8.0),
child: Expanded(
child: Row(
children: [
TextButton.icon(
onPressed: () {},
icon: Icon(Icons.home,
color: Colors.white, size: 30.0),
label: Text(
'Text Button 3',
style: TextStyle(
fontFamily: 'Roboto',
fontSize: 8.0,
color: Colors.white),
),
style: TextButton.styleFrom(
padding:
EdgeInsets.fromLTRB(10.0, 8.0, 20.0, 8.0),
backgroundColor: Color(0xFFD4D7DA),
),
),
SizedBox(
width: 10.0,
),
TextButton.icon(
onPressed: () {},
icon: Icon(Icons.home,
color: Colors.white, size: 30.0),
label: Text(
'Text Button 4',
style: TextStyle(
fontFamily: 'Roboto',
fontSize: 8.0,
color: Colors.white),
),
style: TextButton.styleFrom(
padding:
EdgeInsets.fromLTRB(10.0, 8.0, 75.0, 8.0),
backgroundColor: Color(0xFFD4D7DA),
),
),
],
),
),
),
],
),
],
),
),
],
),
),
);
}
}
Try with this and also if you used a list or column you can make it expanded
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
class QuickMenu extends StatelessWidget {
const QuickMenu({Key key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
automaticallyImplyLeading: false, //to remove back button
backgroundColor: Colors.white,
flexibleSpace: Container(
margin: EdgeInsets.fromLTRB(4.0, 25.0, 4.0, 3.0),
height: 55.0,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Image(
image: AssetImage('images/profile.png'),
),
IconButton(
onPressed: () {},
icon: Icon(
Icons.notifications_outlined,
size: 35.0,
color: Color(0xFF959DA8),
),
),
],
),
),
),
body: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Card(
margin: EdgeInsets.fromLTRB(15.0, 15.0, 15.0, 15.0),
clipBehavior: Clip.antiAlias,
color: Colors.grey,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Padding(
padding:
const EdgeInsets.fromLTRB(10.0, 5.0, 15.0, 3.0),
child: Text(
'MENU BUTTONS',
style: TextStyle(
fontFamily: "Roboto",
fontSize: 20.0,
color: Color(0xFFD4D7DA),
),
),
),
],
),
Row(
children: [
TextButton.icon(
onPressed: () {},
icon: Icon(Icons.home),
label: Container(
width: 100,// change width as you need
height: 70, // change height as you need
child: Align(
alignment: Alignment.centerLeft,
child: Text(
"Text",
textAlign: TextAlign.left,
maxLines: 2, // change max line you need
),
),
),
style: TextButton.styleFrom(
padding:
EdgeInsets.fromLTRB(10.0, 8.0, 20.0, 8.0),
backgroundColor: Color(0xFFD4D7DA),
),
),
SizedBox(width: 10,),
TextButton.icon(
onPressed: () {},
icon: Icon(Icons.payments_rounded),
label: Container(
width: 100, // change width as you need
height: 70, // change height as you need
child: Align(
alignment: Alignment.centerLeft,
child: Text(
"Text Button 2",
textAlign: TextAlign.left,
maxLines: 2,
style: TextStyle(fontSize: 24),// change max line you need
),
),
),
style: TextButton.styleFrom(
padding:
EdgeInsets.fromLTRB(10.0, 8.0, 20.0, 8.0),
backgroundColor: Color(0xFFD4D7DA),
),
),
],
),
SizedBox(height: 10,),
Row(
children: [
TextButton.icon(
onPressed: () {},
icon: Icon(Icons.shopping_cart),
label: Container(
width: 100,
height: 70, // change height as you need
child: Align(
alignment: Alignment.centerLeft,
child: Text(
"TextButton 3 ",
textAlign: TextAlign.left,
maxLines: 2, // change max line you need
),
),
),
style: TextButton.styleFrom(
padding:
EdgeInsets.fromLTRB(10.0, 8.0, 20.0, 8.0),
backgroundColor: Color(0xFFD4D7DA),
),
),
SizedBox(width: 10,),
TextButton.icon(
onPressed: () {},
icon: Icon(Icons.person_outline),
label: Container(
width: 100, // change width as you need
height: 70, // change height as you need
child: Align(
alignment: Alignment.centerLeft,
child: Text(
"TextButton 4",
textAlign: TextAlign.left,
maxLines: 2, // change max line you need
),
),
),
style: TextButton.styleFrom(
padding:
EdgeInsets.fromLTRB(10.0, 8.0, 20.0, 8.0),
backgroundColor: Color(0xFFD4D7DA),
),
),
],
),
],
),
),
),
],
),
),
);
}
}
output:
Just simply use column widget in the label
TextButton.icon(
onPressed: () {},
icon: const Icon(Icons.home, color: Colors.white, size: 30.0),
label: Column(
children: const [
Text(
'Text Button Title',
style: TextStyle(fontFamily: 'Roboto', fontSize: 15.0, color: Colors.white),
),
Text(
'Text Button Subtitle',
style: TextStyle(fontFamily: 'Roboto', fontSize: 15.0, color: Colors.white),
),
],
),
style: TextButton.styleFrom(
padding: const EdgeInsets.fromLTRB(10.0, 8.0, 20.0, 8.0),
backgroundColor: const Color(0xFFD4D7DA),
),
),
OR
You can simply use Row widget
InkWell(
onTap: () {},
child: Container(
padding: const EdgeInsets.fromLTRB(10.0, 8.0, 20.0, 8.0),
color: const Color(0xFFD4D7DA),
child: Row(
children: const [
Icon(Icons.home, color: Colors.white, size: 30.0),
SizedBox(width: 12),
Expanded(
child: Text(
'Text Button 1',
softWrap: true,
style: TextStyle(fontFamily: 'Roboto', fontSize: 15.0, color: Colors.white),
),
),
],
),
),
),
To create UI like this, you just need to follow these steps:
Take a Column widget.
Inside column, take a Align(alignment:Alignment.left, child: Text("Menu Buttons") )
After that take two Rows
Row(children: [
Container(
height: 60,
width: 100,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [Icon(Icons.add), Text("Text")])),
Container(
height: 60,
width: 100,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [Icon(Icons.add), Text("Text")])),
]),

Issue increasing the width of the dialog box in flutter

I cannot seem to enter a trailing row of icons at the end of each card list view.
Is there a way of solving this using the same card code or should another method be used?
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
I decreased the amount of padding to increase the possible available space within the alert dialog box area.
contentPadding: EdgeInsets.all(5.0),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(10.0),
),
),
content: Stack(
overflow: Overflow.visible,
children: <Widget>[
Positioned(
right: -40.0,
top: -40.0,
// width: 600.0,
child: InkResponse(
onTap: () {
Navigator.of(context).pop();
},
child: CircleAvatar(
child: Icon(
Icons.close,
color: Colors.white,
),
backgroundColor: Colors.red,
maxRadius: 20.0,
),
),
),
Form(
key: _formKey,
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text(
'Choose a Submission Type',
style: TextStyle(
fontFamily: 'OpenSans',
fontSize: 18.0),
),
Divider(
height: 10.0,
),
Text(
'This campaign is available to creators with 3000 or more followers.',
textAlign: TextAlign.center,
style: TextStyle(
fontFamily: 'OpenSans',
fontSize: 14.0,
),
),
Card(
margin: EdgeInsets.zero,
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
ListTile(
leading:
const Icon(Icons.image),
title: Text(
'Post',
style: TextStyle(
fontFamily: 'OpenSans',
fontSize: 16.0,
fontWeight:
FontWeight.bold,
),
),
subtitle: Text(
'Single media file',
style: TextStyle(
fontFamily: 'OpenSans',
fontSize: 14.0,
),
),
This is where the issue lies with my code at present. I cannot edit the code to include the two additional icons. What is the best solution for including these trailing icons within this area.
// trailing: Row(
// children: <Widget>[
// Icon(
// FontAwesomeIcons
// .instagram,
// size: 10.0,
// ),
//// Icon(
//// FontAwesomeIcons
//// .facebook,
//// size: 10.0,
//// ),
// ],
// ),
),
],
),
),
All you need to do is add mainAxisSize: MainAxisSize.min, to the Row Like this
trailing: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Icon(
FontAwesomeIcons.instagram,
size: 10.0,
),
SizedBox(
width: 5,
),
Icon(
FontAwesomeIcons.facebook,
size: 10.0,
),
],
),
Let me know if this is what you want. I added that SizedBox too if that wasn't the look you wan't just take it out

Space between FlatButton in flutter

enter image description hereHello I am making an application where i need to maximize and minimise the screen.But i want to reduce space between 'A+'(i.e. maximising the screen) and 'A-'(i.e. minimising).I am attaching an image for better understanding.Thank you.
Here is the code:
return Scaffold(
appBar: AppBar(
title: Text(''),
backgroundColor: Color(0xFF125688),
actions: <Widget>[
FlatButton(
padding: EdgeInsets.all(0),
onPressed: null,
child: Text('A+',style: TextStyle(
fontSize: 22.0,fontWeight: FontWeight.bold,color: Colors.white
),)),
FlatButton(
padding: EdgeInsets.all(0),
onPressed: null,
child: Text('A-',style: TextStyle(
fontSize: 15.0,fontWeight: FontWeight.bold,color: Colors.white
),),
)
],
),
Use SizedBox
Scaffold(
appBar: AppBar(
title: Text(''),
titleSpacing: 10,
backgroundColor: Color(0xFF125688),
actions: <Widget>[
SizedBox(
width: 30,
child: FlatButton(
padding: EdgeInsets.all(0),
onPressed: null,
child: Text('A+',style: TextStyle(
fontSize: 22.0,fontWeight: FontWeight.bold,color: Colors.white
),))),
SizedBox(
width: 30,
child:FlatButton(
padding: EdgeInsets.all(0),
onPressed: null,
child: Text('A-',style: TextStyle(
fontSize: 15.0,fontWeight: FontWeight.bold,color: Colors.white
),),
))
],
))
Image of the Flatbutton:
Container(
decoration: new BoxDecoration(
color: Colors.white,
border: Border.all(color: Colors.blue, width: 1.0),
borderRadius: new BorderRadius.all(Radius.circular(3.0)),
),
width: double.infinity,
child: FlatButton(
padding: EdgeInsets.all(8.0),
onPressed: () {
// Write the function
},
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text("Add a Note"),
Icon(
Icons.note_add,
color: Colors.blue,
),
],
),
),
),