Flutter: add a floating action button to an image - dart

I'm trying to add a floating action button to an image. The button will be used to change the selected image. I want the button to float over the bottom right of the image. So far all I can do is add the floating action button directly below the image. Thanks for any help!
#override
Widget build(BuildContext context) {
// Create the view scaffold. Use a list view so things scroll.
return new Scaffold(
appBar: new AppBar(
title: new Text("My Title"),
),
body: new ListView(
children: [
new Container(
padding: EdgeInsets.zero,
child: new Image.asset(
"assets/images/background_image.png",
fit: BoxFit.fitWidth,
),
),
new FloatingActionButton(
child: const Icon(Icons.camera_alt),
backgroundColor: Colors.green.shade800,
onPressed: () {},
),
new Divider(),
new ListTile(
title: new Text('Email'),
leading: const Icon(Icons.email),
onTap: () {},
),
new Divider(),
],
),
);
}

You may use a Stack and Positioned widget, you can read about those widgets here:
Stack:
https://docs.flutter.io/flutter/widgets/Stack-class.html
Positioned:
https://docs.flutter.io/flutter/widgets/Positioned-class.html
return new Scaffold(
appBar: new AppBar(
title: new Text("My Title"),
),
body: new ListView(
children: [
Stack(
children: <Widget>[
new Container(
padding: EdgeInsets.zero,
child: new Image.asset(
"assets/images/background_image.png",
fit: BoxFit.fitWidth,
)),
Positioned(
right: 0.0,
bottom: 0.0,
child: new FloatingActionButton(
child: const Icon(Icons.camera_alt),
backgroundColor: Colors.green.shade800,
onPressed: () {},
),
),
],
),
new Divider(),
new ListTile(
title: new Text('Email'),
leading: const Icon(Icons.email),
onTap: () {},
),
new Divider(),
],
),
);

Related

How to fill the row with two buttons?

How to make two buttons expand equally over the entire width of the Navigation Drawer?
The main thing will be
ListTile(
title: Row(
children: <Widget>[
Expanded(child: RaisedButton(onPressed: () {},child: Text("Clear"),color: Colors.black,textColor: Colors.white,)),
Expanded(child: RaisedButton(onPressed: () {},child: Text("Filter"),color: Colors.black,textColor: Colors.white,)),
],
),
)
Complete Code
class SO extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
drawer: Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: <Widget>[
DrawerHeader(
child: Text('Drawer Header'),
decoration: BoxDecoration(
color: Colors.blue,
),
),
ListTile(
title: Text('Item 1'),
onTap: () {
// Update the state of the app
// ...
},
),
ListTile(
//contentPadding: EdgeInsets.all(<some value here>),//change for side padding
title: Row(
children: <Widget>[
Expanded(child: RaisedButton(onPressed: () {},child: Text("Clear"),color: Colors.black,textColor: Colors.white,)),
Expanded(child: RaisedButton(onPressed: () {},child: Text("Filter"),color: Colors.black,textColor: Colors.white,)),
],
),
)
],
),
),
);
}
}
This worked for me
Row(
children: <Widget>[
RaisedButton(
onPressed: () {
Route route =
MaterialPageRoute(builder: (context) => MinionFlare());
Navigator.push(context, route);
},
child: SizedBox(
width: MediaQuery.of(context).size.width * 0.4,
child: Text("Minion"),
),
),
RaisedButton(
onPressed: () {
Route route = MaterialPageRoute(
builder: (context) => EmojiRatingBar());
Navigator.push(context, route);
},
child: SizedBox(
width: MediaQuery.of(context).size.width * 0.4,
child: Text("Emoji")),
),
],
),
You can wrap each button with Expanded.
Row(
children : <Widget>[
Expanded(
child: Button(
child: Text("Clear")
)
),
Expanded(
child: Button(
child: Text("Filter")
)
),
])
Container(
height: 100,
child: Row(
children : <Widget>[
Expanded(
child: RaisedButton(
onPressed: () {},
color: Color(0xff0000ff),
child: Text("Left Button", style: TextStyle(color: Colors.white),)
)
),
Expanded(
child: RaisedButton(
onPressed: () {},
color: Color(0xffd4d4d4),
child: Text("Right Button")
)
),
])
)

