How to deal with setState properly - flutter

void showSimpleCustomDialog(BuildContext context, String listName) async{
if(randList.isEmpty){
randList = await theDb.queryWhere("$listName");
}else{
randList.clear();
randList = await theDb.queryWhere("$listName");
}
setState((){
});
String randValue = "Click generate new to get a random value";
Dialog simpleDialog = Dialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12.0),
),
child: Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Padding(
child: Text(
"$randValue"
),
),
Padding(
child: Row(
children: <Widget>[
RaisedButton(
color: Colors.blue,
onPressed: ()
String lol = randList[0 + rng.nextInt(randList.length - 0)].getItem();
print(randValue);
setState(() {
randValue = lol;
});
},
child: Text(
'generate new',
style: TextStyle(fontSize: 18.0, color: Colors.white),
),
)
],
),
),
],
),
),
);
showDialog(
context: context, builder: (BuildContext context) => simpleDialog);}
When I am clicking on "generate new" button I want to update my randomValue and to display that randomValue as Text Widget. To do that dynamically Im using setState, but it is not working, and i dont understand why. Please help me.

You should use StatefulBuilder with dialogue.
showDialog(
context: context,
builder: (context) {
String contentText = "Content of Dialog";
return StatefulBuilder(
builder: (context, setState) {
return AlertDialog(
title: Text("Title of Dialog"),
content: Text(contentText),
actions: <Widget>[
FlatButton(
onPressed: () => Navigator.pop(context),
child: Text("Cancel"),
),
FlatButton(
onPressed: () {
setState(() {
contentText = "Changed Content of Dialog";
});
},
child: Text("Change"),
),
],
);
},
);
},

Related

how to put GestureDetector inside Container alert

I wanna put GestureDetector with container alert but it show error. anyone know how to make this code works? Here the code below which i try to put GestureDetector for the alert container.
Without GestureDetector it works fine but i wanna make whole screen touch able to return to other page.
showPopup(BuildContext context) {
// set up the buttons
// ignore: deprecated_member_use
// set up the AlertDialog
GestureDetector(
Container alert = Container(
child: Stack(
children: <Widget>[
if (controllers!.isNotEmpty)
CarouselSlide2(
controllers: controllers!,
),
Padding(
padding: const EdgeInsets.only(top:688.0,left: 90),
child: GestureDetector(
onTap: () async {
isPop = false;
Navigator.pop(context);
_checkTimer();
},
// child: Icon(Icons.arrow_back,color: Colors.white,size: 100,),
child: DefaultTextStyle(
style: TextStyle(color: Colors.white,fontSize: 30),
child: Text("Tap to return",),
)
),
)
],
)));
// show the dialog
showDialog(
barrierDismissible: true,
context: context,
builder: (BuildContext context) {
return WillPopScope(
onWillPop: () async {
const shouldPop = true;
isPop = false;
Navigator.pop(context);
_checkTimer();
return shouldPop;
},
child: alert);
},
);
}
You are using widget in a wrong way, try this:
Widget alert = GestureDetector(
onTap: () {
print("tap");
},
child: Container(
child: Stack(
children: <Widget>[
if (controllers!.isNotEmpty)
CarouselSlide2(
controllers: controllers!,
),
Padding(
padding: const EdgeInsets.only(top: 688.0, left: 90),
child: GestureDetector(
onTap: () async {
isPop = false;
Navigator.pop(context);
_checkTimer();
},
// child: Icon(Icons.arrow_back,color: Colors.white,size: 100,),
child: DefaultTextStyle(
style: TextStyle(color: Colors.white, fontSize: 30),
child: Text(
"Tap to return",
),
)),
)
],
)),
)

Error GlobalKey Flutter Detected, How solve?

after a few weeks of using Flutter CRUD I was running normally and able to enter the database, but this time I encountered an error as shown below.
The error appears when I finish editing data, delete data. What do you think the solution to this problem is, friends?
Here I provide a snippet of my source code
listnasabah.dart
class ListNasabah {
ApiService apiService;
ListNasabah({this.apiService});
void getNasabah() {
apiService.getNasabah().then((nasabah) {
print(nasabah);
});
}
Widget createViewList() {
return SafeArea(
child: FutureBuilder(
future: apiService.getNasabah(),
builder: (BuildContext context, AsyncSnapshot<List<Nasabah>> snapshot) {
if (snapshot.hasError) {
return Center(
child: Text(
'Something wrong with message: ${snapshot.error.toString()}',
textAlign: TextAlign.center,
),
);
} else if (snapshot.connectionState == ConnectionState.done) {
List<Nasabah> nasabah = snapshot.data;
return nasabahListView(nasabah);
} else {
return Center(
child: CircularProgressIndicator(),
);
}
},
),
);
}
Widget nasabahListView(List<Nasabah> listnasabah) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 16.0),
child: ListView.builder(
shrinkWrap: true,
itemBuilder: (context, index) {
Nasabah nasabah = listnasabah[index];
return Padding(
padding: const EdgeInsets.only(top: 8.0),
child: Card(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
nasabah.nama_debitur,
style: Theme.of(context).textTheme.bodyText1,
),
Text(nasabah.alamat),
Text(nasabah.no_ktp),
Text(nasabah.no_telp),
Text(nasabah.no_selular),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
ElevatedButton.icon(
onPressed: () {
showDialog(
context: context,
builder: (context) => AlertDialog(
title: Text('Hapus Data Nasabah'),
content: Text(
'Apakah anda yakin ingin menghapus data nasabah ini?'),
actions: [
TextButton(
child: Text('Yes'),
onPressed: () async {
apiService
.deleteNasabah(nasabah.id)
.then((value) => Navigator.of(
context)
.pushReplacement(
MaterialPageRoute(
builder: (context) =>
DataNasabah())));
})
],
),
);
},
style: ElevatedButton.styleFrom(
primary: Colors.red,
),
icon: Icon(Icons.delete),
label: Text('Hapus'),
),
SizedBox(
width: 5,
),
ElevatedButton.icon(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => DetailNasabah(
nasabah: nasabah,
),
),
);
},
icon: Icon(Icons.navigate_next),
label: Text(
'Detail',
),
)
],
)
],
),
),
),
);
},
itemCount: listnasabah.length,
),
);
}
}

