How to not rebuild the screen from start in the bottom navigation bar and saving the last state of it and if the state of the screen is changed like the driver app has 4 screens and I want the screen of home that contains button Offline Now or Online Now not change the state if I move to another screen, I used a Tabviewbar
What is the solution?
Main Screen class
import 'package:drivers_app/tabsPages/earnings_tab_screen.dart';
import 'package:drivers_app/tabsPages/home_tab_screen.dart';
import 'package:drivers_app/tabsPages/profile_tab_screen.dart';
import 'package:drivers_app/tabsPages/zones_tab_page.dart';
import 'package:flutter/material.dart';
class MainScreen extends StatefulWidget
{
static const String mainScreenId = "mainScreenId";
@override
_MainScreenState createState() => _MainScreenState();
}
class _MainScreenState extends State<MainScreen> with SingleTickerProviderStateMixin
{
TabController? tabController;
int selectedIndex = 0;
void onItemClicked(int index)
{
setState(()
{
selectedIndex = index;
tabController!.index = selectedIndex;
});
}
@override
void initState() {
// TODO: implement initState
super.initState();
tabController = TabController(length: 4, vsync: this);
}
@override
void dispose() {
// TODO: implement dispose
super.dispose();
tabController!.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold
(
body: TabBarView(
physics: NeverScrollableScrollPhysics(),
controller: tabController,
children:
[
HomeScreen(),
EarningsScreen(),
ZonesScreen(),
ProfileScreen(),
],
//index: selectedIndex,
),
bottomNavigationBar: BottomNavigationBar(
items:
[
BottomNavigationBarItem(
icon: Icon(
Icons.home,
),
label: 'Home',
),
BottomNavigationBarItem(
icon: Icon(
Icons.credit_card,
),
label: 'Earnings',
),
BottomNavigationBarItem(
icon: Icon(
Icons.settings_input_antenna_rounded,
),
label: 'Zones',
),
BottomNavigationBarItem(
icon: Icon(
Icons.person,
),
label: 'Account',
),
],
unselectedItemColor: Colors.black54,
selectedItemColor: Colors.blue,
type: BottomNavigationBarType.fixed,
selectedLabelStyle: TextStyle(
fontSize: 12.0
),
showUnselectedLabels: true,
currentIndex: selectedIndex,
onTap: onItemClicked,
),
);
}
}
Home Screen Class
import 'package:drivers_app/shared/components/components.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_database/firebase_database.dart';
import 'package:flutter/material.dart';
import 'package:flutter_geofire/flutter_geofire.dart';
import 'package:geolocator/geolocator.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
class HomeScreen extends StatefulWidget
{
static final CameraPosition _kGooglePlex = CameraPosition(
target: LatLng(37.42796133580664, -122.085749655962),
zoom: 15,
);
@override
State<HomeScreen> createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
Completer<GoogleMapController> _controllerGoogleMap = Completer();
GoogleMapController? newcontrollerGoogleMap;
var geoLocator = Geolocator();
String driverStatusText = 'Offline Now - Go Online ';
Color driverStatusColor = Colors.black;
bool isDriverAvailable = false;
@override
void initState()
{
super.initState();
getCurrentDriverInfo();
}
void locatePosition() async
{
Position position = await Geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.high);
currentPosition = position;
LatLng latLatPosition = LatLng(position.latitude, position.longitude);
CameraPosition cameraPosition = CameraPosition(target: latLatPosition, zoom: 14);
newcontrollerGoogleMap!.animateCamera(CameraUpdate.newCameraPosition(cameraPosition));
String Address = await AssistantMethods.searchCoordinateAddress(position, context);
print("This is your Address :: " + Address);
}
void getCurrentDriverInfo() async
{
currentfirebaseUser = await FirebaseAuth.instance.currentUser;
driversRef.child(currentfirebaseUser!.uid).once().then((DataSnapshot dataSnapshot)
{
if(dataSnapshot.value != null)
{
driversInformation = Drivers.fromSnapshot(dataSnapshot);
}
});
PushNotificationService pushNotificationService = PushNotificationService();
pushNotificationService.initialize(context);
pushNotificationService.getToken().toString();
AssistantMethods.retrieveHistoryInfo(context);
}
@override
Widget build(BuildContext context)
{
return Stack(
children:
[
GoogleMap(
mapType: MapType.normal,
myLocationButtonEnabled: true,
initialCameraPosition: HomeScreen._kGooglePlex,
myLocationEnabled: true,
onMapCreated: (GoogleMapController controller) {
_controllerGoogleMap.complete(controller);
newcontrollerGoogleMap = controller;
_determinePosition();
},
),
//online offline driver container
Container(
height: 140.0,
width: double.infinity,
color: Colors.black54,
),
Positioned(
top: 60.0,
left: 0.0,
right: 0.0,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children:
[
Padding(padding: EdgeInsets.symmetric(
horizontal: 16.0,
),
child: MaterialButton(
onPressed: ()
{
if(isDriverAvailable != true)
{
makeDriverOnlineNow();
getLocationLiveUpdates();
setState(()
{
driverStatusColor = Colors.green;
driverStatusText = 'Online Now ';
isDriverAvailable = true;
});
displayToast('you are Online Now', context);
}
else
{
displayToast('you are Offline Now', context);
setState(()
{
driverStatusColor = Colors.black;
driverStatusText = 'Offline Now - Go Online ';
isDriverAvailable = false;
});
makeDriverOfflineNow();
Appclosed();
}
},
color: driverStatusColor,
child: Padding(
padding: EdgeInsets.all(17.0,),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
driverStatusText,
style: TextStyle(
fontSize: 20.0,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
Icon(
Icons.phone_android,
color: Colors.white,
size: 26.0,
),
],
),
),
),
),
],
),
),
],
);
}
Main class
import 'package:drivers_app/config_maps.dart';
import 'package:drivers_app/modules/car_info_screen.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_database/firebase_database.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';
import 'package:drivers_app/Data_Handler/app_Data.dart';
import 'package:drivers_app/modules/login_screen.dart';
import 'package:drivers_app/modules/main_screen.dart';
import 'package:provider/provider.dart';
import 'package:drivers_app/modules/register_screen.dart';
//Receive message when app is in background solution for on message
Future<void> backgroundHandler(RemoteMessage message) async
{
print(message.data.toString());
print(message.notification!.title);
}
void main() async{
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
FirebaseMessaging.onBackgroundMessage(backgroundHandler);
currentfirebaseUser = FirebaseAuth.instance.currentUser;
runApp(MyApp());
}
DatabaseReference adminRef = FirebaseDatabase.instance.reference().child("admin");
DatabaseReference driversRef = FirebaseDatabase.instance.reference().child("drivers");
DatabaseReference newRequestRef = FirebaseDatabase.instance.reference().child("Ride Request");
DatabaseReference rideRequestRef = FirebaseDatabase.instance.reference().child("drivers").child(currentfirebaseUser!.uid).child("newRide");
DatabaseReference availableDriverRef = FirebaseDatabase.instance.reference().child("availableDrivers");
DatabaseReference availableDriverRef2 = FirebaseDatabase.instance.reference().child("availableDrivers2").child(currentfirebaseUser!.uid);
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
create:(context) => AppData(),
child: MaterialApp(
title: 'Driver App',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
initialRoute: FirebaseAuth.instance.currentUser == null ? LoginScreen.loginScreenId : MainScreen.mainScreenId,
routes:{
RegisterScreen.registerScreenId: (context)=> RegisterScreen(),
LoginScreen.loginScreenId: (context)=> LoginScreen(),
MainScreen.mainScreenId: (context)=> MainScreen(),
CarInfoScreen.carinfoScreen: (context)=> CarInfoScreen(),
},
),
);
}
}
2
Answers
You can use a
PageView
andAutomaticKeepAliveClientMixin
on each page/portion (item in thePageView
) and setwantToKeepAlive
to true.For example:
If we have 2 portions,
HomePortion
andSettingsPortion
like so:We can then use them in the
Page
like so:in your code