SOLUTION - SystemUi Overlay Disappearing Using YoutubePlayerFlutter - flutter

If this happens when you after you go into full screen.
Before clicking fullscreen
When in fullscreen
Overlay gone on page
Overlay also gone on other pages
Then you will need to add
onExitFullScreen: () => SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual,overlays: SystemUiOverlay.values),
just under YoutubePlayerBuilder.
Widget build(BuildContext context) {
return YoutubePlayerBuilder(
onExitFullScreen: () => SystemChrome.setEnabledSystemUIMode(
SystemUiMode.manual,
overlays: SystemUiOverlay.values),
player: YoutubePlayer(controller: _ytController),
builder: (context, player) {
return Coumn(
children: [
Container(),
player,
]),
});
}
Apologies if this is not a through guide. I spent ages trying to find the problem that when I figured it out I thought id share as I couldn't find it myself online.
Let me know where you need me to clarify more and id be happy to flesh out more details.

Posted above. The reason this works is because YoutubePlayerFlutter removes the System UI when it enters fullscreen mode but it does not correctly add it back once leaving fullscreen mode.
If you have no need for the UI being removed in the Fullscreen mode then instead place the () => SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual,overlays: SystemUiOverlay.values), under onEnterFullScreen: instead of onExitFullScreen:

Related

How to programmatically dismiss a Showcase view in flutter?

I am using showcaseview package for displaying a message in a screen. It is dismissed when we click anywhere on the screen. But if the user came to that page and use the backbutton for going back, the showcase is not getting dismissed. Is there any way to dismiss the showcaseview other than touching the screen.
I highly think from what I got from your question that the show case view starts every time you go to that page, so you can pass a parameter to choose to show case view or not when open the page like :
Navigator.push<void>(
context,
MaterialPageRoute<void>(
builder: (_) => const Detail(showCaseView:false),
),
);
and in Details screen where you use show case view :
#override
void initState() {
super.initState();
if(isShowCaseView){
WidgetsBinding.instance
ambiguate(WidgetsBinding.instance)?.addPostFrameCallback(
(_) => ShowCaseWidget.of(context)
.startShowCase([_one, _two, _three, _four, _five]),
);
}

How to check if screen is fully loaded?

Problem: One of screen in my app has bunch of network images that are being fetched from an API. When user navigates to that screen some images load faster than others, hence users sees a screen that is not fully loaded.
Expected behaviour: I want to show a CircularProgressIndicator until all the network images are fully loaded.
P.S. Below code doesn't do what I wanted, as it executes the function while images are still loading.
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) => yourFunction(context));
}
Also I am using SvgPicture.network from flutter_svg package.
final Widget networkSvg = SvgPicture.network(
'https://site-that-takes-a-while.com/image.svg',
semanticsLabel: 'A shark?!',
placeholderBuilder: (BuildContext context) => Container(
padding: const EdgeInsets.all(30.0),
child: const CircularProgressIndicator()),
);
Maybe this could help Flutter image preload

How to avoid jank (laggy animation) during page transition in Flutter

