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);
}
}
Related
I have a StreamBuilder which returns me a ListView of items.
For each item I also have ElevatedButton button.
ElevatedButton(
onPressed: () {
setState(() {
pressGeoON = !pressGeoON;
if (pressGeoON == true) {
favoriteDataList.add(snapshot
.data?.docs[index].id);
} else {
favoriteDataList.removeWhere(
(item) =>
item ==
snapshot.data
?.docs[index].id);
}
});
},
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.all<
Color>(
Colors.deepPurple,
),
),
child: Icon(
Icons.favorite,
color: pressGeoON
? Colors.blue
: Colors.red,
),
)
I'm trying to change state of only clicked button, but so far with my code it always changes state of all buttons inside of list.
How can I change state only of clicked button and not all of them?
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;
}
}
I am trying to use the progress state button in flutter. From the pub.dev docs, the widget should be set up as follows
Widget buildTextWithIcon() {
return ProgressButton.icon(iconedButtons: {
ButtonState.idle: IconedButton(
text: "Send",
icon: Icon(Icons.send, color: Colors.white),
color: Colors.deepPurple.shade500),
ButtonState.loading:
IconedButton(text: "Loading", color: Colors.deepPurple.shade700),
ButtonState.fail: IconedButton(
text: "Failed",
icon: Icon(Icons.cancel, color: Colors.white),
color: Colors.red.shade300),
ButtonState.success: IconedButton(
text: "Success",
icon: Icon(
Icons.check_circle,
color: Colors.white,
),
color: Colors.green.shade400)
}, onPressed: onPressedIconWithText, state: stateTextWithIcon);
}
I have a function (already written and working fine) that I want to run when the button is clicked, changing the button state to ButtonState.loading then to ButtonState.success then back to ButtonState.idle. See below the function stated on the pub.dev site.
void onPressedIconWithText() {
switch (stateTextWithIcon) {
case ButtonState.idle:
stateTextWithIcon = ButtonState.loading;
Future.delayed(Duration(seconds: 1), () {
setState(() {
stateTextWithIcon = Random.secure().nextBool()
? ButtonState.success
: ButtonState.fail;
});
});
break;
case ButtonState.loading:
break;
case ButtonState.success:
stateTextWithIcon = ButtonState.idle;
break;
case ButtonState.fail:
stateTextWithIcon = ButtonState.idle;
break;
}
setState(() {
stateTextWithIcon = stateTextWithIcon;
});
}
}
However, I am new to coding, and have no idea at all on how to use "breaks" or to change the button state. Could anybody help with advising on how i would insert my funcion (let's say its just void runFunction() in to the above code, changing the state from idle --> loading (onPressed) --> success --. idle.
Any help would be greatly appreciated
You could use setState to update the values for stateTextWithIcon
ButtonState stateTextWithIcon = ButtonState.idle;
Widget buildTextWithIcon() {
return ProgressButton.icon(iconedButtons: {
ButtonState.idle: IconedButton(
text: "Send",
icon: Icon(Icons.send, color: Colors.white),
color: Colors.deepPurple.shade500),
ButtonState.loading:
IconedButton(text: "Loading", color: Colors.deepPurple.shade700),
ButtonState.fail: IconedButton(
text: "Failed",
icon: Icon(Icons.cancel, color: Colors.white),
color: Colors.red.shade300),
ButtonState.success: IconedButton(
text: "Success",
icon: Icon(
Icons.check_circle,
color: Colors.white,
),
color: Colors.green.shade400)
}, onPressed: (){
progressButton()
},
state: stateTextWithIcon,
);
this is the fucntion handled by my onPressed
Future progressButton() async {
setState(() {
//sets the state of stateTextWithIcon to loading once button is pressed
stateTextWithIcon = ButtonState.loading;
});
var url = 'https://google.com';
final response = await http.get(url);
if (response.statusCode == 200 || response.statusCode == 201) {
setState(() {
//sets the state of stateTextWithIcon to success if whatever request made was successful
stateTextWithIcon= ButtonState.success;
});
} else {
setState(() {
//sets the state of stateTextWithIcon to fail if the request was unsuccessful
stateTextWithIcon = ButtonState.fail;
});
}
}
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 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-