Update data every time a screen is shown on device in Flutter - android

I have a flutter app with redux state management.
In my app, I want to refetch some data from server when some other data in other screen changed. But in my case, I navigate from screen1 to screen2, and some data chaned in screen 2. I use a boolean flag needUpdate saved to redux and set to true after changes on screen 2.
But when I navigate back to screen1, I need to refetch data if the flag is true. But it did not work and data didnt refetch.
Here is some code:
class FirstScreen extends StatefulWidget {
const FirstScreen({Key? key}) : super(key: key);
#override
State<StatefulWidget> createState() => _FirstScreenState();
}
class _FirstScreenState extends State<FirstScreen> {
#override
void initState() {
super.initState();
}
#override
void didChangeDependencies() async {
final store = StoreProvider.of<AppState>(context);
var needUpdate = store.state.commonState?.needUpdate.value ?? false;
if (needUpdate) {
await store.dispatch(prepareData(context));
}
}
#override
Widget build(BuildContext context) {}
}
class SecondScreen extends StatefulWidget {
const SecondScreen({Key? key}) : super(key: key);
#override
State<SecondScreen> createState() => _SecondScreenState();
}
class _SecondScreenState extends State<SecondScreen> {
#override
void initState() {
super.initState();
}
void onPress() async {
await store.dispatch(ChangeNeedUpdatePortfolio(true));
Navigator.pop(context);
}
#override
Widget build(BuildContext context) {}
}
and Here is my action:
ThunkAction<AppState> updatePortfolioData(BuildContext context) {
return (Store<AppState> store) async {
bool needUpdate = store.state.commonState?.needUpdate.value ?? false;
if (needUpdate) {
...
await store.dispatch(ChangeNeedUpdatePortfolio(false));
...
return;
}
};
}

Related

How to call final outside class in flutter?

