devs
I have a situation where I want to change my root view based on condition. For example, if a user is logged in already then root view will be Home screen else login screen.
How can I achieve this? Please help.
Thank you
in your main.dart File you have the function void main() => runApp(MyApp()); where MyApp is a widget returing a MaterialApp widget or something similar. You can already select here to start with a different home widget.
If you have to select the start screen based on some asynchronous operation (like checking settings in Preferences or Secure Storage), you return a FutureBuilder instead of your MaterialApp. The FutureBuilder then returns the widget after finishing the operation.
Related
I am trying to create a radio application via Flutter.
However, I cannot update the slider value when I increase or decrease the volume by iPhone button. I am using volume control and audioplayers packages.
Does this not do what you want: https://pub.dev/packages/volume_control
Found that in 5 seconds of searching pub. Please get to know the resources you have available.
If I understand correctly, the issue is detecting when the physical volume up/down buttons are pressed and updating the slider to match. I would check out hardware_buttons.
You should be able to listen for the button being tapped using something like this (from their example)
StreamSubscription _volumeButtonSubscription;
#override
void initState() {
super.initState();
_volumeButtonSubscription = volumeButtonEvents.listen((VolumeButtonEvent event) {
// do something
// event is either VolumeButtonEvent.VOLUME_UP or VolumeButtonEvent.VOLUME_DOWN
});
}
Then use volume_control to get the current volume
// Get the current volume, min=0, max=1
double _val = await VolumeControl.volume;
And finally call setState to update the slider with the current volume.
Black screen appears for a short amount of time when changing from one Material App to another one. This only happens if I set localizationDelegates of MaterialApp.
You can run the following repo to reproduce the issue:
https://github.com/figengungor/localization_black_screen
I am not sure what causes that black screen. Do you have any idea?
Your issue happens because you update the widget tree from
Foo
MaterialApp
to
Foo
Bar
MaterialApp
This makes flutter hard reset the state of MaterialApp, triggering to loading.
You should avoid this in general. It'd be better to either always insert Bar with null datas, or use a GlobalKey as such:
final key = GlobalKey();
// ...
Widget build(BuildContext context) {
final app = MaterialApp(key: key);
return someCondition
? Bar(child: app)
: app;
}
GlobalKey purposefully reuse the previous Element associated with the key
I am trying to pop all the routes before i navigate to my dashboard screen in my flutter app, but the screen is only displaying from the half of the screen,
I have attached a screenshot for reference and i am using the following code in my app.
Navigator.popUntil(context, ModalRoute.withName('/'));
Navigator.push(context, new MaterialPageRoute(builder: (BuildContext context) => new BottomNavBar(0)));
this is just so annoying i have tried too many ways to navigate to the screen and every time i only see the half of the screen and i am not sure what actually is going wrong.
my only intention is I want to pop all the routes before i navigate to a route named '/dashboard' in my app.
Please can someone tell me what might have gone wrong.
Many Thanks
Mahi
I'm not sure whether this is the recommended way of doing it, but I've implemented that before like this:
Navigator.of(context).pushNamedAndRemoveUntil("/dashboard", (Route r) => r == null);
I have a button that allows to hide itself and another widget when pressed. When it is hidden, a new button appears on the screen which can undo (show) the previous button and widget again.
I'm pretty sure my implementation for this works because I've tested it on multiple devices without any problems, but whenever I try to write a formal test for it, something goes wrong. I'm using the following code to test my widget:
await tester.tap(find.widgetWithText(GestureDetector, "HIDE"));
expect(testContainerState.ifContainerWithOptionsIsDisplayed, false);
print(find.byType(GestureDetector));
await tester.tap(find.widgetWithText(GestureDetector, "SHOW"));
expect(testContainerState.ifContainerWithOptionsIsDisplayed, true);
The first two lines are there to tap the button and check whether ifContainerWithOptionsIsDisplayed changed. In my implementation, this is done in a setState method and should repaint to hide the widget and button and show the new button.
In the third line, I check how many GestureDetectors I can still find after what should be a repaint. The output of that print statement still shows me that all of the GestureDetectors of the widget that should now be hidden are still being found.
In the 4th line, I try to find my SHOW button that should now be visible because of the repaint. But no element is found.
Again, I'm pretty sure the code for my widgets are correct because I've tested this test case manually without any issues. Perhaps I'm missing some knowledge about Flutter tests. Could someone please fill me in?
await tester.pump();
or just
tester.pump();
should do that
See also
https://docs.flutter.io/flutter/flutter_test/WidgetTester/pump.html
https://docs.flutter.io/flutter/flutter_test/WidgetTester/pumpAndSettle.html
https://flutter.institute/flutter-and-widget-tests/
I'm working on a today view extension with some custom view elements which I don't set up in interface builder.
Now I'm wondering where the right point in the lifecycle is to init the widget content.
I read about updating the content in widgetPerformUpdateWithCompletionHandler so I implemented a check for new updates which should about the view.
But my observations showed me that the method is called before viewDidAppearand so there is no view to update.
Also I tought the widget stays in memory for a while so that I can have a certain object in widgetPerformUpdateWithCompletionHandler whose content I can update and use in viewDidAppear but this isn't the case (it loads every time)
So what is the correct way: write content to disk in the widgetPerformUpdateWithCompletionHandler, can I depend on something that is in memory or just ignore and refresh on every load?
In TodayViewController.m -viewDidLoad() method is called each time you open notification. So when ever you check Today widget it will call -viewDidLoad(). So you do your customisation in -viewDidLoad(). Unless you don't want to check previous state.
Straight from a blog which helps a create Today widget with real time data:
Creating today widget
Caching
We can take advantage of NSUserDefaults to save the calculated used space between launches. The lifecycle of a widget is short so if we cache this value, we can set up the user interface with an initial value and then calculate the actual value.
Edit:
From Apple documentation it state that
To help your widget look up to date, the system occasionally captures snapshots of your widget’s view. When the widget becomes visible again, the most recent snapshot is displayed until the system replaces it with a live version of the view.
It is also state that from Notification center, We can get widget details of state and snapshot.
Not sure with this, but it state that below method is used by both widget and containing app to check its content. There is no much details about how to get widget snapshot.
func setHasContent(_ flag: Bool,
forWidgetWithBundleIdentifier bundleID: String!)
NCWidgetController setHasContent
Edit 2: Use of NSUserDefaults in extension:
You have two .entitlements files, one for host app and second for the extension app, add below key in both files
<key>com.apple.security.application-groups</key>
<array>
<string>group.YourExtension</string>
</array>
You see the value for key is group.YourExtension it is shared
common key for both host app and extension app
Save your data using group.YourExtension in NSUserDefaults