showModalBottomSheet Function onClose

I want to add a function when the showModalBottomSheet is close or when the barrier tapped the function run(routing to the main page) but how?
I want to run this when the barrier tapped/modal closed
Navigator.pushNamedAndRemoveUntil(context, '/mainMenuPage', (route) => false);
Modal Code
showModalBottomSheet(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(
top: Radius.circular(25.0),
),
),
backgroundColor: Colors.white,
context: context,
builder: (context) => Widget(...),
);
}
Try below code hope its help to you.
Your Widget with bottomSheet:
Center(
child: ElevatedButton(
child: const Text('showModalBottomSheet'),
onPressed: () {
showModalBottomSheet<void>(
context: context,
builder: (BuildContext context) {
return Container(
height: 200,
color: Colors.amber,
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
const Text('Modal BottomSheet'),
],
), //MyWidget()
),
);
},
).then(
(value) => Navigator.push(
context,
MaterialPageRoute(
builder: (context) => MyWidget(),
),
),
);
},
),
),
Other class:
class MyWidget extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Container(
color: Colors.white,
child: Center(
child: Text(
'Hello, World!',
style: Theme.of(context).textTheme.headline4,
),
),
);
}
}
.then() -> This means that the next instructions will be executed. But it allows you to execute the code when the asynchronous method completes.
showModalBottomSheet(
context: context,
builder: (context){
return Text("example");
}
).then((value) => {
Navigator.of(context).push(MaterialPageRoute(builder: (context) => const Page2()))
});
You can try like this.

alertDialog won't appear in flutter

