I have a screen like this:
I'm trying to place the floatActionButton at the bottom right, but I couldn't.I'm putting the floatActionButton, but I couldn't put it in the bottom right.
How can I put it in the bottom right?
Codes:
Container(
child: Padding(
padding: EdgeInsets.only(left: 8, right: 8, bottom: 40),
child: Column(
children: [
SizedBox(height: 15,),
Text("Profile", style: TextStyle(fontSize: 27),),
Divider(thickness: 1, color: Colors.black,),
SizedBox(height: 5),
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("Solved Tests:",style: TextStyle(fontSize: 19)),
],
),
SizedBox(height: 20,),
Container(
width: double.infinity,
height: 200,
child: Expanded(
child: FutureBuilder(
future: listUpload(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
late List<String?> items;
if (!snapshot.hasData){
return Text("Not found");
}
if (snapshot.connectionState == ConnectionState.waiting) {
items = [];
} else if (snapshot.connectionState == ConnectionState.done &&
snapshot.hasData) {
items = snapshot.data as List<String?>;
} else {
items = [];
}
return Scrollbar(
isAlwaysShown: true,
controller: _scrollContreller,
scrollbarOrientation: ScrollbarOrientation.right,
child: ListView.builder(
controller: _scrollContreller,
itemCount: items.length,
itemBuilder: (BuildContext context, int index) {
return Padding(
padding: const EdgeInsets.only(bottom: 20, left: 10, right: 10),
child: Container(
decoration: BoxDecoration(
color: Colors.grey[300],
borderRadius: BorderRadius.circular(10),
),
child: ListTile(
title: Text(
items[index].toString(),
style: TextStyle(fontSize: 20),
),
),
),
);
},
),
);
})),
),
Container(
decoration: BoxDecoration(
color: Colors.red,
borderRadius: BorderRadius.circular(10),
),
),
SizedBox(height: 15,),
Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.only(left: 10),
child: Container(
width: 250,
height: 40,
child: GFButton(
text: "Temizle", textStyle: TextStyle(fontSize: 20, color: Colors.red),
color: Colors.red,
type: GFButtonType.outline2x,
onPressed: () {
AlertDialog eminlik = AlertDialog(
title: Text("Onay"),
content: Text("Çözdüğünüz testlerin kayıtları silinecektir. Emin misiniz?"),
actions: [
FlatButton(
child: Text("Evet"),
onPressed: () {
Navigator.pop(context);
setState(() {
eminlikSil();
});
},
),
FlatButton(
child: Text("Hayır"),
onPressed: () {
Navigator.pop(context);
},
)
],
);
showDialog(context: context, builder: (context) => eminlik);
},
),
),
),
],
),
),
// !!!!!!!!!!! <<<<<<<<<
// !!!!!!!!!!! <<<<<<<<<
FloatingActionButton(
child: Text("FAB"),
onPressed: () {}),
],
),
),
),
In the code I provided, I commented out where I put the floatActionButton.I put the codes of the screen in the picture directly. floatActionButton codes are below.
Thanks in advance for the help.
Looks like you want the achieve the default material design behaviour, in that case use a Scaffold and set the floatingActionButton value
return Scaffold(
body: , // paste your page content here
floatingActionButton: FloatingActionButton(
child: Text("FAB"),
onPressed: () {},
),
);
Your floating action button will placed at the bottom because it's the default behaviour, if you want to change that play with the value of floatingActionButtonLocation
if you don't want to relay on Scaffold use a Stack widget instead
return Stack(
children: [
// paste your page content here
Align(
alignment: Alignment.bottomRight,
child: FloatingActionButton(
child: Text("FAB"),
onPressed: () {},
),
)
],
);
You just need to put the floatingActionButton as a named parameter of Scaffold.
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Floating Action Button'),
),
body: const Center(child: Text('Press the button below!')),
floatingActionButton: FloatingActionButton(
onPressed: () {
// Add your onPressed code here!
},
backgroundColor: Colors.green,
child: const Icon(Icons.add),
),
);
}
Reference: official flutter documentation
The easiest way to add a FloatingActionButton is to add it directly to your Scaffold.
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(),
floatingActionButton: FloatingActionButton(
onPressed: () {},
tooltip: 'Increment',
child: const Icon(Icons.add),
),
);
}
Another solution would be to encapsulate your view in a Stack and to add your FloatingActionButton in an Align.
#override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(children: [
Container(),
Align(
alignment: Alignment.bottomRight,
child: FloatingActionButton(
onPressed: () {},
tooltip: 'Increment',
child: const Icon(Icons.add),
),
)
],)
);
}
Well, if you're using Scaffold, it has floatingActionButton parameter. Where you should put your float, and if it doesn't place it to position you want you can correct it with floatingActionButtonLocation parameter.
Example:
Scaffold(
floatingActionButton: FloatingActionButton(
onPressed: () {},
child: Icon(Icons.add),
),
floatingActionButtonLocation: FloatingActionButtonLocation.endDocked,
)
Otherwise, you can wrap FloatActionButton with Align widget. And give it alignment as you want.
You can set Alignment for use Container or Align Widget .
Using Container:
Container(
alignment: Alignment.bottomRight,
child: FloatingActionButton(
onPressed: () {},
child: Icon(
Icons.add,
),
),
),
Using Align:
Align(
alignment: Alignment.bottomRight,
child: Container(
child: FloatingActionButton(
hoverColor: Colors.black,
elevation: 10,
onPressed: () {},
child: Icon(
Icons.add,
),
),
),
),
Using Scaffold:
Scaffold(
floatingActionButton: FloatingActionButton(
onPressed: () {},
child: Icon(Icons.add),
),
floatingActionButtonLocation: FloatingActionButtonLocation.endDocked,
);
Result Screen->
Related
I want the dialog to open when a button is clicked, but an error occurs due to BLoC. Previously, there was such an error with the class itself, but I successfully solved it, and in this case, the complexity already arises. I've already tried a couple of options but couldn't solve it. I tried to make the event in onPressed as a separate widget, and the same error did not work either.
home_page
class HomePage extends StatelessWidget {
final todoRepository = TodoRepository();
#override
Widget build(BuildContext context) {
// final TodoBloc todoBloc = context.read<TodoBloc>();
return BlocProvider<TodoBloc>(
create: (context) => TodoBloc(todoRepository),
child: Scaffold(
appBar: AppBar(
title: const Text('Flutter Todos'),
),
// floatingActionButton: FloatingActionButton(
// onPressed: () {
// // _addTodo(context);
// final newTodo = Todo(description: 'Todo 1');
// BlocProvider.of<TodoBloc>(context).add(CreateTodos(newTodo));
// },
// child: const Icon(Icons.add),
// ),
body: SingleChildScrollView(
child: Column(
// crossAxisAlignment: CrossAxisAlignment.center,
children: [
// ActionButton(),
TodoList(),
],
),
),
floatingActionButton: FloatingActionButton(
child: const Icon(Icons.add, size: 32, color: Colors.black),
onPressed: () {
// showAddTodoSheet(context);
// showAddTodoSheet(BuildContext context) {
final TodoBloc todoBloc = context.read<TodoBloc>();
final _todoDescriptionFromController = TextEditingController();
showModalBottomSheet(
context: context,
builder: (builder) {
return BlocBuilder<TodoBloc, TodoState>(
builder: (context, state) {
return Padding(
padding: EdgeInsets.only(
bottom: MediaQuery.of(context).viewInsets.bottom),
child: Container(
color: Colors.transparent,
child: Container(
height: 230,
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(10.0),
topRight: Radius.circular(10.0))),
child: Padding(
padding: const EdgeInsets.only(
left: 15, top: 25.0, right: 15, bottom: 30),
child: ListView(
children: <Widget>[
Row(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment:
CrossAxisAlignment.center,
children: <Widget>[
Expanded(
child: TextFormField(
controller:
_todoDescriptionFromController,
textInputAction:
TextInputAction.newline,
maxLines: 4,
style: const TextStyle(
fontSize: 21,
fontWeight: FontWeight.w400),
autofocus: true,
decoration: const InputDecoration(
hintText: 'I have to...',
labelText: 'New Todo',
labelStyle: TextStyle(
color: Colors.indigoAccent,
fontWeight: FontWeight.w500)),
validator: (value) {
if (value!.isEmpty) {
return 'Empty description!';
}
return value.contains('')
? 'Do not use the # char.'
: null;
},
),
),
Padding(
padding: const EdgeInsets.only(
left: 5, top: 15),
child: CircleAvatar(
backgroundColor: Colors.indigoAccent,
radius: 18,
child: IconButton(
icon: const Icon(
Icons.save,
size: 22,
color: Colors.white,
),
onPressed: () {
final newTodo = Todo(
description:
_todoDescriptionFromController
.value.text);
if (newTodo
.description.isNotEmpty) {
todoBloc
.add(CreateTodos(newTodo));
Navigator.pop(context);
}
},
),
),
)
],
),
],
),
),
),
),
);
});
});
},
),
));
}
You have to use MultiBlocProvider before MaterialApp.
just do like that
#override
Widget build(BuildContext context) => MultiBlocProvider(
providers: [
BlocProvider(create: (_) => TodoBloc()),
],
child: MaterialApp()
);
I want that Cancellation charges and the bottom button remains fixed on screen, while the Choose Seat(s) and passengers should be scrollable. But, whenever I am trying to insert any widget after singlechildscrollview, it is not appearing at the bottom.
As, my column has 3 widgets, a row, singlechildscrollview and button, so my button and top row should remain there and remaining seats and passengers should be scrollable, but I am not able to see the bottom button, while my row working fine, remaining there.
Code -
showCancellationCharges(BuildContext? context) {
final DateTime currentDate = DateTime.now();
if (ticketData!.data!.booking!.boarding!.eta! >
currentDate.millisecondsSinceEpoch)
showModalBottomSheet(
backgroundColor: Colors.white,
context: context!,
builder: (context) => Wrap(
children: [
StatefulBuilder(
builder: (context, stateSetter) => Padding(
padding: MediaQuery.of(context).viewInsets,
child: Container(
//height: MediaQuery.of(context).size.height*0.7,
child: Container(
padding: EdgeInsets.symmetric(horizontal: 16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Padding(
padding: const EdgeInsets.only(top: 5.0, bottom: 5.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'Cancellation Charges',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 20,
)
),
IconButton(
icon: Icon(
Icons.close,
color: colorPrimary,
),
onPressed: () {
Navigator.of(context).pop();
},
),
],
),
),
Container(
height: MediaQuery.of(context).size.height*0.5,
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0),
child: Text(
'Choose Seat(s)',
style: TextStyle(color: popUpLightTextColor),
),
),
Column(
children: List.generate(
ticketData!.data!.booking!.seats!.length,
(index) => CancellationItem(
checkBoxState: ticketData!.data!.booking!
.seats![index].selected,
checkBox: (v) => stateSetter(() {
print('seat at index $index $v');
if (v)
totalSeatToCancel++;
else
totalSeatToCancel--;
ticketData!.data!.booking!.seats![index]
.selected = v;
}),
// checkBoxState: data[index.],
imagePath:
'assets/icons/ticket_seat_icon.svg',
title: ticketData!
.data!.booking!.seats![index].code,
)),
),
// CancellationSeatItems(
// data: ticketData.data.booking.seats,
// ),
Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0),
child: Text(
'Choose Passenger(s)',
style: TextStyle(color: popUpLightTextColor),
),
),
Column(
children: List.generate(
ticketData!.data!.booking!.passengers!.length,
(index) => CancellationItem(
checkBoxState: ticketData!.data!.booking!
.passengers![index].selected,
checkBox: (v) => stateSetter(() {
if (v)
totalPassengerToCancel++;
else
totalPassengerToCancel--;
print('passenger at index $index $v');
ticketData!.data!.booking!
.passengers![index].selected = v;
}),
imagePath: (ticketData!.data!.booking!
.passengers![index].gender ==
'MALE')
? 'assets/icons/male_icon.svg'
: 'assets/icons/female_icon.svg',
title: ticketData!.data!.booking!
.passengers![index].name,
)),
),
],
),
),
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 16),
child: Container(
child: ValueListenableBuilder(
valueListenable: isCalculating,
builder: (BuildContext context, bool val, Widget? child) {
return FlatButton(
height: 44,
minWidth: MediaQuery.of(context).size.width,
color: val ? Colors.grey : colorPrimary,
onPressed: () => calculateItem(),
child: Text(
val ? 'Calculating...' : 'Calculate',
style: TextStyle(
color: Colors.white,
fontSize: 16
),
),
);
},
),
),
),
// CancellationPassengerItems(
// data: ticketData.data.booking.passengers,
// ),
],
),
),
),
),
),
],
));
else
_snackbarService.showSnackbar(
message: 'Sorry, ticket can not be cancelled');
}
Actually I solved the problem. I just used isScrollControlled: true, parameter for showModalBottomSheet and it's done.
you may put the listview inside a container with a height
I'm working in a restaurant delivery app, I purchase it in Codecanyon but the support is so bad... I discover a bug in a Cart Dart and the scroll don't work... I receive the "Bottom Overflow Error"
I try all Google tutorials but don't have idea what is bad.
This is my code:
#override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: Helper.of(context).onWillPop,
child: Scaffold(
key: _con.scaffoldKey,
bottomNavigationBar: CartBottomDetailsWidget(con: _con),
appBar: AppBar(
automaticallyImplyLeading: false,
leading: IconButton(
onPressed: () {
if (widget.routeArgument != null) {
Navigator.of(context).pushReplacementNamed(widget.routeArgument.param, arguments: RouteArgument(id: widget.routeArgument.id));
} else {
Navigator.of(context).pushReplacementNamed('/Pages', arguments: 2);
}
},
icon: Icon(Icons.arrow_back),
color: Theme.of(context).hintColor,
),
backgroundColor: Colors.transparent,
elevation: 0,
centerTitle: true,
title: Text(
S.of(context).cart,
style: Theme.of(context).textTheme.headline6.merge(TextStyle(letterSpacing: 1.3)),
),
),
body: RefreshIndicator(
onRefresh: _con.refreshCarts,
child: _con.carts.isEmpty
? EmptyCartWidget()
: Stack(
alignment: AlignmentDirectional.bottomCenter,
children: [
Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.only(left: 20, right: 10),
child: ListTile(
contentPadding: EdgeInsets.symmetric(vertical: 0),
leading: Icon(
Icons.shopping_cart,
color: Theme.of(context).hintColor,
),
title: Text(
S.of(context).shopping_cart,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: Theme.of(context).textTheme.headline4,
),
subtitle: Text(
S.of(context).verify_your_quantity_and_click_checkout,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: Theme.of(context).textTheme.caption,
),
),
),
ListView.separated(
padding: EdgeInsets.symmetric(vertical: 15),
scrollDirection: Axis.vertical,
shrinkWrap: true,
primary: true,
itemCount: _con.carts.length,
separatorBuilder: (context, index) {
return SizedBox(height: 15);
},
itemBuilder: (context, index) {
return CartItemWidget(
cart: _con.carts.elementAt(index),
heroTag: 'cart',
increment: () {
_con.incrementQuantity(_con.carts.elementAt(index));
},
decrement: () {
_con.decrementQuantity(_con.carts.elementAt(index));
},
onDismissed: () {
_con.removeFromCart(_con.carts.elementAt(index));
},
);
},
),`
Without trying this but perhaps put Expanded around the ListView
Being a direct child of a Column it does not know how big it should be.
Expanded(
child: ListView.separated(...)
)
my buttons are must be on center but must aligned in same line ,
the text in side button also should aligned left.
for that i use textalign left but not works in my code , I dont know why.This is my layout screenshot.
So Can anyone modify my code so that the text inside button aligned left ,without affecting my buttons position .
Thank you
class Something extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Solve Before Downvote !'),
),
body: Container(
color: Color(0xff263238),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SingleChildScrollView(
child: Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
MaterialButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0)),
padding: EdgeInsets.only(left: 5),
color: Colors.green,
onPressed: () {},
child: Text('SomeThing', textAlign: TextAlign.left),
),
MaterialButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0)),
color: Colors.green,
onPressed: () { },
child: Text('Nothing', textAlign: TextAlign.left),
),
MaterialButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0)),
color: Colors.green,
onPressed: () {},
child: Text('Can You do something ?',
textAlign: TextAlign.left),
),
MaterialButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0)),
color: Colors.green,
onPressed: () {},
child: Text('Nothing to do !', textAlign: TextAlign.left),
),
],
),
),
)
],
),
),
);
}
}
what i made
Please check the below code. I have comment out the solution in code.
class Something extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Solve Before Downvote !'),
),
body: Container(
width: MediaQuery.of(context).size.width,
color: Color(0xff263238),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SingleChildScrollView(
child: Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.all(2.0),
child: Material(
color: Colors.green,
borderRadius: BorderRadius.circular(10.0),
child: InkWell(
onTap: () {
setState(() {
abc = true;
});
},
child: Padding(
padding: const EdgeInsets.fromLTRB(0, 12, 15, 12),
child: Text('SomeThing', textAlign: TextAlign.left),
),
),
),
),
Padding(
padding: const EdgeInsets.all(2.0),
child: Material(
color: Colors.green,
borderRadius: BorderRadius.circular(10.0),
child: InkWell(
onTap: () {
setState(() {
abc = true;
});
},
child: Padding(
padding: const EdgeInsets.fromLTRB(0, 12, 15, 12),
child: Text('Nothing', textAlign: TextAlign.left),
),
),
),
),
Padding(
padding: const EdgeInsets.all(2.0),
child: Material(
color: Colors.green,
borderRadius: BorderRadius.circular(10.0),
child: InkWell(
onTap: () {
setState(() {
abc = true;
});
},
child: Padding(
padding: const EdgeInsets.fromLTRB(0, 12, 15, 12),
child: Text('Can You do something ?',
textAlign: TextAlign.left),
),
),
),
),
Padding(
padding: const EdgeInsets.all(2.0),
child: Material(
color: Colors.green,
borderRadius: BorderRadius.circular(10.0),
child: InkWell(
onTap: () {
setState(() {
abc = true;
});
},
child: Padding(
padding: const EdgeInsets.fromLTRB(0, 12, 15, 12),
child: Text('Nothing to do !',
textAlign: TextAlign.left),
),
),
),
),
],
),
),
)
],
),
),
);
}
}
Can you add Align() and set alignment : Alignment.centerLeft before widget child text
I am using bottom app bar for bottomnavigation in flutter. when tapped on one of the tab in the bottom app bar, i would still want the bottom app bar and app bar to remain as it is in it's fixed position but only the body content changes based on what is tapped.
I have tried to use push() method but it gives me a new page instead with a back button.
Navigation_tabs.dart:
import 'package:flutter/material.dart';
class NavigationTabs extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new Scaffold(
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
floatingActionButton: FloatingActionButton(
child: const Icon(Icons.add),
onPressed: () {},
),
appBar: AppBar(
title: Text('Dashboard'),
),
bottomNavigationBar: BottomAppBar(
shape: CircularNotchedRectangle(),
notchMargin: 4.0,
child: new Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
IconButton(
icon: Icon(
Icons.home,
color: Colors.cyan[700],
),
onPressed: () {},
),
new Container(
padding: EdgeInsets.only(left: 20),
child: IconButton(
icon: Icon(
Icons.list,
color: Colors.cyan[700],
),
onPressed: () => Navigator.pushNamed(context, '/login'),
)),
new Container(
padding: EdgeInsets.only(left: 120),
child: IconButton(
icon: Icon(
Icons.explore,
color: Colors.cyan[700],
),
onPressed: () {},
)),
new Container(
height: 22.0,
child: new RawMaterialButton(
onPressed: () {},
child: new Icon(
Icons.person,
color: Colors.white,
size: 20.0,
),
shape: new CircleBorder(),
elevation: 1.0,
fillColor: Colors.cyan[700],
))
],
),
));
}
}
I want to be able to only make the page content change without a back button instead of going to a completely new page when one of the tabs is pressed.
You can use a BottomNavigationBarItem instead of creating buttons and use the ontap of the bottomNavigationBar.
class _MyHomePageState extends State<MyHomePage> {
int _index = 0;
final List<Widget> _children = [
Center(child: Text("First Page"),),
Center(child: Text("Second Page"),),
Center(child: Text("Third Page"),)
];
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Bottom Navigation"),
),
body: Center(
child: (_children[_index ]),
),
bottomNavigationBar: BottomNavigationBar(
onTap: onTabTapped,
currentIndex: _currentIndex,
items: [
BottomNavigationBarItem(
icon: Icon(Icons.looks_one),
title: Text('First'),
),
BottomNavigationBarItem(
icon: Icon(Icons.looks_two),
title: Text('Second'),
),
BottomNavigationBarItem(
icon: Icon(Icons.looks_3),
title: Text('Third'),
)
],
),
);
}
void onTabTapped(int index) {
setState(() {
_index = index;
});
}
}
For more detailed explanation:
Flutter documentation