Posts in the “flutter” category

Flutter: How to supply an initial value to a TextFormField

If you need to supply an initial value to a Flutter TextFormField (and possibly a TextField), the initialValue parameter may not do what you expect it to do. (More on this in the Discussion.) Instead, I just used this technique to populate the initial value for a TextFormField when using it with a TextEditingController:

A Dart Future/then/catchError example

When I was trying to debug a problem that I thought was related to Flutter’s SharedPreferences library, I ended up rewriting a preferences method to use code like this rather than the normal approach:

Future<SharedPreferences> fPrefs = SharedPreferences.getInstance();
fPrefs.then((value) {rez = value.getBool(KEY_ENABLE_NOTIFICATIONS) ?? false; })
   .catchError((e) {
       debugPrint("===== ERROR: ${e.error}");
       return 60;
   });
return rez;

While that ended up being a waste of time, the benefit of my side excursion is that I get to show this example of how to use then and catchError with a Dart future. So if you wanted to see a Dart Future/then/catchError example, I hope this is helpful.

When you have Flutter app performance problems, try Profile Mode

Today I learned that for several reasons, Flutter Debug mode may be significantly slower than Production mode. As just one reason, Debug mode is compiled using JIT while Production mode uses AOT. You can read more about the reasons on the Flutter UI Performance page.

A very important note on that page is that if you’re using a real hardware device (as opposed to an emulator), you can run your code in Profile mode like this:

Getting Flutter notifications working on Android

Over the last two days I started to get my Just Be notifications working on Android. I’m rewriting the app using Flutter, and this is what a notification currently looks like if you do a long-press on the app icon after receiving a notification.

How to use the Flutter CupertinoDatePicker in “time picker” mode

As a brief note, if you ever need to use the Flutter CupertinoDatePicker — a spinning wheel chooser — in “time-picker/time-chooser” mode, I can confirm that this example works:

child: CupertinoDatePicker(
    mode: CupertinoDatePickerMode.time,
    initialDateTime: DateTime(1969, 1, 1, _timeOfDay.hour, _timeOfDay.minute),
    onDateTimeChanged: (DateTime newDateTime) {
        var newTod = TimeOfDay.fromDateTime(newDateTime);
        _updateTimeFunction(newTod);
    },
    use24hFormat: false,
    minuteInterval: 1,
)

Note that even when you only want to set an initial time value, the CupertinoDatePicker in CupertinoDatePickerMode.time mode requires that you pass it a DateTime value, so I just give it a date/time back in 1969:

initialDateTime: DateTime(1969, 1, 1, _timeOfDay.hour, _timeOfDay.minute),

You can set the year, month, and day to whatever you want; the only important values in CupertinoDatePickerMode.time mode are the hour and minute.

A complete CupertinoDatePicker/CupertinoDatePickerMode example

If it helps to see a complete CupertinoDatePicker/CupertinoDatePickerMode example, here you go:

import 'package:flutter/material.dart';
import 'shared_prefs_helper.dart';
import 'package:flutter/cupertino.dart';

class PreferencesSelectTime extends StatefulWidget {
    String _title;
    TimeOfDay _timeOfDay;
    Function _updateTimeFunction;

    PreferencesSelectTime(this._title, this._timeOfDay, this._updateTimeFunction);

    @override
    PreferencesSelectTimeState createState() => PreferencesSelectTimeState(_title, _timeOfDay, _updateTimeFunction);
}

class PreferencesSelectTimeState extends State<PreferencesSelectTime> {

    String _title;
    TimeOfDay _timeOfDay;
    Function _updateTimeFunction;
    PreferencesSelectTimeState(this._title, this._timeOfDay, this._updateTimeFunction);

    @override
    Widget build(BuildContext context) {

        return Scaffold(
            appBar: AppBar(
                title: Text(_title),
            ),
            body: FutureBuilder<TimeOfDay>(
                future: SharedPreferencesHelper.getStartTime(),
                builder: (BuildContext context, AsyncSnapshot snapshot) {
                    if (snapshot.connectionState == ConnectionState.done) {
                        return Container(
                            height: MediaQuery.of(context).size.height / 4,
                                child: CupertinoDatePicker(
                                    mode: CupertinoDatePickerMode.time,
                                    initialDateTime: DateTime(1969, 1, 1, _timeOfDay.hour, _timeOfDay.minute),
                                    onDateTimeChanged: (DateTime newDateTime) {
                                        var newTod = TimeOfDay.fromDateTime(newDateTime);
                                        _updateTimeFunction(newTod);
                                    },
                                    use24hFormat: false,
                                    minuteInterval: 1,
                                )
                        );
                    } else {
                        return new CircularProgressIndicator();
                    }
                }
            )
        );
    }
}

I call that code from another widget like this:

onTap: () {
    Navigator.push(
        context,
        MaterialPageRoute(builder: (context) => PreferencesSelectTime(
            'Notification Stop Time',
            _stopTime,
            SharedPreferencesHelper.setStopTime
        ))
    );
},

It generates a Flutter screen/widget that looks like this:

How to use the Flutter CupertinoDatePicker in “time picker” mode

Summary

In summary, if you ever want to use the Flutter CupertinoDatePicker in “time picker” mode, I hope this example code is helpful.

A Flutter function to convert a TimeOfDay to a String (formatted)

If you ever need a Dart/Flutter method to format a TimeOfDay variable — i.e., convert a TimeOfDay to a String — I can confirm that this method works:

String formatTimeOfDay(TimeOfDay tod) {
    final now = new DateTime.now();
    final dt = DateTime(now.year, now.month, now.day, tod.hour, tod.minute);
    final format = DateFormat.jm();  //"6:00 AM"
    return format.format(dt);
}