I am using progress_dialog 1.2.0 package to show a progress dialog in my app, it is showing when I call pr.show() but not getting hidden when I call pr.hide():
onTap: () async {
pr.show();
print('clicked custom category');
print(categorylist[index].catName);
print(categorylist[index].catId);
// await getAllProductsInCategory(categorylist[index].catId);
setState(() {
catId = categorylist[index].catId;
myinitlist.clear();
myinitlist = List.from(productList);
pr.hide();
});
},
When I uncomment that getAllProductsInCategory() function it hides the dialog.
Try with :
onTap: () async {
pr.show();
print('clicked custom category');
print(categorylist[index].catName);
print(categorylist[index].catId);
setState(() {
catId = categorylist[index].catId;
myinitlist.clear();
myinitlist = List.from(productList);
Future.delayed(Duration(seconds: 3)).then((value) {
pr.hide().whenComplete(() {
print(pr.isShowing());
});
});
});
},
or :
onTap: () async {
pr.show();
print('clicked custom category');
print(categorylist[index].catName);
print(categorylist[index].catId);
Future.delayed(Duration(seconds: 3)).then((value) {
setState(() {
catId = categorylist[index].catId;
myinitlist.clear();
myinitlist = List.from(productList);
pr.hide().whenComplete(() {
print(pr.isShowing());
});
});
});
},
Please use await keyword when you are using async calls to start progressDialog & hide:
await progressDialog.show();
await progressDialog.hide();
Example:
Add the Package:
dependencies:
progress_dialog: ^1.2.4
import 'package:progress_dialog/progress_dialog.dart';
Create and initialize a ProgressDialog object inside the build() method passing context to it.
Initialize the ProgressDialog object:
final ProgressDialog pr = ProgressDialog(context);
By default it is a normal dialog to show some message, if you would like to use it to show percentage of progress done, specify the optional type parameter and specify if you want your dialog to dismiss when back button is pressed isDismissible parameter (Optional):
//For normal dialog
pr = ProgressDialog(context,type: ProgressDialogType.Normal, isDismissible: true/false, showLogs: true/false);
//For showing progress percentage
pr = ProgressDialog(context,type: ProgressDialogType.Download, isDismissible: true/false, showLogs: true/false);
> Note: Please initialize the ```ProgressDialog```, where you have availability of the context
Style the progress dialog (Optional)
pr.style(
message: 'Downloading file...',
borderRadius: 10.0,
backgroundColor: Colors.white,
progressWidget: CircularProgressIndicator(),
elevation: 10.0,
insetAnimCurve: Curves.easeInOut,
progress: 0.0,
textDirection: TextDirection.rtl,
maxProgress: 100.0,
progressTextStyle: TextStyle(
color: Colors.black, fontSize: 13.0, fontWeight: FontWeight.w400),
messageTextStyle: TextStyle(
color: Colors.black, fontSize: 19.0, fontWeight: FontWeight.w600)
);
Note: You don't need to use all parameters, all of them are optional.
Showing the progress dialog:
await pr.show();
Dynamically update the content shown out there
pr.update(
progress: 50.0,
message: "Please wait...",
progressWidget: Container(
padding: EdgeInsets.all(8.0), child: CircularProgressIndicator()),
maxProgress: 100.0,
progressTextStyle: TextStyle(
color: Colors.black, fontSize: 13.0, fontWeight: FontWeight.w400),
messageTextStyle: TextStyle(
color: Colors.black, fontSize: 19.0, fontWeight: FontWeight.w600),
);
Dismissing the progress dialog:
pr.hide().then((isHidden) {
print(isHidden);
});
// or
await pr.hide();
Navigating to next screens must be done after the completion of Future - hide(). See here for example.
Check if progress dialog is showing:
bool isProgressDialogShowing = pr.isShowing();
print(isProgressDialogShowing);
Use custom body
pr = ProgressDialog(
context,
type: ProgressDialogType.Normal,
isDismissible: true,
/// your body here
customBody: LinearProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(Colors.blueAccent),
backgroundColor: Colors.white,
),
);
For more details: https://flutterrepos.com/repo/fayaz07-progress_dialog-
Related
I have a timer button that waits for 30 seconds then be active, it is used to allow the user resend OTP verification code. there is also a "Verify" button that verifies the entered OTP and completes the authentication and then resets some variabe through setState.
problem is when I press the Verify button while the timer button is still counting, an error happens saying:
Unhandled Exception: setState() called after dispose():
_TimerButtonState#70c61(lifecycle state: defunct, not mounted)
E/flutter ( 3950): This error happens if you call setState() on a State object for a
widget that no longer appears in the widget tree (e.g., whose parent widget no longer
includes the widget in its build). This error can occur when code calls setState() from
a timer or an animation callback.
E/flutter ( 3950): The preferred solution is to cancel the timer or stop listening to
the animation in the dispose() callback. Another solution is to check the "mounted"
property of this object before calling setState() to ensure the object is still in the
tree.
by testing I can see it only happens if setState happens while the counter is still running. but can't find a way to make it stop counting prior to setstate.
Any Idea how can I solve this?
Timer Button
TimerButton(
buttonType: ButtonType.TextButton,
label: "Resend Code".tr,
timeOutInSeconds: 30,
onPressed: () async {
await sendOTP();
},
resetTimerOnPressed: false,
disabledColor: Colors.grey,
color: const Color.fromARGB(255, 245, 91, 165),
disabledTextStyle:
TextStyle(fontSize: 12.sp, color: Colors.white),
activeTextStyle: TextStyle(
fontSize: 13.sp,
color: Colors.white,
),
),
Verify Button:
SizedBox(
height: 35.h,
width: 220.w,
child: ElevatedButton(
onPressed: () async {
if (loading == true) {
} else {
final PhoneAuthCredential phoneAuthCredential =
PhoneAuthProvider.credential(
verificationId: verificationId,
smsCode: otpcontroller.text);
signInWithPhoneAuthCredential(phoneAuthCredential);
}
},
child: Container(
width: 220.w,
alignment: Alignment.center,
child: Text(
"Verify".tr,
style: GoogleFonts.lato(
fontStyle: FontStyle.normal,
color: Colors.white,
fontSize: 20.sp,
),
),
),
style: TextButton.styleFrom(
primary: Colors.white,
backgroundColor: const Color.fromARGB(255, 245, 91, 165)),
),
Verification Function:
void signInWithPhoneAuthCredential(
PhoneAuthCredential phoneAuthCredential) async {
setState(() {
loading = true;
});
try {
// ignore: non_constant_identifier_names
final AuthCredential =
await _auth.signInWithCredential(phoneAuthCredential);
setState(() {
loading = false;
});
if (AuthCredential.user != null) {}
} on FirebaseAuthException catch (e) {
setState(() {
loading = false;
});
Flushbar(
message: e.message,
duration: const Duration(seconds: 4),
).show(context);
}
}
Didn't find good solution to this, instead I replaced the timer button with a normal TextButton and circular_countdown_timer plugin. and contollred the button become active/inactive using a bool that changes its value with when the timer finishes.
In my flutter application I have a button for follow and unfollow a user.
buttonstate.isSelected && widget.user!.isFollowing == true
? ElevatedButton(
onPressed: () async {
await unfollowuser(widget.user!.id); //Api Call
},
child: Text(
'Following',
style: TextStyle(
color: Theme.of(context).disabledColor,
),
),
)
: ElevevatedButton(
onPressed: () async {
buttonstate.setButtonState(true);
await followuser(widget.user!.id); //Api Call
},
child: Text(
'Follow',
style: TextStyle(
color: Theme.of(context).accentColor,
),
),
),
My objective is whenever the button is pressed I want the Api call to happen as well as the state of the button should change from 'Follow' to 'Following'. Now the Api gets called, but the button wont change to 'following'. After the page is refreshed, button changes to 'following'. How can i manage state of the button using provider??
Ive created a provider for this purpose as follows
import 'package:flutter/material.dart';
class ButtonProvider with ChangeNotifier {
bool isSelected = false;
void setButtonState(bool value) {
isSelected = value;
notifyListeners();
}
bool? get buttondata {
return isSelected;
}
}
Hi I am still new to flutter but was trying to make a pretty simple app I thought.
This app consists of 30 buttons each in their own container. Code to follow. All I am trying to do is if a button is pressed then it will turn orange and then if it is longPressed that it goes back to its default color of white. Can someone explain how to do this. Here is an example of just 1 button.
Container(
width: 65,
height: 65,
child: MaterialButton(
shape: CircleBorder(
side: BorderSide(
width: 5,
color: Colors.blue[900],
style: BorderStyle.solid)),
child: Text(
"1",
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
),
color: Colors.white,
textColor: Colors.black,
onPressed: () {
setState(() {
color:
Colors.orange;
});
},
onLongPress: (){
setState(() {
color:
Colors.white;
});
},
),
),
Thanks in Advance
//declare color variable
Color myColor=Colors.white;
//set myColor to material button
color:myColor;
//in setstate use it like this
setState({
myColor=Colors.white; or myColor=Colors.orange;
})
first define a Color
Color buttonColor = Colors.white;
then pass this color to your button
MaterialButton(color: buttonColor)
after this inside your onPressed function
onPressed: () {
setState(() {
buttonColor =
Colors.orange;
});
},
I am fetching data from firebase database in a async function which triggers when the button is pressed. When the data fetching is complete it moves to the next page(next acitivty). So, in this whole process the async on pressed function takes time to execute the whole code. So, i wanted to show a progress bar until the whole code is executed. Can anyone suggest me how can i show a progress bar until the new activity starts.
Here is my code:
FlatButton(
child: Text("Next",style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontFamily: "Calibri",
fontSize: 20)),
color: Colors.blue,
onPressed:() {
elist.then((value)
async {
for (var item in value) {
alleyes.add(new facial(criminal_id: item.criminal_id,
part_size: item.part_size,
link: item.link));
Uint8List bytes = (await NetworkAssetBundle(Uri.parse(item.link)).load(item.link)).buffer.asUint8List();
eye_str.add(String.fromCharCodes(bytes));
}
Navigator.push(context,
MaterialPageRoute(builder: (context)=>App()));
}
);
},
)
You can start by creating a variable called loading.
bool loading = false;
After this, you can set the loading to true when the button gets tapped and display a progress indicator when the loading variable is true
loading
? Center(child: CircularProgressIndicator())
: FlatButton(
child: Text("Next",style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontFamily: "Calibri",
fontSize: 20)),
color: Colors.blue,
onPressed:() {
setState((){
loading = true;
}); // set loading to true here
elist.then((value)
async {
for (var item in value) {
alleyes.add(new facial(criminal_id: item.criminal_id,
part_size: item.part_size,
link: item.link));
Uint8List bytes = (await NetworkAssetBundle(Uri.parse(item.link)).load(item.link)).buffer.asUint8List();
eye_str.add(String.fromCharCodes(bytes));
}
setState((){
loading = false;
}); // set it to false after your operation is done
Navigator.push(context,
MaterialPageRoute(builder: (context)=>App()));
}
);
},
)
I used the like button flutter package from https://pub.dev/packages/like_button
to include like button to my list view from api. I have a table which is contain the count of likes and I show them in every item. now I want to increment the count of likes after tap on like button, but the type of function is bool and I can pass item id as parameter. so please help to solve this issue
LikeButton(
onTap: onLikeButtonTapped,
size: 20,
circleColor:
CircleColor(start: Colors.pink, end: Colors.pinkAccent),
bubblesColor: BubblesColor(
dotPrimaryColor: Colors.red,
dotSecondaryColor: Colors.redAccent,
),
likeBuilder: (bool isLiked) {
return Icon(
Icons.favorite,
color: isLiked ? Colors.pink : Colors.pink[300],
size: 20,
);
},
likeCount: news[index].count_like,
countBuilder: (int count, bool isLiked, String text) {
var color = isLiked ? Colors.grey[700] : Colors.grey[600];
Widget result;
if (count == 0) {
result = Text(
"love",
style: TextStyle(color: color),
);
} else
result = Text(
text,
style: TextStyle(color: color),
);
return result;
},
),
and here is the predefined function which is provided by the package developer
Future<bool> onLikeButtonTapped(bool isLiked) async{
<!-- send your request here -->
<!-- final bool success= await sendRequest(); -->
<!-- if failed, you can do nothing -->
<!-- return success? !isLiked:isLiked; -->
return !isLiked;
}
I am not sure if this could solve your problem, but I also had a similar situation to pass arguments through the function so I modified the function and somehow solved the issue. Hope it helps.
I used ontap like this:
onTap: (isLiked) {
return changedata(
isLiked,
);
},
and then the function,
Future<bool> changedata(status) async {
//your code
return Future.value(!status);
}
}