How to add Drawer for SliverAppBar

This is my code, copied from here:
SliverAppBar(
expandedHeight: 150.0,
flexibleSpace: const FlexibleSpaceBar(
title: Text('Available seats'),
),
actions: < Widget > [
IconButton(
icon: const Icon(Icons.add_circle),
tooltip: 'Add new entry',
onPressed: () { /* ... */ },
),
]
)
But I need to add a Drawer. How can I do that?
I am trying to rebuild my app in Flutter.
Converting java android app to flutter
I replaced the icon but how can I create a Drawer?
leading: IconButton(icon: Icon( Icons.menu ),onPressed: ()=>{},)
My full code
#override
Widget build(BuildContext context) {
return NestedScrollView(
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
return <Widget>[
SliverAppBar(
leading: IconButton(
icon: Icon(Icons.menu),
onPressed: () => {},
),
actions: <Widget>[
IconButton(
onPressed: () => {},
icon: Icon(Icons.shopping_cart),
)
],
expandedHeight: 200.0,
floating: false,
pinned: true,
flexibleSpace: FlexibleSpaceBar(
centerTitle: true,
title: Text("My Pet Shop",
style: TextStyle(
color: Colors.white,
fontSize: 16.0,
)),
background: Image.network(
"https://firebasestorage.googleapis.com/v0/b/my-pet-world.appspot.com/o/images%2Fbannerads%2FxTmAblJI7fMF1l0nUa1gM32Kh9z1%2F734rm6w7bxznp%2FPETWORLD-HOME-SLIDER-KITTENS.webp?alt=media&token=cf7f48bb-6621-47b3-b3f8-d8b36fa89715",
fit: BoxFit.cover,
)),
),
];
},
body: Container(
margin: EdgeInsets.only(top: 0),
child: Column(
children: <Widget>[
Expanded(
//getHomePageWidget()
child: ListView(
padding: EdgeInsets.all(0.0),
children: <Widget>[getHomePageWidget()],
),
)
],
),
));
}
Drawer is a property for Scaffold. Once you set a drawer property, the menu icon will automatically appear in the SliverAppBar.
Return this inside your build method, and you will get what you are looking for.
return Scaffold(
body: CustomScrollView(
slivers: <Widget>[
SliverAppBar(
expandedHeight: 200.0,
flexibleSpace: const FlexibleSpaceBar(
title: Text('Available seats'),
),
actions: <Widget>[
IconButton(
icon: const Icon(Icons.add_circle),
tooltip: 'Add new entry',
onPressed: () {},
),
],
),
SliverList(
delegate: SliverChildListDelegate([
getHomePageWidget(),
]),
),
],
),
drawer: Drawer(),
);
NOTE: if you have multiple Scaffold in the tree above the CustomScrollView than the Drawer should be in the most bottom Scaffold

Change background color of Tab bar in flutter

