I am working on a social media app which contains a home screen with bottom navbar and 5 pages . Although i am able to change the bool value to show or hide navbar under provider but the changes are not reflecting in widget .
main.dart -
MultiProvider(
providers: [
ChangeNotifierProvider(create: (context) =>
ScrollProvider(),
),
],
child : MyApp()
My provider class -
class ScrollProvider with ChangeNotifier{
bool isVisible = true;
void show() {
isVisible = true;
print("in Provider $isVisible");
notifyListeners();
}
void hide() {
isVisible = false;
print("in Provider $isVisible");
notifyListeners();
}
}
Page which has the value scrollcontroller
ScrollController _scrollController =
ScrollController();
_scrollController.addListener(() {
final direction =
_scrollController.position.userScrollDirection;
if (direction == ScrollDirection.forward) {
ScrollProvider().show();
}
if (direction == ScrollDirection.reverse) {
ScrollProvider().hide();
}
});
And my homescreen which which has body and navbar contains this code
‘’’
bottomNavigationBar: Consumer<BottomBarVisibilityProvider>(
builder: (context, bottomBarVisibilityProvider, child) =>
AnimatedContainer(
duration: const Duration(milliseconds: 200),
child: bottomBarVisibilityProvider.isVisible
? Wrap(
children: const [BottomBar()],
)
: Wrap(),
),
),
I have initialised the provider inside main.dart
Can someone tell me why its not working .. and what should i do
here is the full code of homepage
class _HomeState extends State<Home> {
List<Widget> _pages ;
@override
void initState() {
super.initState();
_pages = [
MemeTabView(scrollController: scrollToHide),
TempTab(),
null,
NotificationScreen(),
ProfileScreen(uid: FirebaseAuth.instance.currentUser.uid,showAppBar: false),
];
}
@override
Widget build(BuildContext context) {
if (widget.selectedIndex == null) {
widget.selectedIndex = 0;
}
return
Scaffold(
appBar: AppBar(
title: brandName(),
),
extendBody: true,
bottomNavigationBar:
Consumer<ScrollProvider>(
builder: (_,scrollProvider,__){
return Container(
child: scrollProvider.isVisible == true
?
bottomNav()
: Container(),
);
},
),
drawer: MyDrawer(),
body:PageView(
controller: _pageController,
physics: NeverScrollableScrollPhysics(),
children: _pages,
),
);
}
CodePudding user response:
You need to read provider like
context.read<BottomBarVisibilityProvider>();
void main() {
runApp(
/// Providers are above [MyApp] instead of inside it, so that tests
/// can use [MyApp] while mocking the providers
MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) => BottomBarVisibilityProvider()),
],
child: const MyApp(),
),
);
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.\
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.red,
),
home: const SCCR(),
);
}
}
class SCCR extends StatefulWidget {
const SCCR({Key? key}) : super(key: key);
@override
State<SCCR> createState() => _SCCRState();
}
class _SCCRState extends State<SCCR> {
//just for test purpose
late final bottomBarVisibilityProvider =
context.read<BottomBarVisibilityProvider>();
late final ScrollController scrollController = ScrollController()
..addListener(() {
final direction = scrollController.position.userScrollDirection;
if (direction == ScrollDirection.forward) {
if (!bottomBarVisibilityProvider.isVisible) {
bottomBarVisibilityProvider.show();
}
} else if (direction == ScrollDirection.reverse) {
if (bottomBarVisibilityProvider.isVisible) {
bottomBarVisibilityProvider.hide();
}
}
});
@override
Widget build(BuildContext context) {
return Scaffold(
body: SingleChildScrollView(
controller: scrollController,
child: Container(
height: 3333,
),
),
bottomNavigationBar: Consumer<BottomBarVisibilityProvider>(
builder: (context, bottomBarVisibilityProvider, child) =>
AnimatedContainer(
duration: const Duration(milliseconds: 200),
child: bottomBarVisibilityProvider.isVisible
? Wrap(
children: [
Container(
height: 100,
color: Colors.red,
width: 100,
)
],
)
: null,
),
),
);
}
}
I will suggest to follow documentation
CodePudding user response:
This is how I use my providers:
I have 3 different providers here, MyThemeClass
, NewMsgListener
and FirebaseProvider
. All of them extend ChangeNotifierProvider
. And this is my main:
import 'package:my_app/my_firebase.dart';
import 'package:my_app/global.dart';
import 'package:provider/provider.dart';
import 'package:navigation_history_observer/navigation_history_observer.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:my_app/firebase_options.dart';
import 'package:my_app/screens/welcome_screen.dart';
import 'package:my_app/new_msg_listener.dart';
import 'package:my_app/provider_updates.dart';
import 'package:my_app/theme.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
MyFirebase.myFutureFirebaseApp =
Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
final NewMsgListener newMsgListener = NewMsgListener();
final MyThemeClass myThemeClass = MyThemeClass();
await myThemeClass.getMyTheme();
print('getMyTheme() is ready');
await MyFirebase.myFutureFirebaseApp;
runApp(MyApp(myThemeClass, newMsgListener));
}
class MyApp extends StatelessWidget {
const MyApp(this.myThemeClass, this.newMsgListener, {Key? key})
: super(key: key);
final MyThemeClass myThemeClass;
final NewMsgListener newMsgListener;
@override
Widget build(BuildContext context) {
print('Building $runtimeType');
FirebaseProvider firebaseProvider = FirebaseProvider();
firebaseProvider.initialize(GlobalVariable.navState);
return MultiProvider(
providers: [
ChangeNotifierProvider<FirebaseProvider>(
create: (context) => firebaseProvider),
ChangeNotifierProvider(create: (context) => myThemeClass),
ChangeNotifierProvider(create: (context) => newMsgListener),
],
builder: (context, child) {
return MaterialApp(
theme: Provider.of<MyThemeClass>(context).currentTheme,
home: WelcomeScreen(myThemeClass),
debugShowCheckedModeBanner: false,
navigatorObservers: [NavigationHistoryObserver()],
navigatorKey: GlobalVariable.navState,
);
});
}
}
Not that it's important, but my my_firebase.dart
file looks like this (just so you don't need to wonder!):
import 'package:firebase_core/firebase_core.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart' as auth;
import 'package:my_app/firebase_labels.dart';
class MyFirebase {
static Future<FirebaseApp>? myFutureFirebaseApp; //Initialized from main()
static FirebaseFirestore storeObject = FirebaseFirestore.instance;
static auth.FirebaseAuth authObject = auth.FirebaseAuth.instance;
}
Does that provider management work for you?