How can I change IOS and Android settings in Flutter? - flutter

I'm working on a drawing app that uses Apple Pad and Stylus.
In order to use stylus smoothly in this app, it must disable scribble option in the stylus setting.
If so, how do I access the settings in the IOS or Android on the setting and change the settings options?
And can I check what the current settings value are before I access setting? For example, can I check if the scribble in stylus setting is enabled?

Check out this package:
https://pub.dev/packages/app_settings/example
import 'dart:async';
import 'package:app_settings/app_settings.dart';
import 'package:flutter/material.dart';
/// Main method to return runApp.
void main() => runApp(MyApp());
/// This is the main app stateful widget.
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
/// This is the app state.
class _MyAppState extends State<MyApp> {
#override
void initState() {
/// Call out to intialize platform state.
initPlatformState();
super.initState();
}
/// Initialize platform state.
Future<void> initPlatformState() async {
// If the widget was removed from the tree while the asynchronous platform
// message was in flight, we want to discard the reply rather than calling
// setState to update our non-existent appearance.
if (!mounted) return;
}
/// Widget build method to return MaterailApp.
#override
Widget build(BuildContext context) {
var actionItems = getListOfActionButtons();
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('App Settings Example App'),
),
body: GridView.count(
crossAxisCount: 2,
childAspectRatio: 2,
children: List.generate(actionItems.length, (index) {
return Center(
child: ButtonTheme(
colorScheme: ColorScheme.dark(),
minWidth: 150.0,
child: actionItems[index],
));
}))));
}
List<Widget> getListOfActionButtons() {
var actionItems = <Widget>[];
actionItems.addAll([
ElevatedButton(
child: Text("WIFI"),
onPressed: () {
AppSettings.openWIFISettings();
},
),
ElevatedButton(
child: Text("Location"),
onPressed: () {
AppSettings.openLocationSettings();
},
),
ElevatedButton(
child: Text("Security"),
onPressed: () {
AppSettings.openSecuritySettings();
},
),
ElevatedButton(
child: Text("Lock & Password"),
onPressed: () {
AppSettings.openLockAndPasswordSettings();
},
),
ElevatedButton(
child: Text("App Settings"),
onPressed: () {
AppSettings.openAppSettings();
},
),
ElevatedButton(
child: Text("Bluetooth"),
onPressed: () {
AppSettings.openBluetoothSettings();
},
),
ElevatedButton(
child: Text("Data Roaming"),
onPressed: () {
AppSettings.openDataRoamingSettings();
},
),
ElevatedButton(
child: Text("Date"),
onPressed: () {
AppSettings.openDateSettings();
},
),
ElevatedButton(
child: Text("Display"),
onPressed: () {
AppSettings.openDisplaySettings();
},
),
ElevatedButton(
child: Text("Notification"),
onPressed: () {
AppSettings.openNotificationSettings();
},
),
ElevatedButton(
child: Text("Sound"),
onPressed: () {
AppSettings.openSoundSettings();
},
),
ElevatedButton(
child: Text("Internal Storage"),
onPressed: () {
AppSettings.openInternalStorageSettings();
},
),
ElevatedButton(
child: Text("Battery optimization"),
onPressed: () {
AppSettings.openBatteryOptimizationSettings();
},
),
ElevatedButton(
child: Text("NFC"),
onPressed: () {
AppSettings.openNFCSettings();
},
),
ElevatedButton(
child: Text("VPN"),
onPressed: () {
AppSettings.openVPNSettings(
asAnotherTask: true,
);
},
),
ElevatedButton(
child: Text("Device Settings"),
onPressed: () {
AppSettings.openDeviceSettings(
asAnotherTask: true,
);
},
),
ElevatedButton(
child: Text("Accessibility"),
onPressed: () {
AppSettings.openAccessibilitySettings(
asAnotherTask: true,
);
},
),
ElevatedButton(
child: Text("Developer"),
onPressed: () {
AppSettings.openDevelopmentSettings(
asAnotherTask: true,
);
},
),
ElevatedButton(
child: Text("Hotspot"),
onPressed: () {
AppSettings.openHotspotSettings(
asAnotherTask: true,
);
},
),
]);
return actionItems;
}
/// Dispose method to close out and cleanup objects.
#override
void dispose() {
super.dispose();
}
}