My form bloc is showing the alert "LateInitializationError: Field 'fileFieldBloc' has not been initialized". I initialize final InputFieldBloc<PlatformFile?,Object> fileFieldBloc; inside class HomePage extends StatefulWidget which was a stateful widget, but i can't call fileFieldBloc inside class _HomePageState extends State<HomePage> with SingleTickerProviderStateMixin, is there any way for me to initialize it? this is the code:
class HomePage extends StatefulWidget {
const HomePage({
Key? key, required this.fileFieldBloc}) : super(key: key);
final InputFieldBloc<PlatformFile?,Object> fileFieldBloc;
#override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> with SingleTickerProviderStateMixin {
late final InputFieldBloc<PlatformFile?, Object> fileFieldBloc;
String _image = 'https://ouch-cdn2.icons8.com/84zU-uvFboh65geJMR5XIHCaNkx-BZ2TahEpE9TpVJM/rs:fit:784:784/czM6Ly9pY29uczgu/b3VjaC1wcm9kLmFz/c2V0cy9wbmcvODU5/L2E1MDk1MmUyLTg1/ZTMtNGU3OC1hYzlh/LWU2NDVmMWRiMjY0/OS5wbmc.png';
late AnimationController loadingController;
File? _file;
PlatformFile? _platformFile;
selectFile() async {
final file = await FilePicker.platform.pickFiles(
type: FileType.custom,
allowedExtensions: ['png', 'jpg', 'jpeg']
);
if (file != null) {
setState(() {
_file = File(file.files.single.path!);
_platformFile = file.files.first;
});
}
loadingController.forward();
}
#override
void initState() {
loadingController = AnimationController(
vsync: this,
duration: const Duration(seconds: 10),
)..addListener(() { setState(() {}); });
super.initState();
}
#override
Widget build(BuildContext context) {
return BlocBuilder<InputFieldBloc<PlatformFile?, Object>,
InputFieldBlocState<PlatformFile?, Object>>(
bloc: fileFieldBloc,
builder: (context, state) {
return Scaffold(
i need to initialize final InputFieldBloc<PlatformFile?,Object> fileFieldBloc; so i could call it inside HomePage and _HomePageState
remove this line from your state
late final InputFieldBloc<PlatformFile?, Object> fileFieldBloc;
and use
bloc: widget.fileFieldBloc,
You can use widget.fileFieldBloc to call this field from the state class

When I open my flutter app it always shows Sign In screen for few seconds, even if I already signed In in my last session. And after that Main page?

final _navigatorKey = GlobalKey<NavigatorState>();
class MainApp extends StatefulWidget {
const MainApp({Key? key}) : super(key: key);
#override
_MainAppState createState() => _MainAppState();
}
class _MainAppState extends State<MainApp> {
#override
Widget build(BuildContext context) {
return GetMaterialApp(
localizationsDelegates: context.localizationDelegates,
supportedLocales: context.supportedLocales,
locale: context.locale,
navigatorKey: _navigatorKey,
color: Colors.white,
getPages: router.routes,
initialRoute: SignInPageRoute,
routingCallback: (routing) {
final _navigationService = locator<NavigationService>();
final _authService = locator<AuthService>();
if (routing!.current == SignInPageRoute) {
WidgetsBinding.instance!.addPostFrameCallback(
(_) {
bool isLoggedIn = _authService.isLoggedIn();
if (isLoggedIn) {
_navigationService.offAllTo(MainPageRoute);
} else {
return;
}
},
);
}
});
}
}
try with this
bool isLoggedIn = await _authService.isLoggedIn();

How to automatically hide the status bar after scrolling it down?

I want to automatically hide the status bar after 3 seconds of scrolling it down.
currently, I'm doing this.
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
#override
void initState() {
super.initState();
Timer.periodic(const Duration(seconds: 3), (timer) {
SystemChrome.setEnabledSystemUIOverlays([SystemUiOverlay.bottom]);
});
}
#override
Widget build(BuildContext context) {
return MaterialApp(
home: HomeScreen();
);
}
}
I want the timer to begin as soon as the user scrolls the the status bar.
Is there any better way to do that?
You may face existing issue on SystemChrome.
When setting System UI Overlays to bottom or top only, the status bar/bottom will show persistently after clicking.
Flutter problem full-screen on android #23913
SystemChrome.setEnabledSystemUIOverlays isn't sticky on android when only disable top #28426
I provide a workaround solution that detect status bar appear and react to it by using WidgetsBindingObserver
class _MyAppState extends State<MyApp> with WidgetsBindingObserver {
var count = 0;
#override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);
}
...
#override void didChangeMetrics() {
count++;
Future.delayed(const Duration(seconds: 3), () {
if(count == 1) {
SystemChrome.restoreSystemUIOverlays();
}
count --;
});
}
...
#override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}

how can progress-bar listen value changes using flutter provider and update another widget?

**this is my provider **
MultiProvider(
child: MyApp(),
providers: [
ChangeNotifierProvider(create: (BuildContext context)=> Downloads(),),)]
***this class implements notifylistner when i print out _progress it all works properly
but the ui wiget does not rebuid to give out the outputs ***
class Downloads extends ChangeNotifier {
int _progress= 0;
int get progress => _progress;
void setProgress(int p) {
_progress = p;
notifyListeners();
}
}
i have removed progress-bar widget to make it simple instead show output value
class FileDownload extends StatelessWidget {
const FileDownload({Key key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(body: progessUi());
}
}
class progessUi extends StatelessWidget {
const progessUi({Key key}) : super(key: key);
#override
Widget build(BuildContext context) {
final model = Provider.of<Downloads>(context);
return Container(child: Text(model.progress.toString()));
}
}
*this just a snippet where the calls to the Download function are made *
if (message['event'] == EV_PROGRESS) {
Downloads().setProgress(message['progress']);
}
if (message['event'] == EV_DONE) {
Downloads().setProgress(100);
}

Flutter: How to pass variables from StatelessWidget to StatefulWidget

The problem is that I cannot pass the values of my own class ForceSelection values from another screen to another screen's StatefulWidget. It works fine in StatelessWidget. I have tried to learn from this flutter tutorial: https://flutter.dev/docs/cookbook/navigation/passing-data#4-navigate-and-pass-data-to-the-detail-screen
I have this kind of class in levelSelection.dart
class ForceSelection {
final String forceSelection;
final String langSelection;
ForceSelection(this.forceSelection, this.langSelection);
}
I am trying to pass the values to next file PlayQuiz.dart
Game(forceSelection: ForceSelection('maa', 'fin'))
game.dart looks like this:
class Game extends StatelessWidget {
final ForceSelection forceSelection;
Game({Key key, #required this.forceSelection}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
title: forceSelection.langSelection, // TODO should work and change later
theme: new ThemeData(
primaryColor: Colors.white,
),
home: PlayQuiz(),
);
}
}
And I want to pass the ForceSelection values to PlayQuiz()
class PlayQuizState extends State<PlayQuiz> {
Game.forceSelection // <--- How can I get the value out of here?
}
class PlayQuiz extends StatefulWidget {
#override
PlayQuizState createState() => new PlayQuizState();
}
The whole code can be found here: https://pastebin.com/nKssz42R
and also levelSelection.dart: https://pastebin.com/8QbBD0A2
Try this code
Added forceSelecton argument in PlayQuiz()
class Game extends StatelessWidget {
final ForceSelection forceSelection;
Game({Key key, #required this.forceSelection}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
title: forceSelection.langSelection, // TODO should work and change later
theme: new ThemeData(
primaryColor: Colors.white,
),
home: PlayQuiz(forceSelection),
);
}
}
In Play Quiz
class PlayQuiz extends StatefulWidget {
final ForceSelection forceSelection;
PlayQuiz(this.forceSelection);
#override
PlayQuizState createState() => new PlayQuizState(forceSelection);
}
In PlayQuizState
class PlayQuizState extends State<PlayQuiz> {
ForceSelection forceSelection;
PlayQuizState(ForceSelection forceSelection) {
this.forceSelection = forceSelection;
}
}

Categories

Resources