video playing in background flutter - flutter

im working through a scrollable page view somewhat like tic tok and each time i leave the screen the video continuously play in the background, which i dont want, cuz this code ids from a youtube tutorial i dont know how to work around the problem, so please help me check problem for a viable solution
import 'package:app/packageManager/package.dart';
import 'dart:io';
class Reels extends StatefulWidget {
const Reels({Key? key}) : super(key: key);
#override
State<Reels> createState() => _ReelsState();
}
vidPicker(ImageSource src, BuildContext context) async{
final vid = await ImagePicker().pickVideo(source: src);
if(vid != null){
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => VideoUploader(
videoPath: vid.path, videoName:vid.name,
videoFile:File(vid.path)
)));
}
} //To Pick a Video
showDialogueBox(BuildContext, context){
return showDialog(context: context, builder: (context) => SimpleDialog(
children: [
SimpleDialogOption(
onPressed: () => vidPicker(ImageSource.gallery, context),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: const [
Icon(Icons.image),
Text(" Gallery ")
],
),
),
),
SimpleDialogOption(
onPressed: () => Navigator.of(context).pop(),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: const [
Icon(Icons.cancel),
Text(" Cancel ")
],
),
),
)
],
));
} //TO Show Option Like Gallery and Cancel
class _ReelsState extends State<Reels> {
#override
Widget build(BuildContext context) {
return Scaffold(
extendBodyBehindAppBar: true,
appBar: AppBar(
automaticallyImplyLeading: false,
elevation: 0,
flexibleSpace: SizedBox(
height: 200,
child: Padding(
padding: const EdgeInsets.all(15.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
IconButton(onPressed: () => showDialogueBox(BuildContext,context),
icon: const Icon(Icons.add),
iconSize: 35,
color: Colors.teal[300],
)
],
),
),
),
backgroundColor: Colors.transparent,
),
body: StreamBuilder(
stream: fireStore.collection("videoReels").snapshots(),
builder: (context, AsyncSnapshot<QuerySnapshot> snapshot) {
// TODO: Put Progress Bar Here
if (!snapshot.hasData) return const Text("Loading...");
return PageView.builder(
itemCount: snapshot.data!.docs.length,
scrollDirection: Axis.vertical,
controller: PageController(viewportFraction: 1, initialPage: 0),
itemBuilder: (context, index){
DocumentSnapshot dataSnapshot = snapshot.data!.docs[index];
return Stack(
alignment: Alignment.bottomCenter,
children: [
VideoPlayerContent(videoUrl: dataSnapshot["videoUrl"]),
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Expanded(
flex: 3,
child: Container(
height: MediaQuery.of(context).size.height/6,
padding: const EdgeInsets.all(10.0),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Row(
children: [
InkWell(
onTap: () => {},
child: const Icon(Icons.thumb_up, color: Colors.blueAccent,),
),
const SizedBox(width: 30,),
InkWell(
onTap: () => {},
child: const Icon(Icons.favorite, color: Colors.red,),
)
],
),
const SizedBox(width: 20,),
InkWell(
onTap: () => {},
child: Text(" Add Comment here... ", style: TextStyle( color: Colors.grey[500] ),),
)
],
),
const SizedBox(height: 30,),
// Second Row
Padding(
padding: const EdgeInsets.fromLTRB(30.0, 4.0,30.0,4.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
InkWell(
onTap: () => { } ,
child:ClipRRect(
borderRadius: BorderRadius.circular(50.0),
child: CircleAvatar(backgroundImage: NetworkImage(dataSnapshot['avatar']), radius: 25,),
),
),
Text((dataSnapshot["videoUrl"])),
ElevatedButton(onPressed: ()=> {}, child: Text("Subscribe"))
],
),
)
],
),
),
),
// TODO: Remove this later
],
)
],
);
},
);
}
),
);
}
}
import 'package:app/packageManager/package.dart';
class VideoPlayerContent extends StatefulWidget {
final videoUrl;
const VideoPlayerContent({Key? key, required this.videoUrl}) : super(key: key);
#override
State<VideoPlayerContent> createState() => _VideoPlayerContentState();
}
class _VideoPlayerContentState extends State<VideoPlayerContent> {
late VideoPlayerController _videoController;
late Future _initializeVideoPlayer;
#override
void initState(){
_videoController = VideoPlayerController.network(widget.videoUrl);
_initializeVideoPlayer = _videoController.initialize();
_videoController.play();
_videoController.setVolume(1);
_videoController.setLooping(true);
super.initState();
}
#override
void dispose (){
_videoController.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
child: FutureBuilder(
future: _initializeVideoPlayer,
builder: (context, snapshot){
if (snapshot.connectionState == ConnectionState.done){
return VideoPlayer(_videoController);
}else{
return Container(
color: Colors.black,
child: const Center(
child: CircularProgressIndicator(
value: 0.8,
valueColor: AlwaysStoppedAnimation<Color>(Colors.purpleAccent),
),
)
);
}
},
),
);
}
}

