Search code examples
fluttersetstateflutter-getx

Future builder return value keeps blinking


I have a screen with a container that shows the current time and under that a list view that contains list tiles with different regions and their corresponding time. I have a Future function that gets the time of a location. The problem is the text field that I have wrapped with future builder keeps blinking. It goes from null to time and back and forth. I want it to keep rebuilding to update the time, but how I do remove the blinking problem. and when I wrap newTime in setState it returns null. Any help will be really appreciated

class _WorldClockState extends State<WorldClock> {


final WorldTimeController worldTimeController =
      Get.put(WorldTimeController());
  String formattedTime = DateFormat('h:mm').format(DateTime.now());
  String hour = DateFormat('a').format(DateTime.now());
  late Timer _timer;
  var location;
  var time;

  @override
  void initState() {
    super.initState();
    _timer =
        Timer.periodic(const Duration(milliseconds: 500), (timer) => _update());
  }

  void _update() {
    setState(() {
      formattedTime = DateFormat('h:mm').format(DateTime.now());
      hour = DateFormat('a').format(DateTime.now());
    });
  }

  var newUrl;
  var newResponse;

  getTime(location) async {
    newUrl = "http://worldtimeapi.org/api/timezone/$location";
    newResponse = await get(Uri.parse(newUrl));
    Map newData = jsonDecode(newResponse.body);
    var time = newData['datetime'];
    String dateTime = newData["utc_datetime"];
    String offset = newData["utc_offset"];
    DateTime now = DateTime.parse(dateTime);
    now = now.add(Duration(
        hours: int.parse(offset.substring(1, 3)),
        minutes: int.parse(offset.substring(4))));
    String newtime = DateFormat.jm().format(now);
    return newtime;
  }

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

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
        resizeToAvoidBottomInset: false,
        body: SingleChildScrollView(
          child: Column(
            children: [
              Padding(
                padding: const EdgeInsets.only(top: 20.0),
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    Text(formattedTime,
                        style: GoogleFonts.lato(
                            fontSize: 80.0,
                            color: Colors.blue,
                            fontStyle: FontStyle.normal,
                            letterSpacing: 5.0)),
                    Padding(
                      padding: const EdgeInsets.only(top: 40.0, left: 5.0),
                      child: Text(
                        hour,
                        style: GoogleFonts.lato(
                          color: Colors.blue,
                          fontSize: 30.0,
                        ),
                      ),
                    ),
                  ],
                ),
              ),
              Container(
                child: Text(
                  DateFormat('EE,  MMM d').format(DateTime.now()),
                  style: GoogleFonts.lato(
                    color: Colors.white,
                    fontSize: 20.0,
                    letterSpacing: 2.0,
                  ),
                ),
              ),
              const Padding(
                padding: EdgeInsets.only(top: 20.0, left: 30.0, right: 30.0),
                child: Divider(
                  color: Colors.white,
                  height: 2.0,
                ),
              ),
              Container(
                height: 600.0,
                width: 450.0,
                child: Padding(
                  padding: const EdgeInsets.only(top: 20.0),
                  child: ListView.builder(
                    scrollDirection: Axis.vertical,
                    physics: const BouncingScrollPhysics(),
                    shrinkWrap: true,
                    itemCount: worldTimeController.WorldTimeList.length,
                    itemBuilder: (BuildContext context, index) => Padding(
                      padding: const EdgeInsets.only(bottom: 18.0),
                      child: Slidable(
                        key: UniqueKey(),
                        startActionPane: ActionPane(
                          motion: ScrollMotion(),
                          dismissible: DismissiblePane(onDismissed: () {
                            worldTimeController.WorldTimeList.removeAt(index);
                          }),
                          children: const [],
                        ),
                        child: ListTile(
                          leading: Text(
                              worldTimeController.WorldTimeList[index].location,
                              style: GoogleFonts.lato(
                                  color: Colors.white70, fontSize: 25)),
                          trailing: FutureBuilder(
                              future: getTime(worldTimeController
                                  .WorldTimeList[index].location),
                              builder: (context, AsyncSnapshot snapshot) {
                                return Text(
                                  '${snapshot.data}',
                                  style: GoogleFonts.lato(
                                      color: Colors.white70, fontSize: 35.0),
                                );
                              }),
                        ),
                      ),
                    ),
                  ),
                ),
              )
            ],
          ),
        ),

Solution

  • I fixed the error by just removing the slidable widget that was wrapping the future builder, don't know why that was causing an error