Charts, Flutter Form

Charts arrive via pub.dev packages (or honest Container composition), and Form + TextFormField + a GlobalKey validate the whole registration in one call, where a validator returning null means VALID.

12 min read · 10 cards · 2 checks

Read in: English · हिन्दी · ગુજરાતી


Theory

The last screen of the semester

Two jobs remain on FestConnect Flutter's list, and they close the whole subject.

The committee wants an attendance chart: day 1 vs day 2 vs day 3, bars.

And registration still accepts an empty name and a 3-digit phone: the form needs validation that scolds precisely and blocks submission until clean.

One of these jobs Flutter refuses to ship a widget for: and both endings teach the framework's deepest habit.

Theory

Charts: the honest situation

Flutter has no built-in chart widget. The real-world route is a package from pub.dev, declared in pubspec.yaml:

dependencies:

fl_chart: ^0.66.0

then flutter pub get, import, and use its BarChart/LineChart widgets. (fl_chart is today's standard; charts_flutter was Google's older library.)

But for a 3-bar attendance chart, there is a purer answer: compose it: a Row of Containers whose heights ARE the data: no package, runs anywhere, and it is the ImageSlider lesson's moral again: missing widgets are assemblies waiting to happen.

Practical

A bar chart from nothing but Containers

final attendance = {'Day 1': 320.0, 'Day 2': 410.0, 'Day 3': 275.0};

Row(
  crossAxisAlignment: CrossAxisAlignment.end,   // bars grow from a floor
  mainAxisAlignment: MainAxisAlignment.spaceEvenly,
  children: attendance.entries.map((e) {
    return Column(
      mainAxisSize: MainAxisSize.min,
      children: [
        Text('${e.value.toInt()}'),
        Container(
          width: 48,
          height: e.value / 2,        // data drives the pixels: 410 -> 205
          color: Colors.deepOrange,
        ),
        Text(e.key),
      ],
    );
  }).toList(),
)

Theory

Form: validation as a system

Three pieces turn scattered fields into a validating Form:

  • the key: final _formKey = GlobalKey<FormState>(); handed to Form(key: _formKey): your handle to the form's state
  • TextFormField: TextField plus a validator: function: (v) => v!.isEmpty ? 'Enter your name' : null
  • the submit call: _formKey.currentState!.validate(): runs EVERY field's validator, paints each returned message under its own field, and answers true only if all returned null

Read the validator's contract carefully: returning null means VALID: a String is the error message. That inversion is this topic's certain exam question.

Practical

The finished registration form

final _formKey = GlobalKey<FormState>();

Form(
  key: _formKey,
  child: Column(
    children: [
      TextFormField(
        decoration: const InputDecoration(labelText: 'Your name'),
        validator: (v) =>
            v == null || v.isEmpty ? 'Enter your name' : null,
      ),
      TextFormField(
        decoration: const InputDecoration(labelText: 'Phone'),
        keyboardType: TextInputType.number,
        validator: (v) =>
            v != null && v.length == 10 ? null : 'Enter a 10-digit phone',
      ),
      ElevatedButton(
        onPressed: () {
          if (_formKey.currentState!.validate()) {
            // every validator returned null: register!
            ScaffoldMessenger.of(context).showSnackBar(
              const SnackBar(content: Text('Registered for the fest!')));
          }
        },
        child: const Text('Register'),
      ),
    ],
  ),
)

Quiz

A TextFormField's validator returns null. What does that mean?

  1. The field failed validation with no specific message
  2. The field is VALID: null means no error to report; a returned String is the error message
  3. The validator crashed on a null input
  4. The field was left empty
Show the answer

The field is VALID: null means no error to report; a returned String is the error message

The contract is inverted from instinct and therefore examined forever: the validator's return value IS the error message, so nothing-to-report: null: means the field passed, while any String both fails the field and becomes the red text painted beneath it. validate() then aggregates: true only when every field answered null. Option A reads null with the usual something-went-wrong instinct this question exists to break. Options C and D confuse the INPUT (v, which may be null or empty and is what you test) with the RETURN (your verdict). Null is a clean bill of health here.

Think first

The whole journey, in one screen

Look at the finished form and name where each of its pieces was learned: the Column, the TextFormField's decoration, the keyboardType, the setState-less validate flow, the SnackBar, and the named parameters carrying it all. Then tap for the roll call.

Show the answer

Column: the invisible-widgets lesson. decoration/InputDecoration and keyboardType: the TextField lesson. The button and its rank: buttons-slider. SnackBar: last lesson. Named parameters everywhere: the Dart functions lesson, exactly as promised. And validate() needing no setState: the FORM object holds field state via the key: a fitting last variation on the state theme. One screen, eleven lessons, two languages, one subject: FestConnect Mobile began as Java widgets in Unit 1 and ends here, rebuilt, validated and cross-platform. That arc: patterns surviving platforms: was the real syllabus.

Watch out

Final-topic traps

Inventing a built-in chart widget: name the honest options: pub.dev packages (fl_chart) or composition: pretending Flutter ships BarChart natively loses the mark.

validator logic inverted: returning 'OK' on success paints OK as an error: null passes, String fails, always.

Forgetting the key: validate() reaches the form only through the GlobalKey; a Form without one is decoration.

Validating on every keystroke by default: validate() on submit is the calm default; live validation is opt-in (autovalidateMode), not free.

Theory

The subject closes

Count what you now carry: Android's widget catalogue and its adapter/recycling machinery, a second language learned in a week by transfer, Flutter's widget algebra (visible/invisible, stateless/stateful, controlled by state), and one app built TWICE. When BCA503-02 and real internships hand you React or whatever comes next, walk in asking the same 3 questions: how does it show, how does it change, how does data flow: and you will feel at home by lunch. FestConnect Mobile 2: shipped.

Summary

Key takeaways

  • No built-in charts: pub.dev packages (fl_chart) via pubspec dependencies + flutter pub get, or compose bars from data-driven Containers.
  • Form(key: GlobalKey<FormState>()) wraps TextFormFields: TextField plus a validator.
  • Validator contract: return null = VALID; return a String = invalid, and that String is the painted error.
  • _formKey.currentState!.validate() runs all validators, shows messages, returns true only if all passed.
  • Submit pattern: if (validate()) proceed: no setState needed; the form state lives behind the key.
  • Composition remains the Flutter answer to missing widgets.
  • Memory hook: null passes, Strings scold, and what Flutter lacks, you compose.

Study this properly

This page is the lesson to read. In Gri-Learn the same topic is a graded deck: the self-checks are scored and your weak topics are tracked. Free to start.

Start this topic

Already have an account? Sign in

More from Flutter widget (Constructor, attributes and Properties)

Gri-Learn · syllabus-mapped B.C.A. lessons in English, Hindi and Gujarati

Charts, Flutter Form · Mobile Application Development - 2 (option B) · Gri-Learn