Have you tried WidgetsBindingObserver and VisibilityDetector?
If you have not, then it might be handy to you.
For WidgetBindingObserver, simply use it as mixin like this:
class _VideoPlayerContentState extends State<VideoPlayerContent> with WidgetsBindingObserver{
#override
void initState(){
WidgetsBinding.instance?.addObserver(this);
super.initState();
}
#override
void didChangeAppLifecycleState(AppLifecycleState state) {
switch (state) {
case AppLifecycleState.resumed:
// TODO: Handle this case.
break;
case AppLifecycleState.inactive:
// Do like this in other lifecylestate if required !
_videoController.pause();
// TODO: Handle this case.
break;
case AppLifecycleState.paused:
// TODO: Handle this case.
break;
case AppLifecycleState.detached:
// TODO: Handle this case.
break;
}
super.didChangeAppLifecycleState(state);
}
// rest of the code .....
#override
void dispose(){
WidgetsBinding.instance?.removeObserver(this);
super.dispose();
}
}
Using visibility detector:
simply wrap the video player with this widget like:
VisibilityDetector(
// Must provide key
key: ValueKey<String>('give any string value to represent key'),
onVisibilityChanged: (visibilityInfo) {
// 0 ---> visible, 1 --> not visible
if(visibilityInfo.visibleFraction == 0){
_videoController.pause();
// might need setState over here
}
},
child : VideoPlayer(_videoController)
);

Related

How to use the pageview inside show dialog (Flutter)?

