Switch screen in flutter without context in flutter - flutter

I have this dart file(app_bar.dart) and am storing Appbars inside it and i have logged_home.dart file where am calling the app_bar.dart from. Now i want to be able to navigate to a new screen when i click next screen it sends me to PostData() while in app_bar.dart.
app_bar.dart:
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:kopala_dictionary/screens/authenticate/login.dart';
import 'package:kopala_dictionary/screens/author/post_data.dart';
import 'package:kopala_dictionary/screens/home/unlogged_home.dart';
//for logged in user
final loggedBar = AppBar(
title: Text('Kopalaz Dictionary'),
backgroundColor: Colors.green,
elevation: 0.0,
actions: <Widget>[
FlatButton.icon(
color: Colors.white,
onPressed: () {
Navigator.push(
context, MaterialPageRoute(builder: (context) => PostData()));
},
icon: Icon(Icons.add),
label: Text(
'Post',
style: TextStyle(color: Colors.white),
)),
],
);
//For unlogged users
final unloggedBar = AppBar(
title: Text('Kopalaz Dictionary'),
backgroundColor: Colors.green,
elevation: 0.0,
);
logged_home.dart:
import 'package:flutter/material.dart';
import 'package:kopala_dictionary/screens/wrapper.dart';
import 'package:kopala_dictionary/services/auth.dart';
import 'package:kopala_dictionary/shared/app_bar.dart';
class LoggedInUserHome extends StatelessWidget {
final AuthService _auth = AuthService();
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.green[10],
appBar: loggedBar,
drawer: Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: <Widget>[
DrawerHeader(
child: Text(
'Kopalationary Menu',
style: TextStyle(color: Colors.white),
),
decoration: BoxDecoration(
color: Colors.green,
),
),
ListTile(
title: Text('Home'),
onTap: () {
Navigator.push(context,
MaterialPageRoute(builder: (context) => Wrapper()));
},
),
ListTile(
title: Text(
'My profile',
),
onTap: () {},
),
ListTile(
title: Text('Logout'),
onTap: () async {
dynamic result = await _auth.logoutUser();
},
),
ListTile(
title: Text(
'About',
),
onTap: () {},
),
],
),
),
body: Center(
child: Text('Development in progress!'),
),
);
}
}

do not forget that in Flutter everything is a widget !
So my advice would be to create functions which returns a widget:
import 'package:flutter/material.dart';
//for logged in user
AppBar loggedBar(BuildContext context) {
return AppBar(
title: Text('Kopalaz Dictionary'),
backgroundColor: Colors.green,
elevation: 0.0,
actions: <Widget>[
FlatButton.icon(
color: Colors.white,
onPressed: () {
Navigator.push(context, MaterialPageRoute(builder: (context) => PostData()));
},
icon: Icon(Icons.add),
label: Text(
'Post',
style: TextStyle(color: Colors.white),
)),
],
);
}
//For unlogged users
AppBar unloggedBar(BuildContext context) {
return AppBar(
title: Text('Kopalaz Dictionary'),
backgroundColor: Colors.green,
elevation: 0.0,
);
}
Do keep in mind that flutter does a lot in the background and it is therefore better practice not to store widget in global variable. If you need to access those widgets from different part of your app you should look into Inherited Widget or other form of state management (see list here).

see below link:
Navigate without context in Flutter with a Navigation Service
https://medium.com/flutter-community/navigate-without-context-in-flutter-with-a-navigation-service-e6d76e880c1c
also, you can use GetX library

Related

flutter:: I have a question about how to use the app top bar

This time I'm making an app top bar in flutter. I wrote code like this.
import 'package:flutter/material.dart';
class VideoAppBar extends StatelessWidget{
const VideoAppBar({Key? key}) : super(key: key);
#override
Widget build(BuildContext context){
return SafeArea(
child: Scaffold(
body: WillPopScope( // <- wraps only the Scaffold body.
child: Center(
),
onWillPop: () {
return Future(() => false);
},
),
appBar: AppBar(
backgroundColor: Colors.white,
title: Text('Very verse',
style: TextStyle(
color: Colors.black,
fontSize: 20,
),),
centerTitle: true,
leading: IconButton(
onPressed: () {
Navigator.pop(context);
},
color: Colors.black,
iconSize: 25,
icon: Icon(Icons.arrow_back),
),
actions: <Widget>[
IconButton(
icon: Icon(Icons.bookmark_outline),
iconSize: 25,
color: Colors.black,
onPressed: () {
print('GD');
}
),
],
),
),
);
}
}
I'd like to put this code simply as a function on several other pages.
AppBar(title:VideoAppBar);
I figured it could be done like this.
But it doesn't go back.
How should I write the code?
Try below Code hope its helpful to you
Create your regular class or your Widget like below:
import 'package:flutter/material.dart';
void main() {
runApp(
MyApp(),
);
}
class MyApp extends StatelessWidget {
bool shouldPop = true;
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: WillPopScope(
onWillPop: () async {
return shouldPop;
},
child: Scaffold(
appBar: appBar(context),
body: Center(
child: Text('Test'),
),
),
),
);
}
}
Create another dart file like appBar.dart and declare your Appbar Widget in dart file. call your widget any file on your need
appBar(BuildContext context) {
return AppBar(
backgroundColor: Colors.white,
title: Text(
'Very verse',
style: TextStyle(
color: Colors.black,
fontSize: 20,
),
),
centerTitle: true,
leading: IconButton(
onPressed: () {
Navigator.pop(context);
},
color: Colors.black,
iconSize: 25,
icon: Icon(Icons.arrow_back),
),
actions: <Widget>[
IconButton(
icon: Icon(Icons.bookmark_outline),
iconSize: 25,
color: Colors.black,
onPressed: () {
print('GD');
}),
],
);
}
For WillPopScope class
For Scaffold class
For AppBar
Your result screen ->

