Flutter Layout Builder Resizing Issues using Expanded() - flutter

I am trying to build a layout where 2 of my widgets are aligned to the bottom of the page and remain there when the window is resized. So far I use the following code and it works in keeping the footer at the bottom of the page:
return Scaffold(
appBar: AppBarDesktop(),
body: LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
return SingleChildScrollView(
child: ConstrainedBox(
constraints: constraints.copyWith(
minHeight: constraints.maxHeight, maxHeight: double.infinity),
child: IntrinsicHeight(
child: Column(
children: [
Container(
//height: 400,
child: Center(
child: Text(
"COMING SOON!",
style: Theme.of(context).textTheme.titleLarge,
),
),
),
newsletterWidget(),
Expanded(
child: Align(
alignment: Alignment.bottomCenter,
child: footerWidget(),
),
),
],
)),
),
);
},
),
);
My issues it that I Want to also have the newsletter anchored to the bottom to resize with the footer. I have tried placing a column within the Expanded Widget however that just breaks the functionality for both, I also tried putting the newsletter widget within the footerwidget however the issue is the same. Is there a way for me to have 2 Expanded widgets? or an alternative way to have 2 rows within one Expanded
Edit:
This is my footer widget:
class footerWidget extends StatelessWidget {
const footerWidget({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Container(
height: 40,
child: Center(
child: Row(
children: [
Padding(
padding: const EdgeInsets.only(left: 8.0),
child: Icon(
IconData(0xe198, fontFamily: 'MaterialIcons'),
size: 20,
),
),
Container(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
"MyGameDevPal 2022. All rights reserved.",
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.bodySmall,
),
),
),
Spacer(),
OnHoverButton(builder: (isHovered) {
return IconButton(
color: isHovered ? HexColor('#2476c4') : Colors.white,
icon: new Icon(FontAwesomeIcons.facebook),
onPressed: () {
_launchUrlFacebook();
},
);
}),
OnHoverButton(builder: (isHovered) {
return IconButton(
color: isHovered ? HexColor('#2476c4') : Colors.white,
icon: new Icon(FontAwesomeIcons.instagram),
onPressed: () {
_launchUrlInstagram();
},
);
}),
OnHoverButton(builder: (isHovered) {
return IconButton(
color: isHovered ? HexColor('#2476c4') : Colors.white,
icon: new Icon(FontAwesomeIcons.twitter),
onPressed: () {
_launchUrlTwitter();
},
);
}),
OnHoverButton(builder: (isHovered) {
return IconButton(
color: isHovered ? HexColor('#2476c4') : Colors.white,
icon: new Icon(FontAwesomeIcons.youtube),
onPressed: () {
_launchUrlYoutube();
},
);
}),
OnHoverButton(builder: (isHovered) {
return Padding(
padding: const EdgeInsets.only(right: 15),
child: IconButton(
color: isHovered ? HexColor('#2476c4') : Colors.white,
icon: new Icon(FontAwesomeIcons.discord),
onPressed: () {
_launchUrlDiscord();
},
),
);
}),
],
),
));
}
}

you can use Flixible instead of expanded tr it

Related

Flutter how to add a dialog screen over main screen like this

