I'm a beginner trying to practice coding with Flutter so it would be helpful if the explanation or suggestion is easy to understand. :) Thanks in advance!
[Goal]
I've created a two folders and one of them is for parts that can be used in multiple places without having to create them every time. And the other one includes files with different pages (I like to keep them separate).
[Question]
I'm currently trying to navigate by using the side drawer and want to go to other pages, however it's not working and I'm getting blanks in black :( Please help...
In this case, should I use the "routes:" argument or should I use the MaterialPageRoute() or is there something else that can be suggested?
I apologize for posting the entire code, but I thought it would be best to understand the whole context. If there's anything that seems odd or have a better idea. Please do let me know!
[Code of Drawer]
class AppDrawer extends StatefulWidget {
#override
_AppDrawerState createState() => _AppDrawerState();
}
class _AppDrawerState extends State<AppDrawer> {
#override
Widget build(BuildContext context) {
return Drawer(
child: ListView(
children: <Widget>[
UserAccountsDrawerHeader(
accountName: Text('John T.'),
accountEmail: Text('*********#gmail.com'),
currentAccountPicture: GestureDetector(
child: CircleAvatar(
backgroundColor: Colors.grey,
child: Icon(Icons.person, color: Colors.white))),
decoration: BoxDecoration(color: Colors.red)),
ListTile(
leading: Icon(Icons.home, color: Colors.redAccent),
title: Text('Home'),
trailing: null,
onTap: () {
Navigator.of(context).pop();
Navigator.of(context).push(
MaterialPageRoute(
builder: (BuildContext context) {
Home();
},
),
);
},
),
ListTile(
leading: Icon(Icons.person, color: Colors.redAccent),
title: Text('My Acount'),
trailing: null,
onTap: () {
Navigator.of(context).pop();
Navigator.of(context).push(
MaterialPageRoute(
builder: (BuildContext context) {
MyAccount();
},
),
);
},
),
ListTile(
leading: Icon(Icons.fitness_center, color: Colors.redAccent),
title: Text('My Workout'),
trailing: null,
onTap: () {},
),
ListTile(
leading: Icon(Icons.cancel, color: Colors.redAccent),
title: Text('My Nutrition'),
trailing: null,
onTap: () {},
),
Divider(color: Colors.red, indent: 20.0),
ListTile(
leading: Icon(Icons.settings, color: Colors.blue),
title: Text('Settings'),
trailing: null,
onTap: () {},
),
ListTile(
leading: Icon(Icons.help, color: Colors.green),
title: Text('About'),
trailing: null,
onTap: () {},
),
],
),
);
}
}
[Code of Home Page]
class Home extends StatefulWidget {
#override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
elevation: 5.0,
title: Text('Home'),
backgroundColor: Colors.red,
centerTitle: true,
),
endDrawer: AppDrawer(),
body: Container(
color: Colors.white,
child: Center(
child: ListView(
children: <Widget>[],
),
),
),
);
}
}
[My Account Page]
class MyAccount extends StatefulWidget {
final String value;
MyAccount({Key key, this.value}) : super (key: key);
#override
_MyAccountState createState() => _MyAccountState();
}
class _MyAccountState extends State<MyAccount> {
final TextEditingController _ageFieldController = TextEditingController();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('My Account'),
centerTitle: true,
backgroundColor: Colors.blue,
),
endDrawer: AppDrawer(),
body: Container(
color: Colors.white,
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
child: Column(
children: <Widget>[
TextField(
controller: _ageFieldController,
decoration: InputDecoration(
hintText: 'Example: 27',
),
autocorrect: true,
keyboardType: TextInputType.number,
),
Text('${widget.value}')
],
),
),
],
),
),
),
);
}
}
[Code of Main.dart]
void main(List<String> args) {
runApp(Bmi());
}
class Bmi extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'BMI',
theme: ThemeData(
primarySwatch: Colors.deepPurple,
),
home: Home(),
);
}
}
The Material Design guidelines suggest a Drawer for navigation between sites of equal importance, so Navigator.push() should not be used, because the animation it does looks like it's a linear navigation(like going to the next page, not one of equal importance.)
Here's a link regarding this topic: material.io site for Navigation Drawer Component
I always update my body according to the currently selected item in the drawer, similar as you would do it with a BottomNavigationBar.
An implementation of that would look similar to this:
return Scaffold(
drawer: Drawer(),
body: Stack(
children: <Widget>[
Offstage(
offstage: index != 0,
child: _buildAccountPage(),
),
Offstage(
offstage: index != 0,
child: _buildHomePage(),
),
],
),
);
You need to return New Page to the Builder Function of Navigator.
Correct Code:
ListTile(
leading: Icon(Icons.person, color: Colors.redAccent),
title: Text('My Acount'),
onTap: () {
Navigator.push(context,
MaterialPageRoute(builder: (context) => MyAccount()));
},
),
Related
Content of this code is after a QR scan it need alert a dialog with confirm to redirect for that i use ShowDialog in the function it need a context of Widget so I used AlertDialog directly.
If i use ShowDialog in side the scaffold i didnt get the scanned data of Qr code. So what to do?
This is the code:
import 'package:appteq_solutions/dashboard.dart';
import 'package:flutter/material.dart';
import 'package:qr_code_scanner/qr_code_scanner.dart';
import 'package:url_launcher/url_launcher.dart';
class Scanner extends StatelessWidget {
Scanner({super.key});
final GlobalKey qrKey = GlobalKey(debugLabel: 'QR');
late QRViewController controller;
Future<Void> _onQRViewCreated(QRViewController controller) {
this.controller = controller;
controller.scannedDataStream.listen((scanData) async {
controller.pauseCamera();
print(scanData.code);
final uri = Uri.parse(scanData.code as String);
AlertDialog(
title: Text('Redirect To The Url'),
content: SingleChildScrollView(
child: ListView(),
),
actions: <Widget>[
ElevatedButton(
onPressed: () {},
child: Text('No'),
),
ElevatedButton(
child: const Text("Confirm"),
onPressed: () async {
if (await canLaunchUrl(uri)) {
await launchUrl(uri);
controller.resumeCamera();
}
},
),
]);
// }
});
return ;
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('QR Scanner'),
),
body: Stack(
children: [
Column(
children: <Widget>[
Expanded(
flex: 5,
child: Stack(
children: [
QRView(
key: qrKey,
onQRViewCreated: _onQRViewCreated,
),
Center(`your text`
child: Container(
width: 300,
height: 300,
decoration: BoxDecoration(
border: Border.all(
color: Colors.red,
width: 4,
),
borderRadius: BorderRadius.circular(12),
),
),
),
],
),
),
Expanded(
flex: 1,
child: GestureDetector(
onTap: () {
Navigator.of(context).pushReplacement(MaterialPageRoute(
builder: (BuildContext context) => Dashboard()));
},
child: Center(
child: Text(
' Press Here To Go DashBoard',
style:
TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
),
),
),
),
],
),
],
),
);
}
}
Help me use Alerdialog in function or to pass the data in dcaffold.
I'm using the sample below (taken from the CupertinoTabScaffold documentation page).
There is a "slide" transition when pushing a new route inside the tab, but when I click on a tabbar item, the content is brutally replaced. How can I have a transition when switching between tabs?
I would like implement something like that: https://github.com/Interactive-Studio/TransitionableTab
CupertinoTabScaffold(
tabBar: CupertinoTabBar(
items: [
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.home),
title: Text("Tab 0"),
),
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.news),
title: Text("Tab 1"),
),
],
),
tabBuilder: (BuildContext context, int index) {
return CupertinoTabView(
builder: (BuildContext context) {
return CupertinoPageScaffold(
navigationBar: CupertinoNavigationBar(
middle: Text('Page 1 of tab $index'),
),
child: Center(
child: CupertinoButton(
child: const Text('Next page'),
onPressed: () {
Navigator.of(context).push(
CupertinoPageRoute<void>(
builder: (BuildContext context) {
return CupertinoPageScaffold(
navigationBar: CupertinoNavigationBar(
middle: Text('Page 2 of tab $index'),
),
child: Center(
child: CupertinoButton(
child: const Text('Back'),
onPressed: () { Navigator.of(context).pop(); },
),
),
);
},
),
);
},
),
),
);
},
);
},
)
May be this package will be help you page_transition: ^2.0.5
https://pub.dev/packages/page_transition
Try this -
It has info on how to animate tabBarView but should be similar to CupertinoTabView
class MyApp2 extends StatefulWidget {
#override
_MyApp2State createState() => _MyApp2State();
}
class _MyApp2State extends State<MyApp2> with SingleTickerProviderStateMixin {
TabController _tabController;
#override
void initState() {
_tabController = TabController(length: 4, vsync: this);
super.initState();
}
_tabBarView() {
return AnimatedBuilder(
animation: _tabController.animation,
builder: (BuildContext context, snapshot) {
return Transform.rotate(
angle: _tabController.animation.value * pi,
child: [
Container(
color: Colors.blue,
),
Container(
color: Colors.orange,
),
Container(
color: Colors.lightGreen,
),
Container(
color: Colors.red,
),
][_tabController.animation.value.round()],
);
},
);
}
_bottomTabBar() {
return TabBar(
controller: _tabController,
labelColor: Colors.black,
tabs: [
Tab(
icon: new Icon(Icons.home),
),
Tab(
icon: new Icon(Icons.public),
),
Tab(
icon: new Icon(Icons.group),
),
Tab(
icon: new Icon(Icons.person),
)
],
);
}
#override
Widget build(BuildContext context) {
return DefaultTabController(
length: 4,
child: Scaffold(
appBar: AppBar(title: const Text('Bottom App Bar')),
body: _tabBarView(),
bottomNavigationBar: _bottomTabBar(),
),
);
}
}
The above code is taken from the following link-
Flutter - Change the animation of TabBarView
Created counter app with one floating action button.
If i want to add one more button for reset the counter, where can i add second floating action button at bottom bar?
Also i have to add any method in void section or is there any reset counter function available?
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Counter App',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Counter App'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Text('You have pressed the button $_counter times.'),
),
bottomNavigationBar: BottomAppBar(
child: Container(
height: 50.0,
),
),
floatingActionButton: FloatingActionButton(
onPressed: () => setState(() {
_counter++;
}),
tooltip: 'Increment Counter',
child: Icon(Icons.add),
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
);
}
}
floatingActionButton property on Scaffold widget do not need to take FloatingActionButton widget necessarily. It can also take Column or Row widgets.
Below, I'm sharing my Scaffold widget example with two floating action buttons on top of each other.
return Scaffold(
appBar: AppBar(
title: Text(""),
),
body: SingleChildScrollView(/*...*/),
floatingActionButton: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
FloatingActionButton(
child: Icon(
Icons.delete
),
onPressed: () {
//...
},
heroTag: null,
),
SizedBox(
height: 10,
),
FloatingActionButton(
child: Icon(
Icons.star
),
onPressed: () => _someFunc(),
heroTag: null,
)
]
)
);
You can use the flutter_speed_dial package: https://pub.dartlang.org/packages/flutter_speed_dial
On the link above have a example showing how to use it. You must use SpeedDial class and on children[] you can add some buttons with SpeedDialChild. The sample below shows 2 FABs.
Example using it:
Widget _getFAB() {
return SpeedDial(
animatedIcon: AnimatedIcons.menu_close,
animatedIconTheme: IconThemeData(size: 22),
backgroundColor: Color(0xFF801E48),
visible: true,
curve: Curves.bounceIn,
children: [
// FAB 1
SpeedDialChild(
child: Icon(Icons.assignment_turned_in),
backgroundColor: Color(0xFF801E48),
onTap: () { /* do anything */ },
label: 'Button 1',
labelStyle: TextStyle(
fontWeight: FontWeight.w500,
color: Colors.white,
fontSize: 16.0),
labelBackgroundColor: Color(0xFF801E48)),
// FAB 2
SpeedDialChild(
child: Icon(Icons.assignment_turned_in),
backgroundColor: Color(0xFF801E48),
onTap: () {
setState(() {
_counter = 0;
});
},
label: 'Button 2',
labelStyle: TextStyle(
fontWeight: FontWeight.w500,
color: Colors.white,
fontSize: 16.0),
labelBackgroundColor: Color(0xFF801E48))
],
);
}
Result:
According to medium post
You can use Column (for vertical alignment) or Row widget (for horizontal alignment) with 2 FAB as children and just set hero Tag null or assign diffent HeroTags.
You can make it by setup "heroTag: null" as below:
Stack(
children: <Widget>[
Align(
alignment: Alignment.bottomLeft,
child: FloatingActionButton(
heroTag: null,
...),
),
Align(
alignment: Alignment.bottomRight,
child: FloatingActionButton(
heroTag: null,
...),
),
],
)
Yes, It's worked..!
floatingActionButton: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
FloatingActionButton(
onPressed: () => {},
child: Icon(Icons.navigate_before_rounded),
heroTag: "fab1",
),
FloatingActionButton(
onPressed: () => {},
child: Icon(Icons.navigate_next_rounded),
heroTag: "fab2",
),
]
)
I fixed it with this, also to add space between the buttons you can add a width and the 'hero' tags are very important.
floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
floatingActionButton: Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
FloatingActionButton(
backgroundColor: Colors.green,
heroTag: "btn",
onPressed: () => _speak(textEditingController.text),
child: Icon(Icons.play_arrow),
),
SizedBox(
width: 40,
),
FloatingActionButton(
backgroundColor: Colors.red,
heroTag: "btn2",
onPressed: () => _stop(),
child: Icon(Icons.stop),
)
],
),
)
enter image description here
In Flutter Documentation, we can use at most one floating action button on a single screen. We can do it using RawMaterialButton() widget. This widget parent widget of the floating action button
It's something like that
class RoundIconButton extends StatelessWidget {
const RoundIconButton({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return RawMaterialButton(
constraints: BoxConstraints(minHeight: 40, minWidth: 40),
shape: CircleBorder(),
fillColor: Colors.white,
onPressed: () {},
child: Text("+"),
);
}
}
class Fab extends StatelessWidget {
const Fab({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Column(
children: [
RawMaterialButton(),
RawMaterialButton(),
],
);
}
}
I have a ListView in which I will dynamically add in some children of same type. Inside every children widget has a button. What I want to implement is, that, when user presses the button on a child widget, this child widget will be removed from the ListView. I can do this in C# using events, but I'm a total noob to Dart and Flutter.
Here is my ListView
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
appBar: AppBar(
title: Text('Edit Plan'),
backgroundColor: Colors.green,
actions: <Widget>[
Builder(
builder: (context) => IconButton(
icon: Icon(Icons.add),
onPressed: () {
setState(() {
txts.add('set');
});
},
),
)
],
),
backgroundColor: Colors.white,
body: ListView(
children: txts.map((string) =>
new ListViewItem()).toList(growable: false),
),
);
}
And here is my listViewItem:
class ListViewItem extends StatelessWidget {
final Workout workout;
ListViewItem({Key key, #required this.workout})
: assert(workout != null),
super(key: key);
#override
Widget build(BuildContext context) {
// TODO: implement build
final theme = Theme.of(context);
return Padding(
padding: EdgeInsets.all(12),
child: Card(
elevation: 12,
color: Colors.green,
child: Padding(
padding: EdgeInsets.only(top: 4, bottom: 4, left: 8, right: 8),
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
const ListTile(
leading: Icon(Icons.album),
title: Text(
'The Enchanted Nightingale',
style: TextStyle(color: Colors.white),
),
subtitle: Text(
'Music by Julie Gable. Lyrics by Sidney Stein.',
style: TextStyle(color: Colors.white),
),
),
TextFormField(
decoration: InputDecoration(
labelText: 'Name your workout',
labelStyle: TextStyle(color: Colors.white)),
),
ButtonTheme.bar(
// make buttons use the appropriate styles for cards
child: ButtonBar(
children: <Widget>[
FlatButton(
child: const Text(
'DELETE',
style: TextStyle(color: Colors.white),
),
onPressed: () {},
),
],
),
),
],
),
)),
);
}
}
I edited your code to use a ListView.builder, you need to remove the item at index from the List (txts) you are using, your code will be as follows:
List<String> txts = List();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Edit Plan'),
backgroundColor: Colors.green,
actions: <Widget>[
Builder(
builder: (context) =>
IconButton(
icon: Icon(Icons.add),
onPressed: () {
setState(() {
txts.add('set');
});
},
),
)
],
),
backgroundColor: Colors.white,
body: new ListView.builder(
itemCount: txts.length,
itemBuilder: (BuildContext context, int index) {
return ListViewItem(
workout: workout,
onDelete: (){
setState(() {
txts.removeAt(index);
});
},
);
},
),
);
}
in addition to that you need to add an ondelete callback in the ListViewItem, the code in the ListViewItem class will be as follows:
class ListViewItem extends StatelessWidget {
final Workout workout;
final VoidCallback onDelete;
ListViewItem({Key key, #required this.workout, this.onDelete})
: assert(workout != null),
super(key: key);
#override
Widget build(BuildContext context) {
final theme = Theme.of(context);
return Padding(
padding: EdgeInsets.all(12),
child: Card(
elevation: 12,
color: Colors.green,
child: Padding(
padding: EdgeInsets.only(top: 4, bottom: 4, left: 8, right: 8),
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
const ListTile(
leading: Icon(Icons.album),
title: Text(
'The Enchanted Nightingale',
style: TextStyle(color: Colors.white),
),
subtitle: Text(
'Music by Julie Gable. Lyrics by Sidney Stein.',
style: TextStyle(color: Colors.white),
),
),
TextFormField(
decoration: InputDecoration(
labelText: 'Name your workout',
labelStyle: TextStyle(color: Colors.white)),
),
ButtonTheme.bar(
// make buttons use the appropriate styles for cards
child: ButtonBar(
children: <Widget>[
FlatButton(
child: const Text(
'DELETE',
style: TextStyle(color: Colors.white),
),
onPressed: () =>onDelete(),
),
],
),
),
],
),
)),
);
}
}
I'm quite new with Flutter and I'm coming from using the Angular framework. Currently, I'm experimenting with flutter to make a desktop application using the following flutter embedding project: https://github.com/Drakirus/go-flutter-desktop-embedder.
I was wondering if someone could explain to me the best way to implement the following:
The black box represents the application as a whole.
The red box represents the custom menu.
The green box represents the content of the page.
How would I go about routing between "widgets" inside of the green area without changing the widget holding the application?
I'd love some direction please.
I am contributing Drakirus 's go-flutter plugin.
This projecd had moved to https://github.com/go-flutter-desktop
The question you ask can use package responsive_scaffold
https://pub.dev/packages/responsive_scaffold
or
you can reference this doc https://iirokrankka.com/2018/01/28/implementing-adaptive-master-detail-layouts/
Basically, there two are different layouts, see comments for detail
class _MasterDetailContainerState extends State<MasterDetailContainer> {
// Track the currently selected item here. Only used for
// tablet layouts.
Item _selectedItem;
Widget _buildMobileLayout() {
return ItemListing(
// Since we're on mobile, just push a new route for the
// item details.
itemSelectedCallback: (item) {
Navigator.push(...);
},
);
}
Widget _buildTabletLayout() {
// For tablets, return a layout that has item listing on the left
// and item details on the right.
return Row(
children: <Widget>[
Flexible(
flex: 1,
child: ItemListing(
// Instead of pushing a new route here, we update
// the currently selected item, which is a part of
// our state now.
itemSelectedCallback: (item) {
setState(() {
_selectedItem = item;
});
},
),
),
Flexible(
flex: 3,
child: ItemDetails(
// The item details just blindly accepts whichever
// item we throw in its way, just like before.
item: _selectedItem,
),
),
],
);
}
For package responsive_scaffold
on-line demo https://fluttercommunity.github.io/responsive_scaffold/#/
github https://github.com/fluttercommunity/responsive_scaffold/
more template code snippets for layout
https://github.com/fluttercommunity/responsive_scaffold/tree/dev
more pictures and demo can found here https://github.com/fluttercommunity/responsive_scaffold/tree/dev/lib/templates/3-column
code snippet 1
import 'package:flutter/material.dart';
import 'package:responsive_scaffold/responsive_scaffold.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
var _scaffoldKey = new GlobalKey<ScaffoldState>();
#override
Widget build(BuildContext context) {
return MaterialApp(
home: ResponsiveListScaffold.builder(
scaffoldKey: _scaffoldKey,
detailBuilder: (BuildContext context, int index, bool tablet) {
return DetailsScreen(
// appBar: AppBar(
// elevation: 0.0,
// title: Text("Details"),
// actions: [
// IconButton(
// icon: Icon(Icons.share),
// onPressed: () {},
// ),
// IconButton(
// icon: Icon(Icons.delete),
// onPressed: () {
// if (!tablet) Navigator.of(context).pop();
// },
// ),
// ],
// ),
body: Scaffold(
appBar: AppBar(
elevation: 0.0,
title: Text("Details"),
automaticallyImplyLeading: !tablet,
actions: [
IconButton(
icon: Icon(Icons.share),
onPressed: () {},
),
IconButton(
icon: Icon(Icons.delete),
onPressed: () {
if (!tablet) Navigator.of(context).pop();
},
),
],
),
bottomNavigationBar: BottomAppBar(
elevation: 0.0,
child: Container(
child: IconButton(
icon: Icon(Icons.share),
onPressed: () {},
),
),
),
body: Container(
child: Center(
child: Text("Item: $index"),
),
),
),
);
},
nullItems: Center(child: CircularProgressIndicator()),
emptyItems: Center(child: Text("No Items Found")),
slivers: <Widget>[
SliverAppBar(
title: Text("App Bar"),
),
],
itemCount: 100,
itemBuilder: (BuildContext context, int index) {
return ListTile(
leading: Text(index.toString()),
);
},
bottomNavigationBar: BottomAppBar(
elevation: 0.0,
child: Container(
child: IconButton(
icon: Icon(Icons.share),
onPressed: () {},
),
),
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: () {
_scaffoldKey.currentState.showSnackBar(SnackBar(
content: Text("Snackbar!"),
));
},
),
),
);
}
}
code snippet 2
import 'package:flutter/material.dart';
import 'package:responsive_scaffold/responsive_scaffold.dart';
class MultiColumnNavigationExample extends StatelessWidget {
#override
Widget build(BuildContext context) {
return ThreeColumnNavigation(
title: Text('Mailboxes'),
showDetailsArrows: true,
backgroundColor: Colors.grey[100],
bottomAppBar: BottomAppBar(
elevation: 1,
child: Row(
children: <Widget>[
IconButton(
icon: Icon(
Icons.filter_list,
color: Colors.transparent,
),
onPressed: () {},
),
],
),
),
sections: [
MainSection(
label: Text('All Inboxes'),
icon: Icon(Icons.mail),
itemCount: 100,
itemBuilder: (context, index, selected) {
return ListTile(
leading: CircleAvatar(
child: Text(index.toString()),
),
selected: selected,
title: Text('Primary Information'),
subtitle: Text('Here are some details about the item'),
);
},
bottomAppBar: BottomAppBar(
elevation: 1,
child: Row(
children: <Widget>[
IconButton(
icon: Icon(Icons.filter_list),
onPressed: () {},
),
],
),
),
getDetails: (context, index) {
return DetailsWidget(
title: Text('Details'),
child: Center(
child: Text(
index.toString(),
),
),
);
},
),
MainSection(
label: Text('Sent Mail'),
icon: Icon(Icons.send),
itemCount: 100,
itemBuilder: (context, index, selected) {
return ListTile(
leading: CircleAvatar(
child: Text(index.toString()),
),
selected: selected,
title: Text('Secondary Information'),
subtitle: Text('Here are some details about the item'),
);
},
getDetails: (context, index) {
return DetailsWidget(
title: Text('Details'),
actions: [
IconButton(
icon: Icon(Icons.share),
onPressed: () {},
),
],
child: Center(
child: Text(
index.toString(),
),
),
);
},
),
],
);
}
}
I'm a noob so please take anything I say with a grain of salt.
I know 2 ways to navigate through widgets and you can find them both here
https://flutter.io/docs/development/ui/navigation
I believe the main difference I can perceive is if you want to
send data to the new 'route' or not (the named route way cannot, at least that I'm aware of);
said so you can keep your main 'screen' and change the red and green widget
using the state of the widget where they are contained
example
class BlackWidget extends StatefulWidget
bla bla bla => BlackWidgetState();
class BlackWidget extend State<BlackWidget>
Widget tallWidget = GreenWidget();
Widget bigWidget = RedWidget();
return
container, column.. etc
Row(
children:[tallWidget,bigWidget
])
button onTap => tallWidget = YellowWidget();
}
GreenWidget... bla bla bla...
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => RedWidget()),
);
}
sorry for the 'bla bla', the part you need is at the bottom,
just added the 'yellow' widget to underline that you can
actually swap the 'green widget' with anything you want