I have two pages, Page A and Page B.
To do transition from Page A to Page B I use Navigation.push():
Navigator.push(
context,
CupertinoPageRoute(...)
);
However, this transition has so much jank and frame drops. (yes, I run in Profile mode)
One reason I think of is Page B has so much heavy-duty UI rendering (such as Google Maps and Charts) and I also noticed as page slide animation is happening, Page B rendering has already begun.
I'm trying to understand how I can improve this experience and maybe somehow pre-load Page B.
I already read this suggestion from a Github issue (tldr use Future.microtask(()) but it didn't work for me. Would appreciate any help or suggestion.
If the screen transition animation is especially janky the first time you run the app, but then gets smoother if you run the transition back and forth a few times, this is a known problem that both the Flutter team and their counterparts within Android and iOS are working on. They have a suggestion for a workaround here: https://docs.flutter.dev/perf/shader , built on "warming up shaders", but since it only warms up the shaders on the specific device you're debugging on, I honestly feel it's like the programming equivalent of "sweeping it under the rug"... You won't see the problem on your device anymore, but it's still there on other devices!
I however found a workaround for this problem myself, which works surprisingly well! I actually push the janky page, wait a bit, and then pop it again, without the user knowing it! 🙂 Like this:
import 'login_screen.dart';
import 'register_screen.dart';
import 'home_screen.dart';
import 'loading_screen.dart';
import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';
class WelcomeScreen extends StatefulWidget {
const WelcomeScreen(Key? key) : super(key: key);
#override
_WelcomeScreenState createState() => _WelcomeScreenState();
}
class _WelcomeScreenState extends State<WelcomeScreen> {
#override
void initState() {
super.initState();
warmUp();
}
Future warmUp() async {
// This silly function is needed to remove jank from the first run screen transition...
print('Running warmUp()');
await Firebase.initializeApp();
// If not using Firebase, you'll have to add some other delay here!
// Otherwise, you will get errors below for trying to push new screens
// while the first one is still building.
if (mounted) {
Navigator.push(context, MaterialPageRoute(builder: (context) => LoginScreen(popWhenDone: false)));
Navigator.push(context, MaterialPageRoute(builder: (context) => RegisterScreen(popWhenDone: false, userType: UserType.artist)));
Navigator.push(context, MaterialPageRoute(builder: (context) => HomeScreen()));
Navigator.push(context, MaterialPageRoute(builder: (context) => LoadingScreen())); // Shows a spinner
await Future.delayed(Duration(milliseconds: 1000));
if (mounted) {
Navigator.popUntil(context, (route) => route.isFirst);
}
}
}
#override
Widget build(BuildContext context) {
print('Building $runtimeType');
return Scaffold(
body: SafeArea(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
MaterialButton(
child: const Text('Sign Up'),
onPressed: () {
Navigator.push(context, MaterialPageRoute(builder: (context) {
return const RegisterScreen();
}));
},
),
MaterialButton(
child: const Text('Log In'),
onPressed: () async {
await Firebase.initializeApp(); // In case I remove the warmUp() later...
if (mounted) {
Navigator.push(
context,
PageRouteBuilder(
pageBuilder: (context, a1, a2) {
return LoginScreen();
},
transitionsBuilder: (context, a1, a2, child) {
return child; // I want only a Hero animation between the screens, nothing else
},
transitionDuration: const Duration(milliseconds: 1000),
),
);
}
},
),
],
),
Expanded(
flex: 4,
child: Hero(tag: 'logoWText', child: Image(image: AssetImage(kImageLogoWText))),
),
],
),
),
);
}
}
This ads a second of waiting for the app to load, with a spinner showing, but I find that most times, the spinner barely has time to show anyway, and in any case, it is a much better user experience to wait a sec for the app to load than to experience jank during use!
Other tips
If your screen transitions are still janky, even if you have run them back and forth, then you probably need to trim the performance of the screens involved. Perhaps it is your build method that's too big, and has too many things going on in it? Maybe certain widgets get rebuilt many times during each build of the screen?
Check out these pieces of advice and see if it helps: https://docs.flutter.dev/perf/best-practices In any case, they should improve your app's performance in general. 🙂
Edit: And check out this link, as provided by ch271828n in a comment below: https://github.com/fzyzcjy/flutter_smooth
If you are having jank without the shader compilation problem, then there is indeed a (new) approach to make it ~60FPS smooth without changing your code (indeed, only need to add 6 characters - CupertinoPageRoute -> SmoothCupertinoPageRoute).
GitHub homepage: https://github.com/fzyzcjy/flutter_smooth
Indeed, I personally see such jank (i.e. jank not caused by shader compilation) a lot in my app, maybe because the new page is quite complicated.
Disclaimer: I wrote that package ;)
Try adding a small delay before loading the initial tasks in page B. Maybe with a Future.delayed()

How to return from a widget to StreamBuilder after navigating to another page in flutter app?

So the first picture has codes from the first page where I have a StreamBuilder in my flutter app, there I tried navigating to the stateful widget named PickupScreen containing the code in second picture and it gave me an error which says SetState( or markNeedsbuild() called during build.So I called the widget directly and it worked but the problem is I cannot go the previous page I know I can't use pop but I need a solution for returning to previous page and show the else code.Currently I am Navigating to another page named HomePage.
You can't do it like that. Either you manage your screen state based on your widget.channel.stream or you must design your UI in a different way so you can actually push a new screen on your screen 1 and then you will be able to pop.
If you still want to keep it like that, you can do something like the following in your first screen:
return StreamBuilder(
stream: widget.channel.stream,
builder: (context, snapshot){
if(snapshot.hasData && jsonDecode(snapshot.data['ntype'] == 10){
WidgetsBinding.instance.addPostFrameCallback((_) => Navigator.push(context, MaterialPageRoute(builder: (_) => PickupScreen(data: jsonDecode(snapshot.data))));
return const SizedBox();
} else {
return _isLoading ? LoadingScreen() : Scaffold();
}
});
Also, next time, make sure you copy/paste code instead of screenshots to make it easy to edit with modifications. :)

Hide fingerprint screen when coming back from Home screen

i have app with two screens,one fingerprint screen and another home screen.once
fingerprint is authenticated i will get routed to home screen(using navigator.push()),but if I click back button in phone now it is getting routed to fingerprint screen again.Now how to close the app instead of routing back to finger print screen?
Use Navigator.pushReplacement. It will replace the current topmost widget on the stack with the new one instead of simply pushing it on top.
Example usage -
Navigator.pushReplacement(
context, MaterialPageRoute(builder: (BuildContext context) => MyHomePage()));
More documentation about this method can be found here.
put your homepage scaffold inside WillPopScope as a child
WillPopScope(
child: Scaffold(...),
onWillPop: () async {
return false;
},
),