Hi all,
I would like to add a screen that slowly appears form the bottom or the screen and partially covers the main screen below. So you can still see the top part of the main screen. Does anyone know how to do this?
Thank you very much
for this you can use showModalBottomSheet method the simple example is
import 'package:flutter/material.dart';
void main() => runApp(const BottomSheetApp());
class BottomSheetApp extends StatelessWidget {
const BottomSheetApp({super.key});
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: const Text('Bottom Sheet Sample')),
body: const BottomSheetExample(),
),
);
}
}
class BottomSheetExample extends StatelessWidget {
const BottomSheetExample({super.key});
#override
Widget build(BuildContext context) {
return Center(
child: ElevatedButton(
child: const Text('showModalBottomSheet'),
onPressed: () {
showModalBottomSheet<void>(
context: context,
builder: (BuildContext context) {
return Container(
height: 200,
color: Colors.amber,
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
const Text('Modal BottomSheet'),
ElevatedButton(
child: const Text('Close BottomSheet'),
onPressed: () => Navigator.pop(context),
),
],
),
),
);
},
);
},
),
);
}
}
you can read more about this method here
You can use showModalBottomSheet() same as below...
showModalBottomSheet<void>(
// context and builder are
// required properties in this widget
context: context,
builder: (BuildContext context) {
// we set up a container inside which
// we create center column and display text
// Returning SizedBox instead of a Container
return SizedBox(
height: MediaQuery.of(context).size.height * 0.6,
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: const <Widget>[
Text('HERE You'll add all your content'),
],
),
),
);
},
);
You can call above method in
initState() of screen or buttons onPressed or onTap.
As per your shared Image I have try something like that Using ModalBottomSheet
Your Button Widget
ElevatedButton(
child: const Text('Show Modal BottomSheet'),
onPressed: () {
showModalBottomSheet<void>(
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(top: Radius.circular(25.0)),
),
context: context,
builder: (BuildContext context) {
return modelSheet(context);
},
);
},
)
bottomSheet Widget:
modelSheet(BuildContext context) {
return Container(
padding: const EdgeInsets.all(12),
decoration: const BoxDecoration(
borderRadius: BorderRadius.vertical(top: Radius.circular(25.0)),
),
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Icon(
Icons.hourglass_empty_outlined,
color: Colors.red,
size: 40,
),
const SizedBox(
height: 10,
),
const Text(
'Beta version',
style: TextStyle(
fontSize: 30,
fontWeight: FontWeight.bold,
),
),
const SizedBox(
height: 20,
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: const [
Icon(
Icons.check,
color: Colors.red,
),
Text('better price')
],
),
const SizedBox(
height: 10,
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: const [
Icon(
Icons.check,
color: Colors.red,
),
Text('early access')
],
),
const SizedBox(
height: 20,
),
RichText(
text: const TextSpan(
text:
'Please mind that this is a beta version of the app. As a founding member you can get',
style: TextStyle(fontSize: 20, color: Colors.black),
children: <TextSpan>[
TextSpan(
text: '50% off',
style: TextStyle(fontWeight: FontWeight.bold)),
TextSpan(text: ' the price & early access. !'),
],
),
),
const SizedBox(
height: 20,
),
const Text(
'You can look forward to more teachers and practices very soon.'),
const SizedBox(
height: 20,
),
ElevatedButton(
onPressed: () => Navigator.pop(context),
style: ElevatedButton.styleFrom(
backgroundColor: Colors.red,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20)),
fixedSize: const Size(double.maxFinite, 50)),
child: const Text('Got it'),
),
],
),
),
);
}
Result Screen->

Passing variables from Tab to DefaultTabController - Flutter

