I am trying to make create data with localhost mysql in separate page with home and after that go back to home that contain list of data with Navigator.pop(context). the problem is when i've done add data, the page go back to home and new data not appear in list, but after i refresh debug the data appear. what should i do to get new data in list after create data?
main.dart
import "package:flutter/material.dart";
import "dart:async";
import 'package:http/http.dart' as http;
import 'dart:convert';
import "Detail.dart";
import "CreatePegawai.dart";
void main() {
runApp(new MaterialApp(
title: "CRUD PEGAWAI",
home: new Home(),
));
}
class Home extends StatefulWidget {
#override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
Future<List> readData() async {
final response = await http.get("http://10.0.2.2/modelpegawai/read.php");
return json.decode(response.body);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: new AppBar(
title: new Text("List Data Pegawai"),
leading: new Icon(Icons.home),
backgroundColor: Colors.blue[300],
),
floatingActionButton: new FloatingActionButton(
child: new Icon(Icons.add),
onPressed: ()=>Navigator.of(context).push(
new MaterialPageRoute(
builder: (BuildContext context)=> new CreatePegawai(),
)
),
),
body: new FutureBuilder<List>(
future: readData(),
builder: (context, snapshot) {
if (snapshot.hasError) {
print(snapshot.error);
}
return snapshot.hasData
? new ItemList(list: snapshot.data)
: new Center(
child: new CircularProgressIndicator(),
);
},
),
backgroundColor: Colors.yellow[200],
);
}
}
class ItemList extends StatelessWidget {
final List list;
ItemList({this.list});
#override
Widget build(BuildContext context) {
return new ListView.builder(
itemCount: list == null ? 0 : list.length,
itemBuilder: (context, i) {
return new Container(
padding: const EdgeInsets.all(10.0),
child: new GestureDetector(
onTap: ()=>Navigator.of(context).push(
new MaterialPageRoute(
builder: (BuildContext context)=>new Detail(list:list, index:i)
)
),
child: new Card(
child: new ListTile(
title: new Text(
list[i]['nama'],
style: new TextStyle(fontSize: 20.0),
),
leading: new Icon(Icons.assignment_ind),
subtitle: new Text(
"Asal : ${list[i]['asalKota']}",
style: new TextStyle(fontSize: 16.0),
),
)),
));
});
}
}
createPegawai.dart
import "package:flutter/material.dart";
import 'package:http/http.dart' as http;
import 'package:intl/intl.dart';
import 'package:datetime_picker_formfield/datetime_picker_formfield.dart';
class CreatePegawai extends StatefulWidget {
#override
_CreatePegawaiState createState() => _CreatePegawaiState();
}
class _CreatePegawaiState extends State<CreatePegawai> {
DateTime date2;
TextEditingController controllerNIP = new TextEditingController();
TextEditingController controllerNama = new TextEditingController();
TextEditingController controllerTgl = new TextEditingController();
TextEditingController controllerAsalKota = new TextEditingController();
TextEditingController controllerDept = new TextEditingController();
TextEditingController controllerEmail = new TextEditingController();
TextEditingController controllerPass = new TextEditingController();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: new AppBar(
title: new Text("Tambah Pegawai"),
),
body: Padding(
padding: const EdgeInsets.all(20.0),
child: ListView(
children: <Widget>[
new Column(
children: <Widget>[
new Text(
"Form Tambah Pegawai",
style: new TextStyle(
fontSize: 20.0,
),
),
nip(),
nama(),
tgl(),
asalKota(),
kodeDept(),
email(),
pass(),
new Padding(
padding: const EdgeInsets.all(10.0),
),
tombol(),
],
),
],
),
));
}
Widget nip() {
return TextField(
controller: controllerNIP,
decoration: new InputDecoration(
hintText: "NIP 3 Angka",
labelText: "NIP",
),
);
}
Widget nama() {
return TextField(
controller: controllerNama,
decoration: new InputDecoration(
hintText: "Masukan Nama",
labelText: "Nama",
),
);
}
Widget tgl() {
return new Container(
child: DateTimePickerFormField(
controller: controllerTgl,
inputType: InputType.date,
format: DateFormat("dd-MM-yyyy"),
initialDate: DateTime(2019, 1, 1),
editable: false,
decoration:
InputDecoration(labelText: 'Date', hasFloatingPlaceholder: false),
onChanged: (dt) {
setState(() => date2 = dt);
},
),
);
}
Widget asalKota() {
return TextField(
controller: controllerAsalKota,
decoration: new InputDecoration(
hintText: "Masukan Kota Asal",
labelText: "Kota Asal",
),
);
}
Widget kodeDept() {
return TextField(
controller: controllerDept,
decoration: new InputDecoration(
hintText: "Dept",
labelText: "Departmen",
),
);
}
Widget email() {
return TextFormField(
controller: controllerEmail,
keyboardType: TextInputType.emailAddress, //KEYBOARD TYPENYA ADALAH EMAIL ADDRESS AGAR SYMBOL # DILETAKKAN DIDEPAN KETIKA KEYBOARD DI TAMPILKAN
decoration: InputDecoration(
labelText: "Email",
hintText: "email#provide.com",
),
);
}
Widget pass() {
return TextFormField(
controller: controllerPass,
obscureText: true, //membuat titik2 pada inputan/tidak keliatan text
decoration: InputDecoration(
labelText: "Password",
hintText: "Masukan password",
),
);
}
Widget tombol() {
return RaisedButton(
child: new Text("Tambah"),
color: Colors.blueAccent,
onPressed: () {
create();
Navigator.pop(context);
},
);
}
void create(){
var url = "http://10.0.2.2/modelpegawai/create.php";
var formatter = new DateFormat('yyyy-MM-dd');
String formatted = formatter.format(date2);
http.post(url, body:{
"nip": controllerNIP.text,
"nama": controllerNama.text,
"tgl": formatted,
"asalKota": controllerAsalKota.text,
"dept": controllerDept.text,
"email": controllerEmail.text,
"pass": controllerPass.text,
});
}
}
A simple trick to achieve your requirement is pass some data when poping from second screen.
// This is where you push to second screen from first screen
// Make sure you a method to get data from server
// And call that function when popped
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => SecondScreen())).then(
(data){
if(data!=null && data){
getDataFromServer();
});
// This is where you are poping from second screen.
// Pass a bool whether you want refresh first screen or not.
Navigator.of(context).pop(true)
I Finally can solve this problem. the new data can show with add async and await in the createData() function like this
void create() async {
var url = "http://10.0.2.2/modelpegawai/create.php";
var formatter = new DateFormat('yyyy-MM-dd');
String formatted = formatter.format(date2);
await http.post(url, body:{
"nip": controllerNIP.text,
"nama": controllerNama.text,
"tgl": formatted,
"asalKota": controllerAsalKota.text,
"dept": controllerDept.text,
"email": controllerEmail.text,
"pass": controllerPass.text,
});
}
Related
Recently implemented a tagForm widget at "+" button press, I want to delete those widgets now at "delete" button press, but right now, even when I press the "delete" button, nothing happens.
How can I solve this?
Any help appreciated!
code:
import 'package:flutter/material.dart';
import '../database/firestoreHandler.dart';
import '../models/todo2.dart';
import '../widgets/dialogs.dart';
class TodoEdit extends StatefulWidget {
String? doctitle;
String? doctdescription;
String? docimage;
String? docid;
List? doctags;
TodoEdit({Key? key, this.doctitle, this.doctdescription, this.docimage, this.docid,this.doctags}) : super(key: key);
#override
_TodoEditState createState() => _TodoEditState();
}
class _TodoEditState extends State<TodoEdit> {
final _formKey = GlobalKey<FormState>();
final tcontroller = TextEditingController();
final dcontroller = TextEditingController();
final icontroller = TextEditingController();
var textEditingControllers = <TextEditingController>[];
//-----------------the list where the form is stored----------
var textformFields = <Widget>[];
void _addformWidget(controller) {
setState(() {
textformFields.add(tagForm(controller));
});
}
//------------------------------------------------------------------------
Widget tagForm(controller){
return TextFormField(
controller: controller,
style: TextStyle(color: Colors.white),
decoration: InputDecoration(
labelText: "Tag",
labelStyle: TextStyle(color: Colors.white60),
fillColor: Colors.black,
filled: true,
suffixIcon: IconButton(
icon:Icon(Icons.delete, color: Colors.white,),
//--------------------- doesn't work?-------------------
onPressed: (){
setState(() {
textformFields.remove(tagForm(controller));
});
},
--------------------------------------------------------------
)
),
);
}
//-----------------------------------------------------------
#override
void initState() {
super.initState();
tcontroller.text = widget.doctitle.toString();
dcontroller.text = widget.doctdescription.toString();
icontroller.text = widget.docimage.toString();
widget.doctags?.forEach((element) {
var textEditingController = new TextEditingController(text: element);
textEditingControllers.add(textEditingController);
//return textformFields.add(tagForm(textEditingController)
return _addformWidget(textEditingController);
//);
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.grey[900],
appBar: AppBar(
actions: [
IconButton(onPressed: (){
showDialog(
barrierDismissible: false,
context: context,
builder: (context) {
return AlertDialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
),
title: Text('Delete TODO'),
actions: [
TextButton(
child: Text('Cancel'),
onPressed: () {
Navigator.pop(context);
},
),
TextButton(
child: Text('Delete'),
onPressed: () {
deleteData(widget.docid.toString(), context);
setState(() {
showSnackBar(context, 'todo "${widget.doctitle}" successfully deleted!');
});
},
),
],
);
},
);
},
icon: Icon(Icons.delete))
],
backgroundColor: Colors.grey[900],
title: Text("${widget.doctitle}"),
),
body: Container(
child: SafeArea(
child: Form(
key: _formKey,
child: Column(
children: [
SizedBox(height: 10),
TextFormField(
controller: tcontroller,
style: TextStyle(color: Colors.white),
decoration: InputDecoration(
labelText: "Title",
labelStyle: TextStyle(color: Colors.white60),
fillColor: Colors.black,
filled: true,
),
),
SizedBox(height: 10),
TextFormField(
controller: dcontroller,
style: TextStyle(color: Colors.white),
decoration: InputDecoration(
labelText: "Description",
labelStyle: TextStyle(color: Colors.white60),
fillColor: Colors.black,
filled: true,
),
),
SizedBox(height: 10),
TextFormField(
controller: icontroller,
style: TextStyle(color: Colors.white),
decoration: InputDecoration(
labelText: "Image url",
labelStyle: TextStyle(color: Colors.white60),
fillColor: Colors.black,
filled: true,
),
),
SizedBox(height: 10),
Row(children: [
Text("Tags:", style:TextStyle(color: Colors.white)),
IconButton(onPressed: (){
var textEditingController = new TextEditingController(text: "tag");
textEditingControllers.add(textEditingController);
_addformWidget(textEditingController);
print(textformFields.length);
},
icon: Icon(Icons.add,color: Colors.white,),
)
],),
/*SingleChildScrollView(
child: new Column(
children: textformFields,
)
),*/
Expanded(
child: SizedBox(
height: 200.0,
child: ListView.builder(
itemCount: textformFields.length,
itemBuilder: (context,index) {
return textformFields[index];
}),
)
),
],
),
),
),
),
floatingActionButton: FloatingActionButton(
onPressed: (){
List<String> test = [];
textEditingControllers.forEach((element) {
test.add(element.text);
});
if(tcontroller == '' && dcontroller == '' && icontroller == ''){
print("not valid");
}else{
var todo = Todo2(
title: tcontroller.text,
description: dcontroller.text,
image: icontroller.text,
tags: test,
);
updateData(todo, widget.docid.toString(),context);
setState(() {
showSnackBar(context, 'todo ${widget.doctitle} successfully updated!');
});
}
},
child: Icon(Icons.update),
),
);
}
}
You can't remove anything from the list with objects from tagForm(controller), because these objects are newly created and therefore not the same as in the list (as long as the == operator is not overwritten)
If you still want to have the widgets in a list instead of just storing the controllers and without having to change much, you could remove the widgets like this:
onPressed: (){
setState(() {
controller.dispose();
textEditingControllers.remove(controller);
textformFields.removeWhere((w) => w.controller = controller));
});
},
and change the type of your List: var textformFields = <TextFormField>[]; and of the method TextFormField tagForm(controller).
In general, you can of course optimize the state management, but with this solution it should work for now.
Dont't store Widget, it is bad way. Insteads store there property, render by List then remove by index when you need.
ps: some code syntax can wrong, i write this on browser.
class _TodoEditState extends State<TodoEdit> {
...
var textformFields = <String>[];
...
void _addformWidget([String? initValue]) {
setState(() => textformFields.add(initValue ?? ""));
}
...
Widget tagForm(String value, void Function(String) onChange, void Function() onRemove){
var openEditor = () {
// Open dialog with text field to edit from [value] call onChange with
// new value
OpenDialog().then((newvalue) {
if(newvalue != null) onChange(newvalue);
}
};
var delete = () {
// Open confirm dialog then remove
OpenConfirmDialog("your message").then((continue) {
if(continue) onRemove();
});
};
return InkWell(
onTap: openEditor,
child: Text(value), // render your tag value
);
}
...
#override
void initState() {
...
textformFields = List.filled(widget.doctags ?? 0, ""); // or List.generate/map if you want replace by own value.
}
...
#override
Widget build(BuildContext context) {
...
ListView.builder(
itemCount: textformFields.length,
itemBuilder: (context,index) => tagForm(
textformFields[index],
(newvalue) => setState(() => textformFields[index] = newvalue),
() => setState(() => textformFields = textformFields..removeAt(index));,
),
),
...
);
}
I am really struggling to understand why my code isn't working. I'm trying to pass the text from two controllers into another widget with named parameters which writes to Firebase.
My "Test" button properly prints both _titleController.text and _descriptionController.text
TextButton(
onPressed: (){
print(_titleController.text); //works fine
print(_descriptionController.text); //works fine
},
child: Text('test')
),
However when I pass these into my next widget it's blank! If I hardcore strings into these parameters it works properly:
PushNewE3 (
changeTitle: _titleController.text, //does not work (empty)
changeDescription: _descriptionController.text, //does not work (empty)
)
Full code:
class CreateE3 extends StatefulWidget {
const CreateE3({Key? key}) : super(key: key);
#override
_CreateE3State createState() => _CreateE3State();
}
class _CreateE3State extends State<CreateE3> {
final _titleController = TextEditingController();
final _descriptionController = TextEditingController();
#override
void initState(){
super.initState();
_titleController.addListener(_printLatestValue);
}
#override
void dispose(){
_titleController.dispose();
super.dispose();
}
void _printLatestValue(){
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('So Frustrating'),
),
body: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: 800,
child: Column(
children: [
Text('Originator: **Add Current User**') ,
TextField(
maxLength: 40,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Change Title'
),
controller: _titleController,
onEditingComplete: (){
//_title = _titleController.text;
},
),
Padding(
padding: const EdgeInsets.fromLTRB(0,10,0,0),
child: TextFormField(
maxLines: 5,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Detailed Description'
),
controller: _descriptionController,
),
),
TextButton(
onPressed: (){
print(_titleController.text); //successfully prints
print(_descriptionController.text); //successfully prints
},
child: Text('test')
),
PushNewE3 (
changeTitle: _titleController.text, //DOES NOT WORK (empty)
changeDescription: _descriptionController.text, //DOES NOT WORK (empty)
)
],
),
),
],
),
);
}
}
class PushNewE3 extends StatelessWidget {
final String changeTitle;
final String changeDescription;
PushNewE3({
required this.changeTitle,
required this.changeDescription
});
#override
Widget build(BuildContext context) {
// Create a CollectionReference called users that references the firestore collection
CollectionReference notificationsE3 = FirebaseFirestore.instance.collection('notificationsE3');
Future<void> pushNewE3() {
// Call the notifications CollectionReference to add a new E3 notification
return notificationsE3
.add({
//'originator': FirebaseAuth.instance.currentUser,
'changeTitle': changeTitle,
'changeDescription': changeDescription,
})
.then((value) => print("E3 Created"))
.catchError((error) => print("Failed to create E3: $error"));
}
return TextButton(
onPressed: (){
print('start:');
print(changeTitle);
print(changeDescription);
print('-end');
},
child: Text(
"Create E3",
),
);
}
}
EDIT:
I still don't understand why the above code doesn't work. I refactored my code into a single widget and now it's working. If anyone can explain why I would still appreciate understanding as there is clearly a gap in my knowledge.
If anyone in the future runs into the same problem here is the refactored code:
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'main.dart';
var global = 'blank';
class CreateE3 extends StatefulWidget {
const CreateE3({Key? key}) : super(key: key);
#override
_CreateE3State createState() => _CreateE3State();
}
class _CreateE3State extends State<CreateE3> {
final _titleController = TextEditingController();
final _descriptionController = TextEditingController();
#override
Widget build(BuildContext context) {
// Create a CollectionReference called users that references the firestore collection
CollectionReference notificationsE3 = FirebaseFirestore.instance.collection('notificationsE3');
Future<void> pushNewE3() {
// Call the notifications CollectionReference to add a new E3 notification
return notificationsE3
.add({
//'originator': FirebaseAuth.instance.currentUser,
'changeTitle': _titleController.text,
'changeDescription': _descriptionController.text,
})
.then((value) => print("E3 Created"))
.catchError((error) => print("Failed to create E3: $error"));
}
return Scaffold(
appBar: AppBar(
title: Text(_titleController.text),
),
body: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: 800,
child: Column(
children: [
Text('Originator: **Add Current User**') ,
TextField(
maxLength: 40,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Change Title'
),
controller: _titleController,
onChanged: (text){
setState(() {
});
},
),
Padding(
padding: const EdgeInsets.fromLTRB(0,10,0,0),
child: TextFormField(
maxLines: 5,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Detailed Description'
),
controller: _descriptionController,
),
),
TextButton(
onPressed: (){
pushNewE3();
},
child: Text('SAVE')
),
],
),
),
],
),
);
}
}
in the onPressed To pass a value and show it, you have to use setState(() { _myState = newValue; });
Something like this
TextButton(
onPressed: (){
print(_titleController.text);
print(_descriptionController.text);
setState(() { _myNewText = _titleController.text; });
},
child: Text('test')
),
I'm not sure what are you trying to do exactly but here's what I did:
1 - add a local variable _title
2 - add this code to the onPressed function:
setState(() {
_title= _titleController.text;
});
This is the whole code :
class CreateE3 extends StatefulWidget {
const CreateE3({Key? key}) : super(key: key);
#override
_CreateE3State createState() => _CreateE3State();
}
class _CreateE3State extends State<CreateE3> {
final _titleController = TextEditingController();
final _descriptionController = TextEditingController();
String _title = 'So Frustrating';
#override
void initState(){
super.initState();
}
#override
void dispose(){
_titleController.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(_title),
),
body: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: 400,
child: Column(
children: [
Text('Originator: **Add Current User**') ,
TextField(
maxLength: 40,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Change Title'
),
controller: _titleController,
onEditingComplete: (){
//_title = _titleController.text;
},
),
Padding(
padding: const EdgeInsets.fromLTRB(0,10,0,0),
child: TextFormField(
maxLines: 5,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Detailed Description'
),
controller: _descriptionController,
),
),
TextButton(
onPressed: (){
print(_titleController.text);
print(_descriptionController.text);
setState(() {
_title = _titleController.text;
});
},
child: Text('test')
),
],
),
),
],
),
);
}
}
.........................
so this is when you first start the app :
after changing the TextField and pressing the 'test button the title in the appbar change :
may i ask how to connect to an open hotspot - wireless- by using wifi_configuration package
cause i just found a method that allow to connect to encrypted wireless networks.
WifiConfiguration.connectToWifi("wirelessname","wirelesspassword","packagename");
inside WifiConfiguration class there is just one method that can be used for connecting.
is there any other library that can connect to an open hotspot or is there a way to do that by using wifi_configuration library ?
Apple mentioned that we need just two parameters to pass which is of course the ssid and the packagename
init(ssid: String)
Creates a new hotspot configuration, identified by an SSID, for an open Wi-Fi network.
i override the method connectToWifi to receive just one parameter but this didn't work.
thanks in advance
You can copy paste run full code below
You can use package https://pub.dev/packages/wifi_utils
You can call Wifi.connection and provide ssid and password
code snippet
import 'package:wifi/wifi.dart';
...
Future<Null> connection() async {
Wifi.connection(ssid, password).then((v) {
print(v);
});
}
working demo
full code
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:wifi/wifi.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Wifi',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: new MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
String _wifiName = 'click button to get wifi ssid.';
int level = 0;
String _ip = 'click button to get ip.';
List<WifiResult> ssidList = [];
String ssid = '', password = '';
#override
void initState() {
super.initState();
loadData();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Wifi'),
centerTitle: true,
),
body: SafeArea(
child: ListView.builder(
padding: EdgeInsets.all(8.0),
itemCount: ssidList.length + 1,
itemBuilder: (BuildContext context, int index) {
return itemSSID(index);
},
),
),
);
}
Widget itemSSID(index) {
if (index == 0) {
return Column(
children: [
Row(
children: <Widget>[
RaisedButton(
child: Text('ssid'),
onPressed: _getWifiName,
),
Offstage(
offstage: level == 0,
child: Image.asset(
level == 0 ? 'images/wifi1.png' : 'images/wifi$level.png',
width: 28,
height: 21),
),
Text(_wifiName),
],
),
Row(
children: <Widget>[
RaisedButton(
child: Text('ip'),
onPressed: _getIP,
),
Text(_ip),
],
),
TextField(
decoration: InputDecoration(
border: UnderlineInputBorder(),
filled: true,
icon: Icon(Icons.wifi),
hintText: 'Your wifi ssid',
labelText: 'ssid',
),
keyboardType: TextInputType.text,
onChanged: (value) {
ssid = value;
},
),
TextField(
decoration: InputDecoration(
border: UnderlineInputBorder(),
filled: true,
icon: Icon(Icons.lock_outline),
hintText: 'Your wifi password',
labelText: 'password',
),
keyboardType: TextInputType.text,
onChanged: (value) {
password = value;
},
),
RaisedButton(
child: Text('connection'),
onPressed: connection,
),
],
);
} else {
return Column(children: <Widget>[
ListTile(
leading: Image.asset('images/wifi${ssidList[index - 1].level}.png',
width: 28, height: 21),
title: Text(
ssidList[index - 1].ssid,
style: TextStyle(
color: Colors.black87,
fontSize: 16.0,
),
),
dense: true,
),
Divider(),
]);
}
}
void loadData() async {
Wifi.list('').then((list) {
setState(() {
ssidList = list;
});
});
}
Future<Null> _getWifiName() async {
int l = await Wifi.level;
String wifiName = await Wifi.ssid;
setState(() {
level = l;
_wifiName = wifiName;
});
}
Future<Null> _getIP() async {
String ip = await Wifi.ip;
setState(() {
_ip = ip;
});
}
Future<Null> connection() async {
Wifi.connection(ssid, password).then((v) {
print(v);
});
}
}
I have the following code that initially displays a blank page, but I'd like an rAlert dialog to display automatically. Once the user clicks 'Request' or 'Cancel', some text will be displayed on the screen.
But I can't get the code to run that displays the Alert. I had it working by showing a button and clicking the button, but i need the Alert to display automatically when the page is displayed. I tried putting it in the initState. I didn't get any errors, but it didn't work either.
Anyone know what I need to do? Thanks?
import 'package:flutter/material.dart';
import 'package:rflutter_alert/rflutter_alert.dart';
import 'dart:async';
import 'package:rostermeon/cwidgets/general_widgets.dart';
import 'package:rostermeon/rmo_constants.dart';
class ForgotPassword extends StatefulWidget {
static const String id = 'forgot_password_screen';
#override
_ForgotPasswordState createState() => _ForgotPasswordState();
}
class _ForgotPasswordState extends State<ForgotPassword> {
StreamController<bool> _events;
#override
initState() {
super.initState();
_events = new StreamController<bool>();
doRequest(context: context);
}
Future<bool> doSaveRequest({String pReason}) async {
await Future.delayed(const Duration(seconds: 3), () {});
return false;
}
Future<bool> doRequest({context}) {
String _reason = '';
GlobalKey<FormState> _formKey = GlobalKey<FormState>();
TextEditingController reasonController = TextEditingController();
TextStyle _style = TextStyle(fontFamily: 'Montserrat', fontSize: 18.0, fontWeight: FontWeight.normal);
InputDecoration _textFormFieldDecoration({String hintText, double padding}) => InputDecoration(
//contentPadding: EdgeInsets.fromLTRB(8.0, 8.0, 8.0, 8.0),
contentPadding: EdgeInsets.all(padding),
isDense: true,
hintText: hintText,
hintStyle: TextStyle(color: kHintText),
border: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(5)),
),
);
return Alert(
context: context,
title: 'Request New Password',
content: StreamBuilder<bool>(
initialData: false,
stream: _events.stream,
builder: (BuildContext context, AsyncSnapshot<bool> snapshot) {
print(" ${snapshot.data.toString()}");
return snapshot.data
? CircularProgressIndicator()
: Form(
key: _formKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
SizedBox(height: 20.0),
Text('Email', textAlign: TextAlign.left, style: _style),
SizedBox(height: 10.0),
TextFormField(
validator: (value) {
if (value.isEmpty) {
return "please enter email";
}
return null;
},
onSaved: (value) {
_reason = value;
},
decoration: _textFormFieldDecoration(
hintText: 'your email address',
padding: 8.0,
),
controller: reasonController,
),
SizedBox(height: 10.0),
],
),
);
}),
buttons: [
DialogButton(
child: Text('Request', style: TextStyle(color: Colors.white, fontSize: 20)),
color: kMainColor,
onPressed: () async {
if (_formKey.currentState.validate()) {
_formKey.currentState.save();
print(_reason);
_events.add(true);
var saved = await doSaveRequest(pReason: _reason);
if (saved) {
Navigator.pop(context, false);
} else {
_events.add(false);
}
Navigator.of(context).pop();
// Navigator.pop(context, false);
}
},
),
DialogButton(
child: Text('Cancel', style: TextStyle(color: Colors.white, fontSize: 20)),
color: kMainColor,
onPressed: () {
Navigator.pop(context, false);
},
),
],
).show();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: rmoAppBar(subText: 'Request New Password', hideBackButton: false),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[],
),
),
);
}
}
Dialogs/Alerts need the buildContext in order to work, You can't have the buildContext before build() method is called, that's why you can't just call it in initstate() before the build is called.
To make it work use addPostFrameCallback to make sure it delays until widget is built:
void initState() {
super.initState();
WidgetsBinding.instance
.addPostFrameCallback((_) => yourMethod(context));
}
https://www.didierboelens.com/2019/04/addpostframecallback/
Am i trying to get the second screen double value in first screen when i click the device back button but i can't get it.I don't know how to do it. I'm a beginner for flutter.Help me to solve it.
My task is first screen get two double value using text field and pass it to second screen.
second screen have text field to enter the operator and click device back button it will check the operator and make the equal operations like(addition,subtraction,multiplication and division) then the answer will be display in the first screen.
How can i get the second screen double variable(value) in first screen. How to pass a double value to another class
This is my code.
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
class User {
final double a, b,c;
User(
{
this.a,
this.b,
this.c,
}
);
}
void main() {
runApp(MaterialApp(
title: 'Navigation Basics',
home: App(),
));
}
class App extends StatelessWidget{
#override
Widget build(BuildContext context){
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
primaryColor: Color(0xFFFB415B),
fontFamily: "Ubuntu"
),
home: LoginPage(),
);
}
}
class LoginPage extends StatefulWidget{
final User value;
LoginPage ({Key key, this.value}) : super(key: key);
#override
_LoginPageState createState() => _LoginPageState();
}
class _LoginPageState extends State<LoginPage>{
double c1;
/*callback(double c2) {
print("$c2");
setState(() {
c1 = c2;
});
}*/
bool _isHidden = true;
var _acontroller= new TextEditingController();
var _bcontroller= new TextEditingController();
void _toggleVisibility(){
setState(() {
_isHidden = !_isHidden;
});
}
Future<bool> _onWillPop() {
return showDialog(
context: context,
builder: (context) => new AlertDialog(
title: new Text('Are you sure?'),
content: new Text('Do you want to exit an App'),
actions: <Widget>[
new FlatButton(
onPressed: () => Navigator.of(context).pop(false),
child: new Text('No'),
),
new FlatButton(
onPressed: () => Navigator.of(context).pop(true),
child: new Text('Yes'),
),
],
),
) ?? false;
}
#override
Widget build(BuildContext context){
return WillPopScope(
onWillPop:_onWillPop,
child: Scaffold(
appBar: AppBar(
title: Text("First Page"),
),
resizeToAvoidBottomPadding: false,
body: Container(
padding: EdgeInsets.only(top: 100.0, right: 20.0, left: 20.0, bottom: 20.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Text(
'Hello',
style: TextStyle(
fontSize: 50.0,
fontWeight: FontWeight.bold,
fontFamily: "Pacifico"
),
),
TextFormField(
keyboardType: TextInputType.number,
inputFormatters: <TextInputFormatter>[
WhitelistingTextInputFormatter.digitsOnly
],
controller: _acontroller,
decoration: InputDecoration(
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(20.0),
),
hintText: 'Enter A value',
hintStyle: TextStyle(color: Colors.grey),
contentPadding: EdgeInsets.all(10)
)
),
TextFormField(
keyboardType: TextInputType.number,
inputFormatters: <TextInputFormatter>[
WhitelistingTextInputFormatter.digitsOnly
],
controller: _bcontroller,
decoration: InputDecoration(
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(20.0),
),
hintText: 'Enter B value',
hintStyle: TextStyle(color: Colors.grey),
contentPadding: EdgeInsets.all(5)
)
),
RaisedButton(
child: Text(" OK "),
color: Colors.red,
textColor: Colors.white,
splashColor: Colors.grey,
padding: EdgeInsets.fromLTRB(10, 10, 10, 10),
onPressed: () async {
if(_acontroller.text == "" && _bcontroller.text == "")
{
await showDialog(
context: context,
builder: (context) => new AlertDialog(
title: new Text('Please Enter The value'),
),
);
}
else if(_acontroller.text == "")
{
await showDialog(
context: context,
builder: (context) => new AlertDialog(
title: new Text('Please Enter The A value'),
),
);
}
else if(_bcontroller.text == "")
{
await showDialog(
context: context,
builder: (context) => new AlertDialog(
title: new Text('Please Enter The B value'),
),
);
}
else
{
//a = emailController.text;
var route = new MaterialPageRoute(
builder: (BuildContext context) =>
new SecondScreen(
value: User(
a:double.parse(_acontroller.text) ,
b:double.parse(_bcontroller.text) ,
)
),
);
Navigator.of(context).push(route);
}
}
),
Text('Answers : $c1',//+ {widget.value.c}.toString(),//${widget.value.c}
style: TextStyle(
fontSize: 35.0,
fontWeight: FontWeight.bold,
fontFamily: "Pacifico"
),
),
]
)
)
));
}
}
class SecondScreen extends StatefulWidget {
final User value;
double c1;
double c2;
//Function(double) callback;
SecondScreen ({Key key, this.value}) : super(key: key);
#override
_SecondScreenState createState() => _SecondScreenState();
}
class _SecondScreenState extends State<SecondScreen> {
var _ccontroller= new TextEditingController();
Future<bool> _onWillPop() async {
if(_ccontroller.text == ""){
await showDialog(
context: context,
builder: (context) => new AlertDialog(
title: new Text('Please Enter The Operator'),
),
);
}
else if(_ccontroller.text == "+"){
double a1= widget.value.a;
double b1= widget.value.b;
// c1 = a1+b1;
setState(() {
widget.c1 = a1+b1;
});
//widget.callback = (c) as Function(double);
Navigator.pop(context);
}
else if(_ccontroller.text == "-"){
double a1= widget.value.a;
double b1= widget.value.b;
setState(() {
widget.c1 = a1-b1;
});
Navigator.pop(context, '$widget.c1');
}
else if(_ccontroller.text == "*" || _ccontroller.text =="×" ){
double a1= widget.value.a;
double b1= widget.value.b;
setState(() {
widget.c1 = a1*b1;
});
Navigator.pop(context, '$widget.c1');
}
else if(_ccontroller.text == "/"){
double a1= widget.value.a;
double b1= widget.value.b;
setState(() {
widget.c1 = a1/b1;
});
Navigator.pop(context, '$widget.c1');
}
else{
await showDialog(
context: context,
builder: (context) => new AlertDialog(
title: new Text('Wrong Operator'),
),
);
}
}
#override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop:_onWillPop,
child: Scaffold(
appBar: AppBar(
title: Text('Operation'),
backgroundColor: new Color(0xFF81C784),
),
body: Center(
child: Wrap(
children: <Widget>[
TextFormField(
controller: _ccontroller,
decoration: new InputDecoration.collapsed(
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10.0),
),
hintText: 'Enter Operator'
),
),
],
),
)
),
);
}
}
You can await the result from your Navigator.of(context).push(...) and use it in your first screen to display the result from the second screen. Also, when you pop your second screen, you need to do it by calling Navigator.of(context).pop(yourValue) for it to work.
Check out this article from Flutter.dev: Return Data from a Screen for a detailed, step-by-step explanation on the topic.
Check cookbook at
https://flutter.dev/docs/cookbook/navigation/returning-data
Basically
Navigator.pop(context, 'Nope.');