I have a list item when long pressed executes _selectionAlert which have two buttons one for delete and one for edit(refer image). Delete works fine but when I press on edit it should execute _editAlert which should show another alertDialog but when I click it nothing happens what's the problem here?
This is responsible to show alert dialog in _selectionAlert
TextButton( // refer code bellow
child: Text('Edit', style: TextStyle(color: Colors.grey)),
onPressed: (){
_editAlert();
Navigator.of(context).pop();
},
)
This bellow code runs when item is long pressed:
void _selectionAlert(){
var selItem = AlertDialog(
title: Text('What you want to do?'),
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
TextButton( // ignore this it is for deletion this works fine
child: Text('Delete', style: TextStyle(color: Colors.red)),
onPressed: (){
_deleteItem();
Navigator.of(context).pop();
},
),
TextButton(
child: Text('Edit', style: TextStyle(color: Colors.grey)),
onPressed: (){
_editAlert(); // this line should call _editAlert
Navigator.of(context).pop();
},
)
],
),
);
showDialog(
context: context,
builder: (BuildContext context){
return selItem;
}
);
}
Representation of above code:
void _editAlert(){ // edit alertDialog
var editItem = AlertDialog(
title: Text('Edit'),
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
TextField(
decoration: InputDecoration(
hintText: 'Edit Item',
),
controller: addeditem,
),
TextButton(
child: Text('Done'),
onPressed: (){
_editItem();
Navigator.of(context).pop();
}
)
],
),
);
showDialog(
context: context,
builder: (BuildContext context){
return editItem;
}
);
}
PS: edit button is of grey color the button surely is clickable and I am testing on google chrome.
Regards
Try to add return statement at your _editAlert method
_editAlert(){ // edit alertDialog
var editItem = AlertDialog(
title: Text('Edit'),
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
TextField(
decoration: InputDecoration(
hintText: 'Edit Item',
),
controller: addeditem,
),
TextButton(
child: Text('Done'),
onPressed: (){
_editItem();
Navigator.of(context).pop();
}
)
],
),
);
return showDialog( //like that
context: context,
builder: (BuildContext context){
return editItem;
}
);
}
Also your way is right,you can use poping for close previous pop up.

How did i setup popup AlertDialog?

How did i setup popup AlertDialog when int is equal or greater than 100?
showDialog(
context: _context,
builder: (BuildContext context) => AlertDialog(
title: Text("$_winner Won"),
)
);
void scoreTeamA() {
setState(() {
outputTeamA += _choiceA;
});
}
// I would like to show outputTeamA on the AlertDialog
Thank you
Mohammad
One way is to create a Widget for the AlertDialog and pass the String/Widget you want to show on that dialog.
class LoadingDialog{
static Future<void> showLoadingDialog(BuildContext context,String text) async {
return showDialog(
context: context,
builder: (BuildContext context){
return SimpleDialog(
children: <Widget>[
Center(
child: Container(
child: Column(
children: <Widget>[
SizedBox(
height:10,
),
Text(text),
]
),
),
),
],
),
}
);
}
}
then you can call on an Event like:
void scoreTeamA(){
outputTeamA += _choiceA;
LoadingDialog.showLoadingDialog(context, outputTeamA);
}
Note: this code might have some errors. i haven't tested this.
This is how I display an AlertDialog
showAlertDialog() {
return showDialog(
context: context,
builder: (context) => AlertDialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30),
side: BorderSide(color: Colors.redAccent, width: 2.0),
),
elevation: 6,
titlePadding: EdgeInsets.all(8.0),
titleTextStyle: TextStyle(
fontSize: 18, color: Colors.red, fontWeight: FontWeight.bold),
title: Text(
'This is the alert title',
textAlign: TextAlign.center,
),
contentPadding: EdgeInsets.all(8.0),
contentTextStyle: TextStyle(fontSize: 14, color: Colors.black),
content: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text('Content...')
//content goes here
],
),
actions: <Widget>[
FlatButton(
onPressed: () => Navigator.of(context).pop(), child: Text('Okay'))
],
),
);
}
And then you would do your if check to check
if( outputTeamA >= 100){
showAlertDialog();
}
Of course you could use outputTeamA in AlertDialog