I have a DefaultTabController with two pages nested in a scaffold. In my scaffold's App Bar is a save button and I want this button to return a value to a previous page, based on a variable that is calculated in one of the tabs. How do I get this value?
Here is my DefaultTabController
DefaultTabController(
initialIndex: index,
length: 2,
child: Scaffold(
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
appBar: AppBar(
elevation: 0,
backgroundColor: fumigruen_accent,
leading: CloseButton(
color: Colors.black,
onPressed: () {
Navigator.of(context).pop();
},
),
actions: buildEditingActions(),
),
body: Column(children: [
tabBar(),
Expanded(
child: TabBarView(children: [
//1st Tab
GewichtsrechnerEinfach(),
//2nd Tab
Column()
]),
)
]),
));}
And here is the save-Button I want to use to pass a varaible to the previous screen
List<Widget> buildEditingActions() => [
ElevatedButton.icon(
style: ElevatedButton.styleFrom(
backgroundColor: fumigruen_accent,
elevation: 0,
foregroundColor: Colors.black,
),
onPressed: () {
Navigator.of(context).pop(gewicht);
},
icon: Icon(Icons.save),
label: Text("Speichern"))
];
The tabbar Code
Widget tabBar() => TabBar(
labelColor: Theme.of(context).primaryColor,
indicatorColor: Theme.of(context).primaryColor,
labelStyle: TextStyle(fontWeight: FontWeight.bold),
tabs: [
Tab(
child: Row(mainAxisSize: MainAxisSize.min, children: [
Icon(
Icons.assessment_outlined,
),
SizedBox(
width: 5,
),
Text("Einfach")
]),
),
Tab(
child: Row(mainAxisSize: MainAxisSize.min, children: [
Icon(
Icons.addchart,
),
SizedBox(
width: 5,
),
Text("Fortgeschritten")
]),
),
]);
and an extract of the GewichtsrechnerEinfach():
class _GewichtsrechnerEinfachState extends State<GewichtsrechnerEinfach> {
final _formKey = GlobalKey<FormState>();
num koerperlaenge = 0;
num brustumfang = 0;
var _koerperlaengeControler = TextEditingController();
var _brustumfangControler = TextEditingController();
num gewicht = 0;
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: SingleChildScrollView(
child: Form(
key: _formKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
//{two textinput fields setting the variables koerperlaenge and brustumfang are here}
Center(
child: Container(
width: MediaQuery.of(context).size.width * 0.8,
decoration: ThemeHelper().buttonBoxDecoration(context),
child: ElevatedButton(
style: ThemeHelper().buttonStyle(),
child: Padding(
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
child: Text(
"berechnen".toUpperCase(),
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
),
onPressed: () async {
if (_formKey.currentState!.validate()) {
setState(() {
gewicht = Gewichtskalkulator().einfach(
brustumfang.toDouble(),
koerperlaenge.toDouble());
});
}
}),
),
),
],
),
),
),
);
}
The variable "gewicht" is calculated and changed in the first tab "GewichtsrechnerEinfach". So how do I get the changed variable to this main screen so that I can use it while saving?
Thanks a lot :)
As I found out by chatting in comments section, you are changing a value in a Page and you want to use it in another pages or screen, this is why you should use StateManagement something like Provider.
As you said you need to change the gewicht variable and use it where ever you want.
step 1) please add provider: ^6.0.5 (or any version that is compatible) in your pubspec.yaml and call flutter pub get.
step 2) now you should create a provider class to make all the variables that you want to use everywhere, alive. please create a dart file named:
gewichtsrechner_einfach_provider.dart
step 3) now you should put these codes in you provider class:
import 'package:flutter/material.dart';
class GewichtsrechnerEinfachProvider extends ChangeNotifier{
num _gewicht = 0;
num get gewicht => _gewicht;
void setGewicht(num newGewicht){
_gewicht = newGewicht;
notifyListeners();
}
}
as you see _gewicht is private and you can use it alive entire your project.
step 4) you should add the provider to main.dart:
MultiProvider(
providers: [
// you are adding your provider
ListenableProvider.value(value: GewichtsrechnerEinfachProvider()),
],
child: MaterialApp(
debugShowCheckedModeBanner: false,
home: ...........
),
);
step 5) now you should use its setter and getter of gewicht:
as you see in _GewichtsrechnerEinfachState you are setting the value and should do this by using Consumer:
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: SingleChildScrollView(
child: Consumer<GewichtsrechnerEinfachProvider>(//note this
builder: (context, gewichtsrechnerEinfachProvider ,child) {
return Form(
key: _formKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
//{two textinput fields setting the variables koerperlaenge and brustumfang are here}
Center(
child: Container(
width: MediaQuery.of(context).size.width * 0.8,
decoration: ThemeHelper().buttonBoxDecoration(context),
child: ElevatedButton(
style: ThemeHelper().buttonStyle(),
child: Padding(
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
child: Text(
"berechnen".toUpperCase(),
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
),
onPressed: () async {
if (_formKey.currentState!.validate()) {
// and note this
gewichtsrechnerEinfachProvider.setGewicht(
Gewichtskalkulator().einfach(
brustumfang.toDouble(),
koerperlaenge.toDouble())
);
}
}),
),
),
],
),
);
}
),
),
);
}
step 6) now you should use its getter where ever you want:
List<Widget> buildEditingActions() => [
Consumer<GewichtsrechnerEinfachProvider>(
builder: (context, gewichtsrechnerEinfachProvider ,child) {
return ElevatedButton.icon(
style: ElevatedButton.styleFrom(
backgroundColor: fumigruen_accent,
elevation: 0,
foregroundColor: Colors.black,
),
onPressed: () {
// Navigator.of(context).pop(gewicht);
print('here is your result:
${gewichtsrechnerEinfachProvider.gewicht}');
},
icon: Icon(Icons.save),
label: Text("Speichern"));
}
)
];
note that you can use your provider where ever you want even with this code not just consumer:
var gewichtsrechnerEinfachProvider = Provider.of<GewichtsrechnerEinfachProvider>(context,listen: false);
as you see by changing its value the provider notifies to where you are showing it.
Ich hoffe, ich konnte dir helfen ;)
happy coding my friend...

How to make a color of custom widget transparent