The first section is an automatic page that I want to make in a dialog box with Flutter.
This is the code I used to try it out, but I couldn't get to what I wanted
Please help me with this by showing the pageView and auto indicator in the dialog
import 'package:flutter/material.dart';
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
#override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
final PageController _controller = PageController(initialPage: 0);
#override
void dispose() {
_controller.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: ElevatedButton(
child: const Text("Show Dialog"),
onPressed: () {
showDialog(
context: context,
builder: (BuildContext context) => AlertDialog(
title: const Text('Warning'),
content: PageView(
controller: _controller,
children: [
Container(width: double.infinity, height: double.infinity, color: Colors.yellow),
Container(width: double.infinity, height: double.infinity, color: Colors.red),
Container(width: double.infinity, height: double.infinity, color: Colors.black),
],
),
actionsAlignment: MainAxisAlignment.center,
actions: <Widget>[
Column(
children: [
ElevatedButton(onPressed: () {}, child: const Text("CONTINUE")),
OutlinedButton(onPressed: () {}, child: const Text("NO THANKS"))
],
),
],
),
);
},
),
),
);
}
}
We need to provide size on PageView. Based on your attached image, I am using LayoutBuilder to get the constraints and providing 30% height of the dialog. Use constraints to provide size.
showDialog(
context: context,
builder: (BuildContext context) =>
LayoutBuilder(builder: (context, constraints) {
debugPrint("${constraints.toString()}");
return AlertDialog(
title: const Text('Warning'),
content: Column(
children: [
SizedBox(
height: constraints.maxHeight * .3,
width: constraints.maxWidth,
child: PageView(
controller: _controller,
children: [
Container(color: Colors.yellow),
Container(color: Colors.red),
Container(color: Colors.black),
],
),
),
],
),
actionsAlignment: MainAxisAlignment.center,
actions: <Widget>[
Column(
children: [
ElevatedButton(
onPressed: () {},
child: const Text("CONTINUE")),
OutlinedButton(
onPressed: () {},
child: const Text("NO THANKS"))
],
),
],
);
}));
If you find the content get overflow after adding many widget wrap top column with SingleChildScrollView
showDialog(
context: context,
builder: (BuildContext context) =>
LayoutBuilder(builder: (context, constraints) {
debugPrint("${constraints.toString()}");
return AlertDialog(
title: const Text('Warning'),
content: SingleChildScrollView(
child: Column(
More about LayoutBuilder

View behind Scaffold - Flutter/Dart

I tried a lot to get the behavior of the iOS project https://github.com/ivanvorobei/SPLarkController working in Flutter / Dart. I do not understand how to get another view behind the scaffold (holding also the bottom navigation bar). Any ideas how this can be achieved?
This could be achieved with the help of Stack.
First layer for the buttons on the bottom:
Second layer for the main content:
Then, you can wrap the BottomNavBar inside GestureDetector with onVerticalDragUpdate property.
Complete Code:
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Builder(
builder: (context) => MyChild(MediaQuery.of(context).size.height),
),
),
);
}
}
class MyChild extends StatefulWidget {
final double screenHeight;
const MyChild(this.screenHeight, {Key? key}) : super(key: key);
#override
_MyChildState createState() => _MyChildState();
}
class _MyChildState extends State<MyChild> {
double val = 1.0;
#override
Widget build(BuildContext context) {
return Stack(
children: [
Container(
padding: const EdgeInsets.only(bottom: 20.0),
color: const Color(0xFF303030),
child: Padding(
padding: const EdgeInsets.only(left: 20.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Row(
children: [
ElevatedButton(
onPressed: () {}, child: const Text('Button 1')),
const SizedBox(
width: 20.0,
),
ElevatedButton(
onPressed: () {}, child: const Text('Button 2'))
],
),
const SizedBox(
height: 20,
),
Row(
children: [
ElevatedButton(
onPressed: () {}, child: const Text('Button 3')),
const SizedBox(
width: 20.0,
),
ElevatedButton(
onPressed: () {}, child: const Text('Button 4'))
],
),
],
),
),
),
LayoutBuilder(
builder: (context, constraints) => AnimatedContainer(
duration: const Duration(milliseconds: 500),
curve: Curves.ease,
height: constraints.maxHeight * val,
color: Colors.white,
child: Column(
children: [
Expanded(
child: ListView.builder(
physics: const BouncingScrollPhysics(),
itemCount: 25,
itemBuilder: (context, index) => ListTile(
title: Text('ListTile $index'),
),
),
),
GestureDetector(
onVerticalDragUpdate: (details) {
if (details.delta.dy < 0) { // If the user drags upwards
setState(() {
val = 0.7;
});
} else if (details.delta.dy > 0) { // If the user drags downwards
setState(() {
val = 1.0;
});
}
},
// Create your bottom navigation bar here
// and not bottomNavigationBar property of Scaffold
child: Container(
color: Colors.green.shade100,
height: 80,
),
)
],
),
),
),
],
);
}
}

Flutter showModalBottomSheet to show ontop of BottomNavigationBar

I want to show a modalsheet like this
above the BottomsNavigationBar like so. I have tried this: But then my whole bottomNavigationBar menu becomes unclickable.
My code for this is:
Widget build(BuildContext context) {
final theme = Theme.of(context);
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
return WillPopScope(
onWillPop: () => _willPopCallback(context),
child: Scaffold(
key: _scaffoldKey,...
bottomNavigationBar: BottomNavigationBar(
onTap: (v) {
_scaffoldKey.currentState!.showBottomSheet<Null>(
(BuildContext context){
return GridView.count....
}
}).....
Then this is my original code:
#override
Widget build(BuildContext context) {
final theme = Theme.of(context);
return WillPopScope(
onWillPop: () => _willPopCallback(context),
child: Scaffold(
body: PageView(
controller: _controller,
physics:const NeverScrollableScrollPhysics(),
onPageChanged: (v) => setState(() => _selectedIndex = v),
children: BottomNavigationList.pageList(context),
),
bottomNavigationBar: BottomNavigationBar(
onTap: (v) {
setState(() {
if (v == 3) {
showModalBottomSheet(
...
builder: (BuildContext context){
return GridView.count...
but then it is going ontop of the BottomNavigationBar. Like this:
Is there any way I can have it clipped on top of the BottomNavigationBar like in the first image or a FAB
UPDATE: I have tried the suggested implementation and got this:
Maybe let me try to rephrase: so the first image has 3 rows, the most bottom row is the bottomNavigationBar. When and if you click on it when you are on that selectedIndex of the bottomNav, the other two rows have to show, WITHOUT obscuring the bottomNav. #Yeasin, in your solution there, the purple row has to show when the hamburger menu is pressed, and hide when pressed again that is why I had used the showModalBottomSheet and also tried the showBottomSheet
You can use Stack Or Column with boolean to handle view.
Using Column
class _CustomViewState extends State<CustomView> {
bool _showBottomSheet = false;
#override
Widget build(BuildContext context) {
return Scaffold(body: LayoutBuilder(
builder: (context, constraints) {
return Column(
children: [
Expanded(
child: CustomScrollView(
slivers: [
SliverToBoxAdapter(
child: ElevatedButton(
onPressed: () {
setState(() {
_showBottomSheet = !_showBottomSheet;
});
},
child: Text(
"show btmSheet",
)),
),
],
),
),
if (_showBottomSheet)
SizedBox(
//get single gridWith * mainAxisCount
height: constraints.maxWidth / 4 * 2, //based on your view
child: GridView.count(
crossAxisCount: 4,
physics: NeverScrollableScrollPhysics(),
children: [
...List.generate(
8,
(index) => Container(
color: Colors.pink,
child: Text("$index"),
),
)
],
),
),
Container(
width: constraints.maxWidth,
color: Colors.deepPurple,
height: kToolbarHeight,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
...List.generate(
4,
(index) => ElevatedButton(
onPressed: () {
print("tapped on $index");
},
child: Text("$index"),
),
)
],
),
)
],
);
},
));
}
}
Using Stack
class CustomView extends StatefulWidget {
CustomView({Key? key}) : super(key: key);
#override
_CustomViewState createState() => _CustomViewState();
}
class _CustomViewState extends State<CustomView> {
bool _showBottomSheet = false;
#override
Widget build(BuildContext context) {
return Scaffold(body: LayoutBuilder(
builder: (context, constraints) {
return Stack(
children: [
Align(
alignment: Alignment.center, // based on UI,
child: CustomScrollView(
slivers: [
SliverToBoxAdapter(
child: ElevatedButton(
onPressed: () {
setState(() {
_showBottomSheet = !_showBottomSheet;
});
},
child: Text(
"show btmSheet",
)),
)
],
),
),
Align(
alignment: Alignment.bottomCenter,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
if (_showBottomSheet)
SizedBox(
height: 100,
child: GridView.count(
crossAxisCount: 4,
physics: NeverScrollableScrollPhysics(),
children: [
...List.generate(
8,
(index) => Container(
color: Colors.pink,
))
],
),
),
Container(
width: constraints.maxWidth,
color: Colors.deepPurple,
height: kToolbarHeight,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
...List.generate(
4,
(index) => ElevatedButton(
onPressed: () {
print("tapped on $index");
},
child: Text("$index"),
),
)
],
),
)
],
),
)
],
);
},
));
}
}

Fixed buttons between AppBar and SingleChildScrollView (Flutter)

I would like to include buttons between AppBar and ListView. In the example below, the buttons scroll along with the text. I tried to include the SingleChildScrollView within a Column, but was unsuccessful.
I read that the Column widget does not support scrolling. I already searched a lot, but I didn't find an example similar to what I need.
Can someone help me?
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('A Idade do Lobo'),
elevation: 0.0,
backgroundColor: COLOR_MAIN,
),
body: NotificationListener(
onNotification: (notif) {
if (_hasScroll) {
if (notif is ScrollEndNotification && scrollOn) {
Timer(Duration(seconds: 1), () {
_scroll();
setState(() {
_controlButton();
});
});
}
}
return true;
},
child: SingleChildScrollView(
controller: _scrollController,
child: new Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
new Center(
child: new Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
new RaisedButton(
onPressed: _showScrollPickerDialog,
child: Text('Rolagem ${_scrollSpeed}'),
),
new RaisedButton(
onPressed: _showTomPickerDialog,
child: Text('TOM ${_tom}'),
),
],
),
),
new Flexible(
fit: FlexFit.loose,
child: new ListView.builder(
shrinkWrap: true,
itemCount: _songDetails.length,
itemBuilder: (context, index) {
return new Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding: new EdgeInsets.all(5.0),
child: new RichText(
text: TextSpan(children: [
new TextSpan(
text: '${_songDetails[index].line}',
style: _getStyle(
_songDetails[index].type,
),
),
]),
),
),
],
);
},
),
),
],
),
),
),
floatingActionButton: _controlButton(),
);
}
}
You can use bottom properly of AppBar to achieve desire UI.
Following example clear your idea.
import 'package:flutter/material.dart';
class DeleteWidget extends StatefulWidget {
const DeleteWidget({Key key}) : super(key: key);
#override
_DeleteWidgetState createState() => _DeleteWidgetState();
}
class _DeleteWidgetState extends State<DeleteWidget> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("your title"),
bottom: PreferredSize(
preferredSize: Size(MediaQuery.of(context).size.width, 40),
child: Center(
child: new Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
new RaisedButton(
onPressed: () {},
child: Text('Rolagem '),
),
new RaisedButton(
onPressed: () {},
child: Text('TOM '),
),
],
),
),
),
),
body: Container(
child: ListView.builder(
itemBuilder: (context, int index) {
return Text(index.toString());
},
itemCount: 100,
),
));
}
}

