I'm trying to avoid the default behaviour of Flutter, instead of closing app when the back button (of the smartophone of course) is pressed I will send the app in background, so when I try to reopen the app it returns on the last screen.
I also tried a solution that I have found here, but didn't work.
This is the code:
return WillPopScope(
onWillPop: () async =>
await SystemChannels.platform.invokeMethod('SystemNavigator.pop'),
child: Scaffold(
It also closes the app and don't send it in background.
The screen that contains the code showed above is the last route.
You can use MethodChannel for this, invoke a method from Flutter that will trigger a method in Java.
// in flutter use something like this
methodChannel.invokeMethod("homeButton");
And in Java, you can create a method like:
public void homeButton() {
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
More info on how to write platform specific code.
Flutter plugin for sending mobile applications to the background. Supports iOS and Android.
move_to_background: ^1.0.2
WillPopScope(
child: MaterialApp(...),
onWillPop: () async {
MoveToBackground.moveTaskToBack();
return false;
},
);
Related
Help! my will pop not even printing. Here is the code:
Future<bool> _willPopCallback() async {
print('Hi');
return false;
}
WillPopScope(
onWillPop: _willPopCallback,
child: Scaffold()
It was not working i tried my best so at the end i started using a package called back_button_interceptor. Its easy to use you can find here:
https://pub.dev/packages/back_button_interceptor/example
I have a flutter app that connects via bluetooth with a device by pressing on the device name from the list of paired devices. This is the coding :
final BluetoothDevice server;
DataCollectionPage({required this.server});
...............................................................................
child: ListView(
children: devices
.map((_device)=> BluetoothDeviceListEntry(
device: _device,
enabled: true,
onTap: (){
if (kDebugMode) {
print("item");
}
_startDataCollection(context, _device);
},
................................................................................
void _startDataCollection(BuildContext context, BluetoothDevice server){
Navigator.of(context).push(MaterialPageRoute(builder: (context){
return DataCollectionPage(server: server);
}));
}
Then once I navigate to the "DataCollectionPage" page, I perform some actions and data collection methods and at the end I will be in other page named "DataCollectionTimer". In this page a timer will be displayed on the screen for few seconds then at the end of this timer a Dialog will show to give some message and then finally Once I press the button close on this dialog, I want to go back to DataCollectionPage. So If I try to use
MaterialPageRoute( builder: (context) => DataCollectionPage(), ),
It will give an error because parameter 'server' is required which I obtained from the list of paired devices that was in a different class.
Is there a way to go back to DataCollectionPage from the current one without going all the way back to the page where the list of paired devices is there.
Thank you in advance
You need to make the server field optional and then use popUntil
final BluetoothDevice? server;
DataCollectionPage({this.server});
// I already tried this but it wont work
return WillPopScope(
onWillPop: () { Navigator.pop(context);
},
child: Scaffold(),
error:Error: A non-null value must be returned since the return type 'Future' doesn't allow null.
'Future' is from 'dart:async'.
onWillPop: () { Navigator.pop(context);
If there is a screen in the stack then tapping the android back bottom will automatically go to the previous screen. this is the android default behavior. you don't have to wrap with WillPopScope.
If you want to show some dialog or do something by tapping the back button then wrap with WillPopScope.
onWillpop is an async function, it requires a function with a return type Future<bool>.
If you want to disable the default behavior of the android back button then you can use this.
onWillPop: () async {
// do something here
return false;
},
Otherwise,
onWillPop: () async {
// do something here
return true;
},
Returning true will not disable the default behavior of the android back button.
I've been building an app that has a back arrow '<-' and cross 'X' in the app bar. Programmatically, I have included various commands, including Navigator.pop(context) and to clear global data stored with a GetX data controller, like so:
onPressed: () {
try {
/// Clear data, so the app is ready to use again
c.updateValue('');
/// Close Screen
Navigator.pop(context);
} catch (e) {
print(
'Error when closing the database input window.');
}
},
In this instance, clearing the value means simply replacing whatever string is stored with an empty string.
Now, this works perfectly when either the back arrow or cross in the app bar are pressed. However, I've noticed on a physical device that when I make use of the phone's back arrow/button, which is outside of the app, whilst it moves the screen, it does not clear any of the data, as per the first statement in my onPressed function above.
My question is, how do I get the same commands to take place when the user makes use of the phone's back button, compared to the app's programmed back button?
Thank you!
Wrap your Scaffold with WillPopScope and execute the same command on the onWillPop like this:
return WillPopScope(
onWillPop: () async{
try {
/// Clear data, so the app is ready to use again
c.updateValue('');
return true; // true allows navigating back
} catch (e) {
print(
'Error when closing the database input window.');
return false; // false prevents navigating back
}
},
child: Scaffold(....),
);
Is there any method similar to this.finish() in android to finish current flutter activity.
Do you mean close current screen and come back to previous screen?
If that, Navigator.pop(context) should do the work. However, if you are at the entry screen (the first screen of the app and this screen has no parent screen/previous screen), Navigator.pop(context) will return you to a black screen. In this case, we have to use SystemNavigator.pop().
But don't use SystemNavigator.pop() for iOS, Apple says that the application should not exit itself :)
Below code will work on Android for both cases
if (Navigator.canPop(context)) {
Navigator.pop(context);
} else {
SystemNavigator.pop();
}
use Navigator.pushReplacement(BuildContext context, Route<T> newRoute) to open a new route which replace the current route of the navigator
use thie code
Navigator.pushReplacement(context,
MaterialPageRoute(builder: (context) {
return AddDemoUnitActivity();
}));