I have a below screen and have a bottombar as the below image:
What I need now to make this bottom bar transparent, I tried to add transparent color by wraping the padding with a container and doesn't work fine...
this is the below code for the home screen:
import 'package:deliveryapp/domain/repository/api_repository.dart';
import 'package:deliveryapp/domain/repository/local_storage_repository.dart';
import 'package:deliveryapp/presentation/common/theme.dart';
import 'package:deliveryapp/presentation/provider/home/cart/cart_bloc.dart';
import 'package:deliveryapp/presentation/provider/home/cart/cart_screen.dart';
import 'package:deliveryapp/presentation/provider/home/home_bloc.dart';
import 'package:deliveryapp/presentation/provider/home/products/products_screen.dart';
import 'package:deliveryapp/presentation/provider/home/profile/profile_screen.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class HomeScreen extends StatelessWidget {
HomeScreen._();
static Widget init(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider(
create: (_) => HomeBLoC(
apiRepositoryInterface: context.read<ApiRepositoryInterface>(),
localRepositoryInterface: context.read<LocalRepositoryInterface>(),
)..loadUser(),
builder: (_, __) => HomeScreen._(),
),
],
);
}
#override
Widget build(BuildContext context) {
final bloc = Provider.of<HomeBLoC>(context);
return Scaffold(
body: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Expanded(
child: IndexedStack(
index: bloc.indexSelected,
children: [
ProductsScreen.init(context),
const Placeholder(),
const CartScreen(),
const Placeholder(),
ProfileScreen.init(context),
],
),
),
_DeliveryNavigationBar(
index: bloc.indexSelected,
),
],
),
);
}
}
class _DeliveryNavigationBar extends StatelessWidget {
final int index;
_DeliveryNavigationBar({
Key key,
this.index,
}) : super(key: key);
#override
Widget build(BuildContext context) {
final bloc = Provider.of<HomeBLoC>(context);
final cartBloc = Provider.of<CartBLoC>(context);
final user = bloc.user;
return Padding(
padding: const EdgeInsets.all(20.0),
child: DecoratedBox(
decoration: BoxDecoration(
color: Theme.of(context).canvasColor,
border: Border.all(
color: Theme.of(context).bottomAppBarColor,
width: 2,
),
borderRadius: BorderRadius.circular(25),
),
child: Padding(
padding: const EdgeInsets.all(5.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Expanded(
child: Material(
child: IconButton(
icon: Icon(
Icons.home,
color: index == 0
? DeliveryColors.green
: DeliveryColors.lightGrey,
),
onPressed: () => bloc.updateIndexSelected(0),
),
),
),
Expanded(
child: Material(
child: IconButton(
icon: Icon(
Icons.store,
color: index == 1
? DeliveryColors.green
: DeliveryColors.lightGrey,
),
onPressed: () => bloc.updateIndexSelected(1),
),
),
),
Expanded(
child: Material(
child: Center(
child: Stack(
children: [
CircleAvatar(
backgroundColor: DeliveryColors.blackBlue,
radius: 23,
child: IconButton(
icon: Icon(
Icons.shopping_basket,
color: index == 2
? DeliveryColors.green
: DeliveryColors.white,
),
onPressed: () => bloc.updateIndexSelected(2),
),
),
Positioned(
right: 0,
child: cartBloc.totalItems == 0
? const SizedBox.shrink()
: CircleAvatar(
radius: 10,
backgroundColor: Colors.pinkAccent,
child: Text(
cartBloc.totalItems.toString(),
),
),
),
],
),
),
),
),
Expanded(
child: Material(
child: IconButton(
icon: Icon(
Icons.favorite_border,
color: index == 3
? DeliveryColors.green
: DeliveryColors.lightGrey,
),
onPressed: () => bloc.updateIndexSelected(3),
),
),
),
Expanded(
child: InkWell(
onTap: () => bloc.updateIndexSelected(4),
child: user?.image == null
? const SizedBox.shrink()
: Center(
child: CircleAvatar(
radius: 15,
backgroundImage: AssetImage(
user.image,
),
),
),
),
),
],
),
),
),
);
}
}
You can use Opacity Class
A widget that makes its child partially transparent.
This class paints its child into an intermediate buffer and then blends the child back into the scene partially transparent.
which is especially designed for this usecase:
return Opacity(opacity: 0.5, child: Padding(...
Along with adding extendBody: true to your Scaffold:
Scaffold(extendBody: true, ...

Flutter - Issues when I try to filter the results (using SearchDelegate)

I got some problems to filter the results into the SearchDelegate.
Here is my code:
class CustomSearchDelegate extends SearchDelegate<String> {
List<DropdownMenuItem<String>> _listaItensDropCategorias;
List<DropdownMenuItem<String>> _listaItensDropEstados;
String _itemSelecionadoCategoria;
String _itemSelecionadoEstado;
_carregarItensDropdown(){
//Categorias
_listaItensDropCategorias = Configuracoes.getCategorias();
//Estados
_listaItensDropEstados = Configuracoes.getEstados();
}
_abrirDialog(BuildContext context) async {
_carregarItensDropdown();
return showDialog(
context: context,
barrierDismissible: true,
builder: (BuildContext context){
return StatefulBuilder(
builder: (BuildContext context,StateSetter setState){
return AlertDialog(
content: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Padding(
padding: EdgeInsets.only(top: 10, bottom: 20),
child: Text("Filtrar", style: TextStyle(color: Colors.black, fontWeight: FontWeight.bold, fontSize: 27),),
),
Padding(
padding: EdgeInsets.only(bottom: 5),
child: Row(
children: <Widget>[
Text("Categoria", style: TextStyle(color: Colors.grey, fontSize: 20),),
Expanded(
child: Wrap(
alignment: WrapAlignment.end,
children: <Widget>[
DropdownButton(
value: _itemSelecionadoCategoria,
items: _listaItensDropCategorias,
style: TextStyle(
fontSize: 20,
color: Colors.black
),
onChanged: (categoria){
setState(() {
_itemSelecionadoCategoria = categoria;
});
},
),
],
),
),
],
),
),
Padding(
padding: EdgeInsets.only(bottom: 5),
child: Row(
children: <Widget>[
Text("Estado", style: TextStyle(color: Colors.grey, fontSize: 20),),
Expanded(
child: Wrap(
alignment: WrapAlignment.end,
children: <Widget>[
DropdownButton(
value: _itemSelecionadoEstado,
items: _listaItensDropEstados,
style: TextStyle(
fontSize: 20,
color: Colors.black
),
onChanged: (estado){
setState(() {
_itemSelecionadoEstado = estado;
});
},
),
],
),
),
],
),
),
Padding(
padding: EdgeInsets.only(top: 30),
child: Row(
children: <Widget>[
Expanded(
child: Wrap(
alignment: WrapAlignment.end,
children: <Widget>[
Padding(
padding: EdgeInsets.only(right: 30),
child: GestureDetector(
child: Text(
"Aplicar",
style: TextStyle(color: Colors.lightBlue),
),
onTap: (){ //************************************Here is my problem
showResults(context);
Navigator.pop(context);
},
),
),
GestureDetector(
child: Text(
"Cancelar",
style: TextStyle(color: Colors.lightBlue),
),
onTap: (){
Navigator.pop(context);
},
),
],
),
),
],
),
),
],),
);
},
);
}
);
}
#override
List<Widget> buildActions(BuildContext context) {
return [
IconButton(
icon: Icon(Icons.clear),
onPressed: () {
query = "";
},
),
IconButton(
icon: Icon(Icons.tune),
onPressed: () {
_abrirDialog(context);
},
),
];
}
#override
Widget buildLeading(BuildContext context) {
return IconButton(
icon: Icon(Icons.arrow_back),
onPressed: () {
close(context, "");
},
);
}
#override
Widget buildResults(BuildContext context) {
return Pesquisar(query.toUpperCase(),_itemSelecionadoCategoria,_itemSelecionadoEstado);
}
}
As you can see, I build an "alertDialog" where the user can choose the filters (Categoria and Estado), and I put a GestureDetector "Aplicar" (see the image below) to apply automatically the filters and show results, but nothing happens when I press it.
But when I select the filters, type in the Search Field (see the image below) and press the search button (magnifying glass), the filters are applied.
P.S.: I know why it works when I press the search button, 'cause I passed the parameters ("_itemSelecionadoCategoria" , "_itemSelecionadoEstado") to the buildResults, where it answer when the search button is pressed.
So, my doubt is: What can I put in the onTap from GestureDetector "Aplicar" to give me the results with the filters applied? (I thought that putting "showResults(context)" in the "onTap" would solve my problem, but it didn't work).

How to create an admin UI left menu with Flutter [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I'm new to flutter but I have a curiosity. Considering the typical bootstrap admin UI that you can find online and the typical left menu, how would you recreate that with flutter? I'm particularly interested on a left menu that can be resized clicking on a button and on a sub-menu that can appear and disappear.
An example can be found here
Edit:
I want to be be clear about the effect I'm trying to reproduce as well. If you click the link relative to the example on the left you see a number of menu. For instance, clicking on Base you are going to see a vertical menu appearing and disappearing. I would like to know how to reproduce it as well.
Thanks
Thanks
I have tried to re-create the same design with some minor changes in Flutter. I have to enable flutter web support by following the instructions here:
Flutter Web
Regarding the left menu, I have used AnimatedSize widget to give the sliding drawer feel & placed it inside Row.
Please find the code below:
import 'package:flutter/material.dart';
final Color darkBlue = Color.fromARGB(255, 18, 32, 47);
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Center(
child: MyWidget(),
),
),
);
}
}
class MyWidget extends StatefulWidget {
#override
_MyWidgetState createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget>
with SingleTickerProviderStateMixin {
final colors = <Color>[Colors.indigo, Colors.blue, Colors.orange, Colors.red];
double _size = 250.0;
bool _large = true;
void _updateSize() {
setState(() {
_size = _large ? 250.0 : 0.0;
_large = !_large;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Row(
children: [
AnimatedSize(
curve: Curves.easeIn,
vsync: this,
duration: Duration(seconds: 1),
child: LeftDrawer(size: _size)),
Expanded(
flex: 4,
child: Container(
child: Column(
children: [
Container(
color: Colors.white,
padding: const EdgeInsets.all(8),
child: Row(
children: [
IconButton(
icon: Icon(Icons.menu, color: Colors.black87),
onPressed: () {
_updateSize();
},
),
FlatButton(
child: Text(
'Dashboard',
style: const TextStyle(color: Colors.black87),
),
onPressed: () {},
),
FlatButton(
child: Text(
'User',
style: const TextStyle(color: Colors.black87),
),
onPressed: () {},
),
FlatButton(
child: Text(
'Settings',
style: const TextStyle(color: Colors.black87),
),
onPressed: () {},
),
const Spacer(),
IconButton(
icon: Icon(Icons.brightness_3, color: Colors.black87),
onPressed: () {},
),
IconButton(
icon: Icon(Icons.notification_important,
color: Colors.black87),
onPressed: () {},
),
CircleAvatar(),
],
),
),
Container(
height: 1,
color: Colors.black12,
),
Card(
margin: EdgeInsets.zero,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(0),
),
child: Container(
color: Colors.white,
padding: const EdgeInsets.all(20),
child: Row(
children: [
Text(
'Home / Admin / Dashboard',
style: const TextStyle(color: Colors.black),
),
],
),
),
),
Expanded(
child: ListView(
children: [
Row(
children: [
_container(0),
_container(1),
_container(2),
_container(3),
],
),
Container(
height: 400,
color: Color(0xFFE7E7E7),
padding: const EdgeInsets.all(16),
child: Card(
color: Colors.white,
child: Container(
padding: const EdgeInsets.all(16),
child: Text(
'Traffic',
style: const TextStyle(color: Colors.black87),
),
),
),
),
],
),
),
],
),
),
),
],
),
);
}
Widget _container(int index) {
return Expanded(
child: Container(
padding: const EdgeInsets.all(20),
color: Color(0xFFE7E7E7),
child: Card(
color: Color(0xFFE7E7E7),
child: Container(
color: colors[index],
width: 250,
height: 140,
padding: const EdgeInsets.all(20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Expanded(
child: Text(
'9.823',
style: TextStyle(fontSize: 24),
)),
Icon(Icons.more_vert),
],
),
Text('Members online')
],
),
),
),
),
);
}
}
class LeftDrawer extends StatelessWidget {
const LeftDrawer({
Key key,
this.size,
}) : super(key: key);
final double size;
#override
Widget build(BuildContext context) {
return Expanded(
flex: 1,
child: Container(
width: size,
color: const Color(0xFF2C3C56),
child: ListView(
children: [
Container(
alignment: Alignment.center,
padding: const EdgeInsets.all(16),
color: Color(0xFF223047),
child: Text('CORE UI'),
),
_tile('Dashboard'),
Container(
padding: const EdgeInsets.only(left: 10),
margin: const EdgeInsets.only(top: 30),
child: Text('THEME',
style: TextStyle(
color: Colors.white54,
))),
_tile('Colors'),
_tile('Typography'),
_tile('Base'),
_tile('Buttons'),
],
),
),
);
}
Widget _tile(String label) {
return ListTile(
title: Text(label),
onTap: () {},
);
}
}
You can use the Drawer widget inside a Scaffold. If you want the navigation drawer to be able to resize according to the browser height and width you can use the responsive_scaffold package.