Related

How to Change the label of an existing chip in flutter?

I'm using chips in my code when I tap on chip a counter is displayed, I want to update the chip label with when count is added.
Widget returnWidget() {
return InkWell(
child: Chip(
label: Text(temp!),
),
onTap: () {
print(temp);
_showMyDialog();
},
);
}
This is the widget I'm using to add multiple chips.
Future<void> _showMyDialog() async {
return showDialog<void>(
context: context,
barrierDismissible: false, // user must tap button!
builder: (BuildContext context) {
return AlertDialog(
scrollable: false,
title: const Text('Add Count'),
content: Container(
height: 50,
width: 50,
alignment: Alignment.center,
padding: const EdgeInsets.all(3),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: const [
AddCount(),
],
),
),
actions: <Widget>[
TextButton(
child: const Text('Cancel'),
onPressed: () {
{
setState(() {
_itemCount = 0;
});
}
Navigator.of(context).pop();
},
),
TextButton(
child: const Text('Add'),
onPressed: () {
if(count==0) {
setState((){
temp = temp! + _itemCount.toString();
Text(temp!);
count++;
});
}
print(text);
},
),
],
);
},
);
}
This is the code block which is showing a counter dialog. I want to update chip label on add.
Hello here I have a solution, I did not see more details about your code but here I did a working solution, the variable you want to update should be located inside the classed where is used but you can also use state management or InheritedWidget to update variables globally:
class App extends StatelessWidget {
const App({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Example(),
);
}
}
class Example extends StatefulWidget {
const Example({Key? key}) : super(key: key);
#override
State<Example> createState() => _ExampleState();
}
class _ExampleState extends State<Example> {
int temp = 0; // declare the variable inside the class you want to update it
Future<void> _showMyDialog() async {
return showDialog<void>(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return AlertDialog(
scrollable: false,
title: const Text('Add Count'),
content: Container(
height: 50,
width: 50,
alignment: Alignment.center,
padding: const EdgeInsets.all(3),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: const [
// AddCount(),
],
),
),
actions: <Widget>[
TextButton(
child: const Text('Cancel'),
onPressed: () {
Navigator.of(context).pop();
},
),
TextButton(
child: const Text('Add'),
onPressed: () {
setState((){
temp = temp += 1; // update the chip UI
});
Navigator.of(context).pop();
},
),
],
);
},
);
}
Widget returnWidget() {
return InkWell(
child: Chip(
label: Text("count $temp"), // <-- new change
),
onTap: () {
print(temp);
_showMyDialog();
},
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.red,
body: Center(
child: Container(
margin: const EdgeInsets.all(32),
child: returnWidget(),
),
),
);
}
}

Flutter: disable the user input while data is uploading