Could not find the correct Provider - Flutter

#override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () async {
return false;
},
child: Stack(
children: <Widget>[
DefaultTabController(
length: 5,
child: ChangeNotifierProvider(
builder: (context) => MySchedule(),
child: (
Scaffold(
appBar: AppBar(
actions: <Widget>[
Container(
width: MediaQuery.of(context).size.width,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
GestureDetector(
onTap: () async{
await Navigator.of(context).push(
MaterialPageRoute(builder: (context){
return InApp();
})
);
final MySchedule schedules = Provider.of<MySchedule>(context);
schedules.numberOfCoins = 10;
},
child: Card(
child: Padding(
padding: const EdgeInsets.all(4.0),
child: Row(
children: <Widget>[
Consumer<MySchedule>(
builder: (context, coin, _) =>
buildCoinBar(coin),
),
SizedBox(
width: 2,
),
Stack(
children: <Widget>[
Image.asset('assets/coin2.png',
height: 22, width: 22,),
],
),
],
),
),
),
),
Image.asset('assets/LOGO.png'),
Consumer<MySchedule>(
builder: (context, userdata, _) =>
topRightElement(userdata, context),
),
],
),
)
],
automaticallyImplyLeading: false,
bottom: TabBar(
labelStyle: TextStyle(fontSize: 8),
tabs: [
Consumer<MySchedule>(
builder: (context, schedule, _) =>
buildNewCardNotification(schedule),
),
Tab(icon: Icon(Icons.star), text: 'Csapatom' ,),
Tab(icon: Icon(Icons.verified_user), text: 'Forduló',),
Tab(icon: Icon(Icons.stars), text: 'Kártyáim',),
Tab(icon: Icon(Icons.account_balance), text: 'Ligák',),
],
),
),
body: TabBarView(
children: [
Office(),
MyTeam(),
MatchListView(),
MyCardView(),
ChampionshipView2(),
],
),
)
),
),
),
Visibility(
visible: msgVisible,
child: SafeArea(
child: GestureDetector(
onTap: (){
setState(() {
msgVisible = false;
});
},
child: Padding(
padding: const EdgeInsets.all(2.0),
child: ClipRRect(
borderRadius: BorderRadius.circular(0.0),
child: Card(
shape: RoundedRectangleBorder(
side: new BorderSide(color: Colors.lightGreenAccent, width: 2.0),
borderRadius: BorderRadius.circular(16.0)),
elevation: 8,
color: Colors.black87,
child: Container(
height: 64,
width: MediaQuery.of(context).size.width,
child: Row(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(10.0),
child: Image.asset('assets/LOGO.png', height:44),
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Text(title, style: TextStyle(
fontSize: 16,
color: Colors.lightGreenAccent
),),
Text(body,
overflow: TextOverflow.ellipsis)
],
),
],
),
),
),
),
),
),
),
)
],
),
);
}
I try to modify the numberOfCoins variable, when I pop the InApp() class.
But I have the following error:
[VERBOSE-2:ui_dart_state.cc(148)] Unhandled Exception: Error: Could
not find the correct Provider above this FantasyNbi Widget
To fix, please:
Ensure the Provider is an ancestor to this FantasyNbi
Widget * Provide types to Provider * Provide types to
Consumer * Provide types to Provider.of()
Always use package imports. Ex: import 'package:my_app/my_code.dart'; * Ensure the correct context` is
being used.
You need a builder bridge between ChangeNotifierProvider and Scaffold.
Provider package already has it's own builder called Consumer, you can use it like:
ChangeNotifierProvider<MySchedule>(
create: (context) => MySchedule(),
child: Consumer<MySchedule>(
builder: (context, provider, child) => Scaffold(....,
Check this link: https://pub.dev/packages/provider#reading-a-value
edit: builder is now create.
According to the latest version of the Provider package, the builder() method of ChangeNotifierProvider was changed to create().
So editing Esen Mehmet's version, this will work instead:
ChangeNotifierProvider(
create: (context) => MySchedule(), //change builder to create
child: Consumer<MySchedule>(
builder: (context, provider, child) => Scaffold(....,
You can use provider as Below,
class HomeApp extends StatefulWidget {
#override
State<StatefulWidget> createState() {
// TODO: implement createState
return HomeAppState();
}
}
class HomeAppState extends State<HomeApp> {
final _user = UserModel();
#override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider<LoginNotifier>(create: (BuildContext context) {
return LoginNotifier();
}),
ChangeNotifierProvider<UserModel>.value(value: _user),
],
child: MaterialApp(
debugShowCheckedModeBanner: false,
theme: Provider.of<ThemeModel>(context).currentTheme,
home: HomeScreen(),
));
}
}