1

I have a futureBuilder which populates a listView from Json.

On every iteration of my list, I'm calling a custom widget, which returns a card.

Works like a charm. But whenever I try and add interactivity inside my child widget like an elevatedButton... Nothing happens.

Is it even possible to add interactivity inside a futurebuilder listview ??? I mean, I get that it's stateful. Could my issue be related to it ?

Is there anyway I can get around this ?

Future<List> get campaignList async {
String jwt = await userToken;

var url = Uri.parse('[API_URL]');
var response = await http.get(
  url,
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer $jwt',
  },
);

List<dynamic> list = json.decode(response.body);
return list;
}


                      ....................
                      FutureBuilder<List>(
                      future: campaignList,
                      builder: (BuildContext context,
                          AsyncSnapshot<List> snapshot) {
                        List<Widget> children;

                        children = <Widget>[];

                        if (snapshot.hasData) {
                          var campaignList = snapshot.data;
                          campaignList!
                              .forEach((campaign) => children += <Widget>[
                                    CampaignCard(
                                        id: campaign['id'],
                                        title: campaign['title'],
                                        operatingModeId:
                                            campaign['operating_mode_id'],
                                        coringTypeId:
                                            campaign['coring_type_id'],
                                        createdAt: campaign['created_at'],
                                        status: campaign['status'],
                                        statusId: campaign['status_id'],
                                        done: campaign['done'],
                                        total: campaign['total'])
                                  ]);
                        } else {
                          if (snapshot.hasError) {
                            children = <Widget>[Text('${snapshot.error}')];
                          } else {
                            children = <Widget>[Text('Loading')];
                          }
                        }
                        return Center(
                          child: Column(
                            mainAxisAlignment: MainAxisAlignment.center,
                            crossAxisAlignment: CrossAxisAlignment.center,
                            children: children,
                          ),
                        );
                      })
                 .....................
import 'dart:convert';
import 'package:flutter/material.dart';
//++import 'package:intl/intl.dart';
import 'package:percent_indicator/percent_indicator.dart';
import '../colors.dart';
import '../map_screen.dart';
import 'package:jiffy/jiffy.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:http/http.dart' as http;

class CampaignCard extends StatefulWidget {
  CampaignCard(
      {Key? key,
      required this.id,
      required this.title,
      required this.operatingModeId,
      required this.coringTypeId,
      required this.createdAt,
      required this.status,
      required this.statusId,
      required this.done,
      required this.total})
      : super(key: key);

  final int id;
  final String title;
  final int operatingModeId;
  final int coringTypeId;
  final String createdAt;
  final String status;
  final int statusId;
  final int done;
  final int total;

  final _storage = FlutterSecureStorage();

  Future<String> get userToken async {
    var jwt = await _storage.read(key: "token");
    if (jwt == null) return "Votre compte n\' a pas pu être identifié.";
    return jsonDecode(jwt);
  }

  Future<String> get coringType async {
    String jwt = await userToken;

    var url = Uri.parse('https://api-dev.maorie.com/api/campaigns');
    var response = await http.get(
      url,
      headers: {
        'Content-Type': 'application/json',
        'Authorization': 'Bearer $jwt',
      },
    );

    String string = json.decode(response.body);
    return string;
  }

  @override
  _CampaignCardState createState() => _CampaignCardState();
}

class _CampaignCardState extends State<CampaignCard>
    with SingleTickerProviderStateMixin {
  @override
  void initState() {
    super.initState();
  }

  @override
  void dispose() {
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    final percent = widget.done / widget.total;

    return Card(
      elevation: 5,
      child: ClipRect(
          child: Padding(
        padding: EdgeInsets.all(7),
        child: Stack(children: <Widget>[
          Align(
            alignment: Alignment.centerRight,
            child: Stack(
              children: <Widget>[
                Padding(
                    padding: const EdgeInsets.only(left: 10, top: 5),
                    child: Column(
                      children: <Widget>[
                        Row(
                            mainAxisAlignment: MainAxisAlignment.spaceBetween,
                            children: <Widget>[
                              Text(
                                widget.title,
                                style: TextStyle(
                                    fontWeight: FontWeight.bold, fontSize: 20),
                              ),
                              Chip(
                                label: Text(widget.coringTypeId.toString(),
                                    style: TextStyle(color: Colors.white)),
                                backgroundColor:
                                    generateMaterialColor(Palette.tiro),
                              ),
                            ]),
                        Row(
                            mainAxisAlignment: MainAxisAlignment.spaceBetween,
                            children: <Widget>[
                              Text(
                                '${Jiffy(widget.createdAt).yMMMd}',
                              ),
                            ]),
                        Row(
                            mainAxisAlignment: MainAxisAlignment.spaceBetween,
                            children: <Widget>[
                              DataTable(
                                columnSpacing: 100.0,
                                columns: const <DataColumn>[
                                  DataColumn(
                                    label: Text(
                                      'Carottes',
                                    ),
                                  ),
                                  DataColumn(
                                    label: Text(
                                      'Matériau',
                                    ),
                                  ),
                                ],
                                rows: <DataRow>[
                                  DataRow(
                                    cells: <DataCell>[
                                      DataCell(Text(widget.total.toString(),
                                          textAlign: TextAlign.center)),
                                      DataCell(Text(
                                          widget.operatingModeId.toString())),
                                    ],
                                  ),
                                ],
                              ),
                            ]),
                        Row(
                            mainAxisAlignment: MainAxisAlignment.center,
                            crossAxisAlignment: CrossAxisAlignment.center,
                            mainAxisSize: MainAxisSize.max,
                            children: <Widget>[
                              Padding(
                                  padding: const EdgeInsets.all(25.0),
                                  child: new CircularPercentIndicator(
                                    radius: 100.0,
                                    lineWidth: 10.0,
                                    percent: percent,
                                    animation: true,
                                    center: Text("${percent * 100}%"),
                                    backgroundColor: Colors.grey,
                                    progressColor:
                                        generateMaterialColor(Palette.ponga),
                                  )),
                            ]),
                        Row(
                            mainAxisAlignment: MainAxisAlignment.center,
                            crossAxisAlignment: CrossAxisAlignment.center,
                            mainAxisSize: MainAxisSize.max,
                            children: <Widget>[
                              Padding(
                                padding: const EdgeInsets.all(25.0),
                                child: ElevatedButton(
                                    onPressed: () => Navigator.push(
                                        context,
                                        MaterialPageRoute(
                                            builder: (context) => MapScreen(
                                                campaignId: widget.id))),
                                    child: Text('Voir sur la carte')),
                              ),
                            ]),
                      ],
                    ))
              ],
            ),
          )
        ]),
      )),
    );
  }
}

Brice Le Roux
  • 83
  • 1
  • 8
  • 1
    First of all why you have emty `initState` and `dispose` method and `SingleTickerProviderStateMixin` mixin which you are not even using and you have nothing which is required to be stateful widget and About your question you have a `Stack` widget so that can be the problem and your button could be under some other widget – Pokaboom Jun 29 '21 at 13:37
  • Thanks for your reply. nitState and dipose are not empty, I just not included that part of the code in the post. SingleTickerProviderStateMixin is eventually used in initState (I have an animationController there). I tried ans embed an elevatedButton on my widget, which led to the same result ! nothing happns on pressed event. Stack widget is supposedly not responsible for this behaviour then. – Brice Le Roux Jun 29 '21 at 14:54

0 Answers0