I'm working on a flutter application. But the page transition is not smooth. And I can't find the problem to solve it;
The pages stop for a second before finished its transition
I'm using
import 'package:page_transition/page_transition.dart';
Navigator.push(context, PageTransition(type: PageTransitionType.leftToRight, child: Service()));
But even before using this I have this problem
Can Anyone help me, please?
EDIT:
I'm using shared_preferences to save local data like user name and order data and so on.
My initState() usually reads userdata in each page to show it in the drawer
#override
void initState() {
checkInternet();
GetUserData();
GetOrderData();
super.initState();
}
Related
Hello hope you guys are ok.
the problem I'm facing is we have a main_page which leads to a page doing some changes on data which are show on the main page.
after some process if the user touches back button and goes to main_page app loads it from stack and the data are not shown because it does not get rebuilt.
I don't want to control back button because there are other pages which lead to data changing page and I also tried using valuelistenablebuilder but I don't know why it goes wild and gets into a screen refresh loop without even changing the valueListenable I used redux to manage the value.
actual reason I want main page to rebuild is to call a method. why do I not call that method in second page is complicated and because i don't want to.
in conclusion I want main page to rebuild whenever it shows up even when it's read from the stack or even is there a way to tamper with stack of the pages without visual changes to the user.
you need to use Shared preferences plugin
https://pub.dev/packages/shared_preferences
If I understood the question correctly
The flow should be:
Screen A
#override
void initState() {
loadSomeDataFromDB();
super.initState();
}
Screen B
#override
void initState() { *//INIT AS EXAMPLE*
changeSomeDataFromDB();
super.initState();
}
You can try this in Screen A
onPressed: () async {
bool? shouldLoadDataAgain = await
Navigator.of(context).push(PageRouteBuilder(
pageBuilder: (context, animation, secondaryAnimation) =>
const ScreenB(),
));
if(shouldLoadDataAgain!=null&&shouldLoadDataAgain ==true){
loadSomeDataFromDB();
}
},
and this in Screen B when user press back button
onPressed: () async {
Navigator.of(context).pop(true)
},
solution for my problem was that used redux store had an object and updating object property or a list does not count as variable change to redux so the widget wouldn't rebuild.
I have a stateless page with a provider. I use Google AdMob to display ads (in_app_purchase package).
On the page I have a start button. onPressed event has below code to go to the next page:
Navigator.push(
context,
MaterialPageRoute(builder: (context) => const NextScreen()),
);
To implement rewarded ad I have added code to onPressed event to detect whether the ads are required, and if so, instead of routing to the next page, a dialog box is displayed asking user to watch an ad. If the user accepts, this starts the ad process in the provider.
This all works great, but my problem is that when the reward is granted in the provider event, I do not know how to trigger the move to the next page.
The ad code in the provider class looks like this:
await _rewardedAd!.show(
onUserEarnedReward: (AdWithoutView ad, RewardItem reward) {
//here I can notify listeners to change the UI look, but not to trigger a page move
}
);
At that point I can notify listeners to change UI look, but not to trigger a page move. It would be useful to have some sort of a "function widget" that does nothing but listen for a value change and execute some code, but could not find such a thing.
At a time of desperation I even tried putting and invisible widget on the page to do that, but that triggers an error when I call navigator route from a widget that is being rebuilt.
It would be nice if button onPressed even could listen for provider change, but I don't know if this is possible.
What is the proper way to do this? I suspect this is a very common scenario. Is this even possible to achieve with a stateless widget and provider pattern? Must I switch to a stateful widget?
Ended up implementing this solution which works but seems a bit hacky and not sure if it will cause some problems with the widget tree.
Will accept a better solution.
In a nutshell, provider has a special trigger variable that now a StateFulWidget screen listens for in didChangeDependencies event.
In the provider I have this code to display the ad and listen for rewarded event:
await _rewardedAd!.setImmersiveMode(true);
await _rewardedAd!.show(
onUserEarnedReward: (AdWithoutView ad, RewardItem reward) {
//set the trigger and notify listeners
_startWorkoutTrigger = true;
notifyListeners();
});
I converted the page to a StatefulWidget and added this code to didChangeDependencies event:
#override
Future<void> didChangeDependencies() async {
super.didChangeDependencies();
if (Provider.of<Settings>(context, listen: false)
.getStartTrigger()) {
Provider.of<Settings>(context, listen: false).cancelStartTrigger();
Future.delayed(
Duration.zero,
() => Navigator.push(
context,
MaterialPageRoute(builder: (context) => const NextScreen()),
));
}
}
I am building a flutter application in which I have 2 screens.I have API calls on both screens.When I navigate on 2nd screen and return back to 1st screen then build function of 1st Screen runs as expected and API is called again(In future of FutureBuilder) which I don't want. I only want to update or fetch the API when I slide from top to bottom on screen.But due to FutureBuilder in my !st screen's build function it is fetching the data again and again everytime.
Any suggestion with e.g. code will be helpful.Thank you!
you can use StatefullWidget and have a property in State class like Future<String>
and assing it in initState.
if you back from second screen your build function called but you have previous data.
...
Future<String> future;
initState(){
future = apiCall();
}
Widget build(){
return FutureBuilder(
future: future,
);
}
I am struggling with the following problem:
I built a list of widgets using StreamBuilder (and made it searchable). The widgets are Cards and inside them the user can make his selection and then push a button.
Everything is (was) working just fine.
Then I wanted to add a little animation and make the Icon associated to the button an animated one.
Now it is a mess, the StreamBuilder is in an infinite loop and I have also some problem on my list. If I comment out the animated icon and put in again the previous Icon ...everything starts to work fine again.
...
child: FloatingActionButton(
onPressed: (){
addFood();
mealListState.getAcontroller(id).forward();
},
child:
// MyAddIcon(id), //--> my animated Icon. It does not work
Icon(Icons.add), //--> it works
....
I read that the problem is that adding States management (Unnecessary Widget Rebuilds While Using Selector (Provider) inside StreamBuilder) inside the stream mess things up and that you have to make the widget building the stream Stateful and set up the stream in the initState.
I tried to follow this way but I need the context to build my card list, so I could follow the above hint just to read the data from db (firestore) and ...it is not enough
Could someone point me in the right direction or I have to leave the idea and move on?
Thanks
If you need the context, you can try to listen to the the stream in the didChangeDependencies method of your State class.
Use the Streamsubscription returned by stream.listen to cancel your subscription like so to avoid subsribing twice or even more times:
#override
didChangeDependencies() {
final stream = Provider.of<MyStream>(context); // context available here.
if (this.streamsubscription != null) {
this.streamsubscription.cancel();
}
this.streamsubscription = stream.listen((value) {
// your callback code here
});
super.didChangeDependencies(); // important
}
I'm new to the flutter, and I have a question. When the user creates the account, I would like to redirect him to the configuration page with a certain Widget on the page already open. It's possible?
Navigator.push(context, MaterialPageRoute(builder: (context){
return SettingsWidget();
}));
I'm using this code to direct the Configuration page, but the Widget that has the person inside would have to click on the button, but I wanted it to be already open.
I think you want to show a dialog as soon as the page opens! If that is your requirement you can do this:
#override
void initState() {
super.initState();
SchedulerBinding.instance
.addPostFrameCallback((_) => showDialog(context));
}