I am working on flutter app, where I am generating QR code for payment. When user click on Generate QR code button, it will call an API which return svg.
My problem is that when I receive this svg from API, I update state. In my code, I have condition that if this state is null, display button, else display svg. However, I click on button, state is updated but my UI is not updated. I need to click on for example text input to see this image. How can I fix this problem, so that after button click it will update UI without me needing to click somewhere?
I also tried to add spinner until API request is completed, but again, state was updated (I printed everything), but spinner was spinning infinitely.
Here is how I declare svg image variable
String? paymentQrCode;
Here is my function, which is getting svg from API and updating state.
handleQrCodePaymentMethod() async {
try {
final authService = AuthenticationService();
final dioClient = DioClient(authService);
ApiClient apiClient =
ApiClient(baseUrl: Env.apiUrl, dioClient: dioClient);
String endpoint = 'funds/generate-payment';
Map<String, String> data = {
'paymentType': 'qrCode',
'iban': _iban,
'bic': _swift,
'bank': _bankName,
'paymentIdentification': widget.accountId,
'amount': _priceController.text,
'currency': _selectedFundsCurrency.toString(),
};
var response = await apiClient.performPostRequest(endpoint, data);
if (response['response'] == 'OK') {
setState(() {
paymentQrCode = response['qrCode'];
});
}
} catch (e) {
print('Catch error: $e');
}
}
And here is my how I call my dialog and also dialog it self.
PopupMenuButton<String>(
icon: const Icon(Icons.more_vert,
color: Color.fromRGBO(235, 235, 245, 0.6)),
shape: const RoundedRectangleBorder(
borderRadius:
BorderRadius.all(Radius.circular(16.0)),
),
color: Colors.white,
onSelected: (String value) {
if (value == 'settings') {
_settings(context, widget.name,
widget.investmentTarget);
} else if (value == 'addFunds') {
_addFunds(context);
} else if (value == 'accountStatement') {
_accountStatement(context);
} else if (value == 'taxAccountStatement') {
_taxAccountStatement(context);
}
},
AddFunds dialog:
Future<bool> _addFunds(BuildContext context) {
bool isDepositInfoVisible = false;
return showDialog<bool>(
barrierDismissible: false,
context: context,
builder: (BuildContext context) {
return StatefulBuilder(
builder: (BuildContext context, StateSetter setStateDialog) {
return AlertDialog(
contentPadding:
const EdgeInsets.symmetric(horizontal: 12, vertical: 20),
insetPadding:
const EdgeInsets.symmetric(horizontal: 12, vertical: 20),
title: Row(
children: [
….
paymentQrCode == null
? ElevatedButton(
onPressed: () =>
handleQrCodePaymentMethod(),
style: ElevatedButton
.styleFrom(
minimumSize:
const Size(
200, 50),
padding:
const EdgeInsets
.symmetric(
vertical:
14.0,
horizontal:
20.0),
backgroundColor:
const Color
.fromRGBO(
0,
122,
255,
1),
foregroundColor:
Colors.white,
),
child: Text(
AppLocalizations.of(
context)!
.detailsGenerateButton,
),
)
: Padding(
padding:
const EdgeInsets
.only(
bottom: 65.0),
child:
SvgPicture.string(
paymentQrCode
.toString(),
key: ValueKey<
String>(
paymentQrCode
.toString()),
height: 330,
width: 330,
),
)
So as you can see, there is part where I check if paymentQrCode is null, then I display button, else I display svg image itself.
Thanks for any advices!
2
Answers
I managed to get it working.
In my addFunds dialog I am declaring 'StateSetter setStateDialog'.
I tried to pass it as a parameter to function, where I am saving state.
And then, instead of setState, I called this parameter setStateDialog
And now, my QR code displays after I click on generate :)
Use
flutter_svg: ^2.0.10+1
. It provides an option to fetch SVG images from the internet via a URL and display a placeholder until the image loads.Use below code to show network svg using
flutter_svg
package