To prevent errors I want to disable the user input while my flutter app is uploading some data to firebase. I already tried IgnorePointer and AbsorbPointer with a boolean which gets updated via setState when the user presses "upload data". But the user can still enter something on the screen.
Is there a way to disable the user input while the data is uploading? After the upload is finished the user will be navigated automatically in the main menu.
Here are some parts of the code:
class AddJob extends StatefulWidget {
AddJob({Key? key}) : super(key: key);
#override
_AddJobState createState() => _AddJobState();
}
class _AddJobState extends State<AddJob> {
bool ignoring = false;
Future<void> addJob() async {
return showDialog<void>(
barrierDismissible: true,
context: context,
builder: (context) {
return AlertDialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(15))),
title: Text('Privat oder Öffentlich?'),
content: Text(
'xy'),
actions: <Widget>[
TextButton(
onPressed: () {
Navigator.of(context).pop();
},
child: Text('back'),
),
TextButton(
onPressed: () async {
setState(() {
ignoring = true;
});
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
duration: Duration(seconds: 4),
content: Row(
children: <Widget>[
new CircularProgressIndicator(),
new Text(" Hochladen...")
],
),
));
... uploading
}
}
#override
Widget build(BuildContext context) {
final _picker = ImagePicker();
return IgnorePointer(
ignoring: ignoring,
child: GestureDetector(
onTap: () {
FocusScopeNode currentFocus = FocusScope.of(context);
if (!currentFocus.hasPrimaryFocus) {
currentFocus.unfocus();
}
},
child: Scaffold(
appBar: AppBar(
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.vertical(bottom: Radius.circular(15))),
backgroundColor: blueLayerOne,
title: Text('create'),
actions: [
IconButton(
icon: Icon(Icons.info_outline_rounded),
onPressed: () {
showInfos();
}),
],
),
body: SingleChildScrollView(
...normal screen widgets
}
}

showMaterialBanner doesnt hide on change route Looking up a deactivated widget's ancestor is unsafe

Cant close Material banner after closing the page that call it.
I two screen LoginScreen RecoverScreen, from LoginScreen the user open RecoverScreen to send recover password's email, if sent was done sucesfully i show MaterialBanner and pop RecoverScreen, in LoginScreen when i clic "Close" button in my Materialbanner i got the following error:
════════ Exception caught by gesture ═══════════════════════════════════════════
The following assertion was thrown while handling a gesture:
Looking up a deactivated widget's ancestor is unsafe.
At this point the state of the widget's element tree is no longer stable.
To safely refer to a widget's ancestor in its dispose() method, save a reference to the ancestor by calling dependOnInheritedWidgetOfExactType() in the widget's didChangeDependencies() method.
When the exception was thrown, this was the stack
dart-sdk/lib/internal/js_dev_runtime/private/ddc_runtime/errors.dart 251:49 throw
packages/flutter/src/widgets/framework.dart 4032:9
packages/flutter/src/widgets/framework.dart 4045:14 [_debugCheckStateIsActiveForAncestorLookup]
ScaffoldMessenger.of(context).showMaterialBanner(
MaterialBanner(
padding: EdgeInsets.all(20),
content: Text('Recover password email was sended.'),
leading: Icon(Icons.info),
backgroundColor: Colors.green,
actions: <Widget>[
TextButton(
child: Text(
'Close',
style: TextStyle(color: Colors.white),
),
onPressed: () {
ScaffoldMessenger.of(context)
.hideCurrentMaterialBanner();
},
),
],
),
);
Try this full example:
import 'package:flutter/material.dart';
void main() {
runApp(
MaterialApp(
home: LoginScreen(),
),
);
}
class LoginScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: ElevatedButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => RecoverScreen(),
),
);
},
child: const Text('Recover password'),
)),
);
}
}
class RecoverScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: ElevatedButton(
onPressed: () {
Navigator.of(context).pop();
ScaffoldMessenger.of(context).showMaterialBanner(
MaterialBanner(
padding: const EdgeInsets.all(20),
content: const Text('Recover password email was sended.'),
leading: const Icon(Icons.info),
backgroundColor: Colors.green,
actions: <Widget>[
TextButton(
child: const Text(
'Cerrar',
style: TextStyle(color: Colors.white),
),
onPressed: () {
ScaffoldMessenger.of(context).hideCurrentMaterialBanner();
},
),
],
),
);
},
child: const Text('Send Password'),
)),
);
}
}
I know that in this case i can use a snackbar, but its only a example and i want to know how to deal with this problem.
Try wrapping the TextButton with Builder and pass the context of it instead of already closed RecoverScreen's.
actions: <Widget>[
Builder(
builder: (context) => TextButton(
child: const Text(
'Cerrar',
style: TextStyle(color: Colors.white),
),
onPressed: () {
ScaffoldMessenger.of(context).hideCurrentMaterialBanner();
},
),
),
],
Before route change call ScaffoldMessenger.of(context).clearMaterialBanners();
Like, here wrap Scaffold widget by WillPopScope,
Sample Code:
WillPopScope(
onWillPop: (){
ScaffoldMessenger.of(context).clearMaterialBanners();
Navigator.pop(context);
return;
},
child: ........
}
Here is how I solved it in Flutter 3.0.5
#override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () {
var c = Completer<bool>();
try {
ScaffoldMessenger.of(context).clearMaterialBanners();
ScaffoldMessenger.of(context).clearSnackBars();
c.complete(true);
} catch (e) {
c.completeError(e);
}
return c.future;
},
child: Scaffold(...),
);
}