I am trying to change the background color of the tab bar in flutter, I have tried the following ( which was accepted as an answer on this forum ) but it didnt work:
here is the code
return new MaterialApp(
theme: new ThemeData(
brightness: Brightness.light,
primaryColor: Colors.pink[800], //Changing this will change the color of the TabBar
accentColor: Colors.cyan[600],
),
EDIT :
When I change the theme data colors the background color doesnt change. Im trying to create a horizontal scrolling sub menu underneath the app bar and it was suggested I use a Tab bar.
Here is the entire dart file:
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
class Index extends StatelessWidget {
//final User user;
// HomeScreen({Key key, #required this.user}) : super(key: key);
#override
Widget build(BuildContext context) {
// TODO: implement build
// String emoji = emojify(":cool:");
return new MaterialApp(
theme: new ThemeData(
brightness: Brightness.light,
primaryColor: Colors.white, //Changing this will change the color of the TabBar
accentColor: Colors.cyan[600],
),
home: DefaultTabController(
length: 2,
child: Scaffold(
appBar: new AppBar(
backgroundColor: const Color(0xFF0099a9),
title: new Image.asset('images/lb_appbar_small.png', fit: BoxFit.none,),
bottom: TabBar(
tabs: [
Tab( text: "Tab 1",),
Tab(text: "Tab 2"),
],
),
),
body: Column(children: <Widget>[
Row(
//ROW 1
children: [
Container(
margin: EdgeInsets.all(25.0),
child: IconButton(
icon: new Icon(FontAwesomeIcons.checkSquare,),
iconSize: 60.0,
color: const Color(0xFF0099a9),
onPressed: () { print("Pressed"); }
),
),
Container(
margin: EdgeInsets.all(25.0),
child: IconButton(
icon: new Icon(FontAwesomeIcons.glasses,),
iconSize: 60.0,
color: const Color(0xFF0099a9),
onPressed: () { print("Pressed"); }
)
),
Container(
margin: EdgeInsets.all(25.0),
child: IconButton(
icon: new Icon(FontAwesomeIcons.moon,),
iconSize: 60.0,
color: const Color(0xFF0099a9),
onPressed: () { print("Pressed");
Text("Check Out");
}
)
),
]
),
Row(//ROW 2
children: [
Container(
margin: EdgeInsets.all(25.0),
child: IconButton(
icon: new Icon(FontAwesomeIcons.users,),
iconSize: 60.0,
color: const Color(0xFF0099a9),
onPressed: () { print("Pressed"); }
)
),
Container(
margin: EdgeInsets.all(25.0),
child: IconButton(
icon: new Icon(FontAwesomeIcons.trophy,),
iconSize: 60.0,
color: const Color(0xFF0099a9),
onPressed: () { print("Pressed"); }
)
),
Container(
margin: EdgeInsets.all(25.0),
child: IconButton(
icon: new Icon(FontAwesomeIcons.calendar,),
iconSize: 60.0,
color: const Color(0xFF0099a9),
onPressed: () { print("Pressed"); }
)
)
]),
Row(// ROW 3
children: [
Container(
margin: EdgeInsets.all(25.0),
child: IconButton(
icon: new Icon(FontAwesomeIcons.fileExcel,),
iconSize: 60.0,
color: const Color(0xFF0099a9),
onPressed: () { print("Pressed"); }
)
),
Container(
margin: EdgeInsets.all(25.0),
child: IconButton(
icon: new Icon(FontAwesomeIcons.shoppingCart,),
iconSize: 60.0,
color: const Color(0xFF0099a9),
onPressed: () { print("Pressed"); }
)
),
Container(
margin: EdgeInsets.all(25.0),
child: IconButton(
icon: new Icon(FontAwesomeIcons.list,),
iconSize: 60.0,
color: const Color(0xFF0099a9),
onPressed: () { print("Pressed"); }
)
),
]),
],
),
bottomNavigationBar: new BottomNavigationBar(
items: [
new BottomNavigationBarItem(
icon: new Icon(Icons.feedback, color: const Color(0xFF0099a9),),
title: new Text("feedback")
),
new BottomNavigationBarItem(
icon: new Icon(Icons.help, color: const Color(0xFF0099a9),),
title: new Text("help")
),
new BottomNavigationBarItem(
icon: new Icon(Icons.people, color: const Color(0xFF0099a9),),
title: new Text("community",)
)
]
)
)
)
);
}
}
You have the TabBar inside your AppBar for that reason it take the same color, just move the TabBar outside the Appbar
Scaffold(
appBar: new AppBar(
backgroundColor: const Color(0xFF0099a9),
title: new Image.asset(
'images/lb_appbar_small.png',
fit: BoxFit.none,
),
),
body: Column(
children: <Widget>[
TabBar(
tabs: [
Tab(
text: "Tab 1",
),
Tab(text: "Tab 2"),
],
),
Row(
//ROW 1
....
Hi you are getting same color since you have added tabbar in appbar,If you are looking for different color for both TabBar and Appbar. Here is what you have to do.
*Add TabBar in body of Scafold.
Sample Code:
class _SwapOfferPageState extends State<SwapOfferPage> with SingleTickerProviderStateMixin{
TabController _tabController;
#override
void initState() {
_tabController = new TabController(length: 2, vsync: this);
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Swap or Offer shift"),
centerTitle: true,
),
body: Column( // Column
children: <Widget>[
Container(
color: Color(0xffF5F5F5), // Tab Bar color change
child: TabBar( // TabBar
controller: _tabController,
labelColor: const Color(0xff959595),
indicatorWeight: 2,
indicatorColor: Color(0xff4961F6),
tabs: <Widget>[
Tab(
text: "SWAP MY SHIFT",
),
Tab(
text: "OFFER MY SHIFT",
),
],
),
),
Expanded(
flex: 3,
child: TabBarView( // Tab Bar View
physics: BouncingScrollPhysics(),
controller: _tabController,
children: <Widget>[
Text('Tab1'),
Text('Tab2'),
],
),
),
],
),
);
}
}
For anyone who is still looking for How to separate a TabBar from Appbar , please check the below code-
appBar: new AppBar(
title: new Text("some title"),
body: new Column(
children: [
/// this is will not colored with theme data
new TabBar(...),
Expanded(
new TabBarView(...)
)
]
)
)
You can change the Tabbar background-color, when Tabbar is inside the Material widget.
Material(
color: Colors.white, //Tabbar background-color
child: TabBar(
isScrollable: true,
labelStyle: Theme.of(context).tabBarTheme.labelStyle,
unselectedLabelStyle:
Theme.of(context).tabBarTheme.unselectedLabelStyle,
labelColor: Theme.of(context).tabBarTheme.labelColor,
unselectedLabelColor:
Theme.of(context).tabBarTheme.unselectedLabelColor,
indicatorColor: Theme.of(context).primaryColor,
tabs: [
Tab(text: 'tab 1'),
Tab(text: 'tab 2'),
Tab(text: 'tab 3'),
Tab(text: 'tab 4'),
],
),
),
Or you can even simply wrap the TabBar in a Container widget, and apply the "color" you want.

How to add notch to TabBar to place FloatingActionButton in it

I would like to create a notch inside the TabBar to place the FloatingActionBottom in it but I don't know how to do that.
I found nothing in the documentations or on the internet.
You can use the Bottom App Bar for this kind of User Interface
The hasNotch property of the BottomAppBar must be true.
This would get you what I am upto
Widget build(BuildContext context) {
return new Scaffold(
appBar: AppBar(title: const Text('Bottom App Bar')),
floatingActionButtonLocation:
FloatingActionButtonLocation.centerDocked,
floatingActionButton: FloatingActionButton(
child: const Icon(Icons.add), onPressed: () {},),
bottomNavigationBar: BottomAppBar(
hasNotch: true,
child: new Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
IconButton(icon: Icon(Icons.menu), onPressed: () {},),
IconButton(icon: Icon(Icons.search), onPressed: () {},),
],
),
),
);
}
Thank You!
Try implementing this revised version of the code. The FAB should persist across the three tabs
class BarTab extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: DefaultTabController(
length: 3,
child: Scaffold(
appBar: AppBar(
bottom: TabBar(
tabs: [
Tab(icon: Icon(Icons.directions_car)),
Tab(icon: Icon(Icons.directions_transit)),
Tab(icon: Icon(Icons.directions_bike)),
],
),
title: Text('Tabs Demo'),
),
body: TabBarView(
children: [
Icon(Icons.audio),
Icon(Icons.play),
Icon(Icons.maps),
],
),
floatingActionButton: FloatingActionButton(
onpressed:(){},
child: Icon(Icons.add),
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
bottomNavigationBar:BottomAppBar(
color:Colors.blue,
hasNotch: true,
child:Container(
height:50.0
child:Row(
children: <Widget>[
IconButton(
icon: Icon(Icons.menu),
onPressed: (){})
]
)
)
),
),
);
}
2020 solution:
hasNotch property is no more in BottomAppBar, however, you can do this in Scaffold
bottomNavigationBar: BottomAppBar(
shape: CircularNotchedRectangle(), //this is what creates the notch
color: Colors.blue,
child: SizedBox(
height: height * 0.1,
width: width,
),
),
floatingActionButton: Container(
margin: EdgeInsets.all(10),
width: 80.0,
height: 80.0,
child: FloatingActionButton(
onPressed: () {},
child: Icon(
Icons.add,
size: 25.0,
),
),
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked
output :

Flutter ButtonRow padding

I am developing an app in Flutter with Dart and am generally finding layout quite straightforward. However, I am running into a problem which I think is related to default padding between widgets.
I have two flutter ButtonRows in a Column which render with a quite large gap between them which I would like to eliminate. I guess it is caused by padding and have tried various approaches with no success so far. An extract from the code is as follows:
#override
Widget build(BuildContext context) {
return new Scaffold(
...
body: new Column(
...
children: <Widget>[
...
new Container(
margin: new EdgeInsets.all(0.0),
child: new Padding(
padding: new EdgeInsets.all(0.0),
child: new ButtonBar(
...
children: <Widget>[
new MaterialButton(
...
),
new MaterialButton(
...
),
),
),
),
),
new Container(
margin: new EdgeInsets.all(0.0),
child: new Padding(
padding: new EdgeInsets.all(0.0),
child: new ButtonBar(
...
children: <Widget>[
new MaterialButton(
...
),
new MaterialButton(
...
),
],
),
),
),
],
),
);
}
You have different ways to customize buttons:
customize ButtonTheme for ButtonBar
use Row instead of ButtonBar
implement your own button via InkWell
etc
What to use depends on your cases/requirements. Here quick example of different ways:
class ButtonRowWidget extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("Buttons"),
),
body: new Column(mainAxisSize: MainAxisSize.min, children: <Widget>[
new Container(
child: new Text("widget ButtonBar:"),
margin: new EdgeInsets.fromLTRB(0.0, 10.0, 0.0, 10.0),
),
new ButtonBar(children: <Widget>[
new FlatButton(
child: new Text("Button 1"),
onPressed: () => debugPrint("Button 1"),
),
new FlatButton(
child: new Text("Button 2"),
onPressed: () => debugPrint("Button 2"),
)
]),
new Container(
child: new Text("widget ButtonBar with custom ButtomTheme:"),
margin: new EdgeInsets.fromLTRB(0.0, 10.0, 0.0, 10.0),
),
new ButtonTheme(
minWidth: 44.0,
padding: new EdgeInsets.all(0.0),
child: new ButtonBar(children: <Widget>[
new FlatButton(
child: new Text("Button 1"),
onPressed: () => debugPrint("Button 1"),
),
new FlatButton(
child: new Text("Button 2"),
onPressed: () => debugPrint("Button 2"),
),
]),
),
new Container(
child: new Text("widget Row with FlatButton:"),
margin: new EdgeInsets.fromLTRB(0.0, 10.0, 0.0, 10.0),
),
new Row(
children: <Widget>[
new FlatButton(
child: new Text("Button 1"),
onPressed: () => debugPrint("Button 1"),
),
new FlatButton(
child: new Text("Button 2"),
onPressed: () => debugPrint("Button 2"),
),
],
),
new Container(
child: new Text("widget Row with InkWell"),
margin: new EdgeInsets.fromLTRB(0.0, 10.0, 0.0, 10.0),
),
new Row(
children: <Widget>[
new InkWell(
child: new Text("Button 1"),
onTap: () => debugPrint("Button 1"),
),
new InkWell(
child: new Text("Button 2"),
onTap: () => debugPrint("Button 2"),
),
],
)
]),
);
}
}
Debug paint can be helpful in this case.
Also, the ButtonBar itself has a buttonPadding attribute that you can customize.
Overrides the surrounding ButtonThemeData.padding to define the
padding for a button's child (typically the button's label).
If null then it will use the surrounding ButtonBarTheme.buttonPadding.
If that is null, it will default to 8.0 logical pixels on the left and
right.
ButtonBar(
buttonPadding: EdgeInsets.all(0),
children: <Widget>[
FlatButton(
child: Text('Hello'),
onPressed: () => print(),
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
),
],
),

Resources