Change Drawer Icon of Drawer Widget being returned from an external Class

I'm trying to change the icon and color of my drawer widget in Dart. I've found ways of doing it but none that apply to my scenario. My custom drawer widget is being returned from another class and so I can't change the leading icon in the home class where the app bar is or it will replace my current drawer. I won't show all the code because I don't believe it would be necessary. Any help would be appreciated.
My Current drawer and method of calling it:
Drawer class:
import 'package:flutter/material.dart';
import 'package:new_app/Users.dart';
import '../main.dart';
class MainDrawer extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Drawer(
child: Column(
children: <Widget>[
Container(
width: double.infinity,
padding: EdgeInsets.all(20),
color: Theme.of(context).primaryColor,
child: Center(
child: Column(
children: [
Container(
Menu Class/ home page:
import 'screens/drawer_main.dart';
class Home extends StatefulWidget {
#override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
#override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () {
return new Future(() => false);
},
child: Scaffold(
backgroundColor: Colors.blueGrey[900],
appBar: AppBar(
//backgroundColor: Colors.blueGrey[900],
backgroundColor: Colors.transparent,
automaticallyImplyLeading: true,
title: Text(
"Home Page",
style: TextStyle(color: Colors.white),
),
actions: <Widget>[
//Profile Pic
IconButton(
icon: Icon(Icons.circle, color: Colors.white),
tooltip: 'Comment Icon',
onPressed: () {},
),
MainPopUp(), //IconButton
],
//IconButton
brightness: Brightness.dark,
),
//Current Method of Calling the Drawer:
drawer: MainDrawer(),
body: Center(
Add the leading property in the App Bar and then call the Drawer Widget Programmatically.
Scaffold(
backgroundColor: Colors.blueGrey[900],
appBar: AppBar(
//backgroundColor: Colors.blueGrey[900],
leading: Builder(
builder: (context) => IconButton(
icon: Icon(Icons.menu_rounded),
onPressed: () => Scaffold.of(context).openDrawer(),
),
),
backgroundColor: Colors.transparent,
automaticallyImplyLeading: true,
title: Text(
"Home Page",
style: TextStyle(color: Colors.white),
),
actions: <Widget>[
//Profile Pic
IconButton(
icon: Icon(Icons.circle, color: Colors.white),
tooltip: 'Comment Icon',
onPressed: () {},
),
MainPopUp(), //IconButton
],
//IconButton
brightness: Brightness.dark,
),
//Current Method of Calling the Drawer:
drawer: MainDrawer(),
Add a leading inside AppBar() and open drawer programatically.
AppBar(
leading: InkWell(
child: Icon(
//your preferred icon
Icons.camera
),
onTap: () {
Scaffold.of(context).openDrawer();
},
),
)

Flutter - How can I reuse some code at multiple places

Hi I have a app where I will be making a book and this book will be with images,
I am trying to reuse code meaning how to add code within a method and than have that method at different areas but only change the image in each method .. .to make the code more reusable??? the code will stay the same but the image in each code block will change... i dont want to copy and paste the code again and again.
import 'dart:ui';
import 'package:adobe_xd/adobe_xd.dart';
import 'dart:io';
import 'package:Quran_highlighter/main.dart';
import 'package:flutter/rendering.dart';
import 'package:system_shortcuts/system_shortcuts.dart';
import 'package:Quran_highlighter/Widgets/NavDrawer.dart';
import 'package:flutter/material.dart';
import 'package:zoom_widget/zoom_widget.dart';
import 'package:flutter/gestures.dart';
import 'package:Quran_highlighter/Widgets/size_config.dart';
import 'package:flutter_slidable/flutter_slidable.dart';
class Aliflaammeem extends StatefulWidget {
#override
_AliflaammeemState createState() => _AliflaammeemState();
}
class _AliflaammeemState extends State<Aliflaammeem> {
#override
Widget build(BuildContext context) {
var screenSizes = MediaQuery.of(context).size;
return Scaffold(
appBar: new AppBar(title: new Text("1 Alif-laam-meem آلم, Pg2")),
// return DefaultTextStyle(
// style: Theme.of(context).textTheme.bodyText2,
body: LayoutBuilder(builder:
(BuildContext context, BoxConstraints viewportConstraints) {
return SingleChildScrollView(
child: Stack(children: <Widget>[
new Slidable(
delegate: new SlidableDrawerDelegate(),
actionExtentRatio: 0.10,
// body: Center,
child: SafeArea(
top: true,
bottom: true,
right: true,
left: true,
child: new Container(
**child: new Image.asset(
"test/assets/Para 1 - Alif-laam-meem no color/quranpg2.png",**
fit: BoxFit.cover,
),
),
),
actions: <Widget>[
new IconSlideAction(
caption: 'English',
// color: Colors.lightBlue,
color: Colors.blueGrey,
icon: Icons.language,
foregroundColor: Colors.lightBlue,
// color: Colors.black,
// ),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Changepg2topg3()),
);
}),
new IconSlideAction(
caption: 'Forward',
// color: Colors.greenAccent,
// color: Colors.black87,
icon: Icons.arrow_back_ios,
foregroundColor: Colors.greenAccent,
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Changepg2topg3()),
);
}),
// ),
],
secondaryActions: <Widget>[
new IconSlideAction(
caption: 'Back',
// color: Colors.red[200],
icon: Icons.arrow_forward_ios,
foregroundColor: Colors.red[200],
// color: Colors.black87,
// onTap: () => _showSnackBar('More'),
),
new IconSlideAction(
caption: 'Arabic',
// color: Colors.yellow[800],
icon: Icons.brightness_4,
foregroundColor: Colors.yellow[800],
color: Colors.blueGrey,
// onTap: () =>
),
],
),
]));
}));
}
}
//I WANT THE TOP CODE TO BE THE GLOBAL CODE WHICH WILL REUSED AGAIN AND
AGAIN IN THE SAME CLASS - AND IF I CHANGE SOMETHING UP THERE, I WANT IT TO AUTOMATICALLY CHANGE THROUGHOUT ALL THE PAGES
AND BELOW WE HAVE THE SAME CODE WHICH I COPIED AND PASTED - AND JUST CHANGED THE IMAGE AND APPBAR TITLE.... I NEED TO SEE HOW I CAN ACHIEVE THIS WITHOUT COPY AND PASTING....
class Changepg2topg3 extends StatelessWidget {
#override
Widget build(BuildContext context) {
var screenSizes = MediaQuery.of(context).size;
return Scaffold(
appBar: new AppBar(title: new Text("1 Alif-laam-meem آلم, Pg3")),
// return DefaultTextStyle(
// style: Theme.of(context).textTheme.bodyText2,
body: LayoutBuilder(builder:
(BuildContext context, BoxConstraints viewportConstraints) {
return SingleChildScrollView(
child: Stack(children: <Widget>[
new Slidable(
delegate: new SlidableDrawerDelegate(),
actionExtentRatio: 0.10,
// body: Center,
child: SafeArea(
top: true,
bottom: true,
right: true,
left: true,
child: new Container(
// padding: EdgeInsets.zero,
**child: new Image.asset(
`"test/assets/Para 1 - Alif-laam-meem no color/quranpg3.png",*`*
// fit: BoxFit.fitidth,
fit: BoxFit.cover,
),
),
),
actions: <Widget>[
new IconSlideAction(
caption: 'English',
color: Colors.lightBlue,
icon: Icons.language,
// onTap: () =>
),
new IconSlideAction(
caption: 'Forward',
color: Colors.greenAccent,
icon: Icons.arrow_back_ios,
// onTap: () => _showSnackBar('Share'),
),
],
secondaryActions: <Widget>[
new IconSlideAction(
caption: 'Back',
color: Colors.red[200],
icon: Icons.arrow_forward_ios,
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Aliflaammeem()),
);
}),
// ),
new IconSlideAction(
caption: 'Arabic',
color: Colors.yellow[800],
icon: Icons.brightness_4,
// onTap: () =>
),
],
),
]));
// );
}));
}
}
// }
1.Make a class returning a list
2.Make a New Widget function and pass-in the list to this function

Add 2 appbars in flutter

I want my app to have 2 appBars but i don't know how i can add the second one , The first one have this code :
appBar:
AppBar(
title: Text('Tariffo',
style: TextStyle(
color: Colors.white,
fontFamily: 'SignPainter',
fontSize: 45)),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(
bottom: Radius.circular(30),
),
),
actions: <Widget>[
Padding(
padding: EdgeInsets.only(right: 10),
),
IconButton(
icon: Icon(Icons.center_focus_weak),
onPressed: () async {
String scaning = await BarcodeScanner.scan();
setState(() {
qrResult = scaning;
});
},
),
IconButton(
icon: Icon(
Icons.perm_identity,
color: Colors.white,
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => UserPage()),
);
}),
And the second one have this code:
appBar: AppBar(title: const Text('Bottom App Bar')),
floatingActionButtonLocation:
FloatingActionButtonLocation.centerDocked,
floatingActionButton: FloatingActionButton(
child: const Icon(Icons.add), onPressed: () {},),
bottomNavigationBar: BottomAppBar(
shape: CircularNotchedRectangle(),
notchMargin: 4.0,
child: new Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
IconButton(icon: Icon(Icons.menu), onPressed: () {},),
IconButton(icon: Icon(Icons.search), onPressed: () {},),
],
),
),
);
}
So how can i add the second one to not get an error? Beacuse i tried to erase the first part with appbar: Appbar and i get a lot o errors
Edit:
As Derek pointed out you should not place two Scaffolds in your App.
A different solution could be to place the first AppBar as usual in the appBar property of your Scaffold and the second as a first children in a Column.
This would look like:
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
backgroundColor: Colors.blue,
title: Text("First appbar"),
),
body: Column(
children: [
AppBar(
backgroundColor: Colors.red,
title: Text("Second appbar"),
),
HomePage()
],
),
),
);
}
}
class HomePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Container(
color: Colors.yellow,
child: Text("Content"),
);
}
}
---------------------------
Old Answer:
Actually this is really simple.
You create your Scaffold in which you put the first AppBar as usual.
As the body of this Scaffold you put a second Scaffold in which you place your second AppBar.
The result would look like:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
backgroundColor: Colors.blue,
title: Text("First appbar"),
),
body: Scaffold(
appBar: AppBar(
backgroundColor: Colors.red,
title: Text("Second appbar"),
),
),
),
);
}
}