Change the content of dialog in Flutter

After I clicked the button in the dialog, the content would change from a list of buttons into a form with textfields. However, I am frustrated in codes to achieve it.
You just need a stateful dialog and a bool state. Here is an example:
class MyDialog extends StatefulWidget {
const MyDialog({Key? key}) : super(key: key);
#override
MyDialogState createState() => MyDialogState();
}
class MyDialogState extends State<MyDialog> {
/// When this value is false, it shows list of buttons
/// When this value is true, it shows list of textfields
bool isForm = false;
#override
Widget build(BuildContext context) {
return AlertDialog(
title: const Text('AlertDialog Title'),
// Here, we conditionally change content
content: isForm
? Column(
children: [
TextFormField(),
TextFormField(),
TextFormField(),
TextFormField(),
],
)
: Column(
children: [
TextButton(onPressed: () {}, child: Text('Button')),
TextButton(onPressed: () {}, child: Text('Button')),
TextButton(onPressed: () {}, child: Text('Button')),
TextButton(onPressed: () {}, child: Text('Button')),
],
),
actions: [
TextButton(
// Here isForm is switched to change the content
onPressed: () => setState(() => isForm = !isForm),
child: const Text('Switch'),
),
TextButton(
onPressed: () => Navigator.pop(context),
child: const Text('Cancel'),
),
TextButton(
onPressed: () => Navigator.pop(context, true),
child: const Text('OK'),
),
],
);
}
}
Use it with showDialog(context: context, builder: (context) => MyDialog())

Flutter save page content after routing

i have a favorite icon that exist on page (A) that changes it's color whenever i click, the problem is when i move to another page and go back to page (A) icon goes to regular color, it doesn't save the changes on page , is there a way to keep the changes even after moving from page to page ?
Thanks.
If you push and pop back, then you can find the saved state from the route. How-ever if you pop back, current page state will be removed from stack. To handle this, you need to use state-management property. You can use StateProvider in this case, or the thing that suit for your project.
Demo:
class PageA extends StatefulWidget {
PageA({Key? key}) : super(key: key);
#override
_PageAState createState() => _PageAState();
}
class _PageAState extends State<PageA> {
Color color = Colors.deepOrange;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("PAge A"),
),
body: Center(
child: Column(
children: [
Container(
width: 400,
height: 400,
color: color,
alignment: Alignment.center,
child: Text("init Color:deepOrange "),
),
ElevatedButton(
onPressed: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => PageB(),
));
},
child: Text("Move to B"),
)
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
setState(() {
color = Colors.deepPurple;
});
},
),
);
}
}
class PageB extends StatefulWidget {
const PageB({Key? key}) : super(key: key);
#override
_PageBState createState() => _PageBState();
}
class _PageBState extends State<PageB> {
Color color = Colors.greenAccent;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("PAge B"),
),
body: Center(
child: Column(
children: [
Container(
width: 400,
height: 400,
color: color,
alignment: Alignment.center,
child: Text("init Color:greenAccent "),
),
ElevatedButton(
onPressed: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => PageC(),
),
);
},
child: Text("Move to C"),
),
ElevatedButton(
onPressed: () {
Navigator.of(context).pop();
},
child: Text("Move Back to A, you can find last saved state"),
)
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
setState(() {
color = Colors.black;
});
},
),
);
}
}
class PageC extends StatefulWidget {
PageC({Key? key}) : super(key: key);
#override
_PageCState createState() => _PageCState();
}
class _PageCState extends State<PageC> {
Color color = Colors.amberAccent;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("PAge C"),
),
body: Center(
child: Column(
children: [
Container(
width: 400,
height: 400,
color: color,
child: Center(child: Text("init Color:amberAccent ")),
),
ElevatedButton(
onPressed: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => PageB(),
),
);
},
child: Text("Push to B, will assing new state on route"),
),
ElevatedButton(
onPressed: () {
Navigator.of(context).pop();
},
child: Text(
"pop to B\n if you pop then current state of Page B will be visible"),
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
setState(() {
color = Colors.pink;
});
},
),
);
}
}