why flutter BottomNavigationBar changes the icon but does not change the page?

Im new to coding and flutter and I have been trying to make my bottomNavigationBar change pages from home page to chatroom but what ever I try is not working , I watched many videos but their bottomNavigationBar is inside their body and when I apply what they are doing I get the red line under my padding right after body and return Scaffold( right under this parenthesis before my appBar: image link is at the end of the code
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter_rating_bar/flutter_rating_bar.dart';
import 'package:trading/core/const.dart';
import 'package:trading/models/apartment_model.dart';
import 'package:trading/pages/chat.dart';
import 'package:trading/pages/detail_page.dart';
class Homepage extends StatefulWidget {
#override
_HomepageState createState() => _HomepageState();
}
class _HomepageState extends State<Homepage> {
var data = ApartmentModel.list;
int _selectedIndex = 0;
List<Widget> `enter code here`pages=[
Homepage(),
Chatroom(),
];
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.transparent,
elevation: 0,
title: Text(
"find your product",
style: TextStyle(color: Colors.black87, fontWeight: FontWeight.bold),
),
actions: <Widget>[
IconButton(
icon: Icon(
Icons.search,
color: Colors.black38,
),
onPressed: () {}),
IconButton(
icon: Icon(
Icons.filter_list,
color: Colors.black38,
),
onPressed: () {}),
],
),
bottomNavigationBar:
BottomNavigationBar(
showSelectedLabels: false,
showUnselectedLabels: false,
type: BottomNavigationBarType.fixed,
selectedItemColor: AppColors.stylecolor,
unselectedItemColor: Colors.black38,
currentIndex: _selectedIndex,
items: [
BottomNavigationBarItem(
icon: Icon(Icons.home), title: Text("datsa")),
BottomNavigationBarItem(
icon: Icon(Icons.chat), title: Text("data"),),
BottomNavigationBarItem(
icon: Icon(Icons.person), title: Text("data")),
],
),
body:
pages.elementAt(_selectedIndex),
Padding(
padding: EdgeInsets.all(16.0),
child:
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
"65 result in your area",
style: TextStyle(color: Colors.black38),
),
Expanded(
child: ListView.builder(
physics: BouncingScrollPhysics(),
itemCount: data.length,
itemBuilder: (context, index) {
return GestureDetector(
onTap: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (_) => DetailPage(
data[index]
),
),
);
},
child: _buildItem(context, index));
},
),
),
// Container( child: _builBottomNavigationBar),
],
),
),
);
}
here is a pic of the red line that I was saying
body can take one widget not more, you assign pages and padding if you want both you must use a column
You have to make a List of Widgets containing your pages, and in the body you populate the Widget according to the Selected Index.
Example:
List<Widget> pages=[
Dashboard(),
Profile(),
Settings(),
];
then show the page in the body as:
body:
pages.elementAt(_selectedIndex),