0

I have created a stateful customer information form and the there are two widgets that use the state - two list tiles with radio buttons and a drop down button. The list tiles respond to the code and updates their states and saves the data to the variable as expected.

But the drop down button only saves the value in the assigned variable, but does not display the new value instead of the hint.

I have followed sample code but as I'm new to Flutter I can't find where the mishap might be. Thank you for any help!

The code is as follows; please note that some of the label texts are in my native language and it wouldn't affect code readability. The code in question is in bold (**).

import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;

class CustomerForm extends StatefulWidget {
  const CustomerForm({Key key}) : super(key: key);
  @override
  CustomerFormState createState() {
    return CustomerFormState();
  }}


class CustomerFormState extends State<CustomerForm> {
  final formKey = GlobalKey<FormState>();

  String _name = '';
  String _age = '';
  String _nic = '';
  String _sex = '';
  String _telephone = '';
  String _address = '';
  String _email = '';
  String _inquiry = '';
**String _branch = '';**




  @override
    Widget build(BuildContext context) => Scaffold(
      resizeToAvoidBottomInset : false,
     appBar: AppBar(
      title: Text('ඔබේ තොරතුරු පහත පුරවන්න',
      style: TextStyle(
      fontSize: (20.0),),),
      centerTitle: true,
      backgroundColor: Colors.cyan,
      shadowColor: Colors.tealAccent[50] ),
      body:SingleChildScrollView(
        child: Form(
            key: formKey,
              child: Column(children:[
                Padding(
                  padding: const EdgeInsets.fromLTRB(10, 0, 10, 0),
                  child: TextFormField(
                      autofocus: true,
                      decoration: InputDecoration(labelText: 'නම'),
                      validator: (value) {
                        if (value.isEmpty) {
                          return 'මෙම තොරතුරු අවශ්‍යයි';}
                        else if(value.length < 4) {
                          return 'ඔබ යෙදූ නම කෙටි වැඩි ය.';}
                        return null;},
                      onSaved: (value) => _name = value),
                ),
                Padding(
                  padding: const EdgeInsets.fromLTRB(10, 0, 10, 0),
                  child: TextFormField(
                      decoration: InputDecoration(labelText: 'වයස (අවු. 18ට වැඩි විය යුතුයි)'),
                      validator: (value) {
                        if (value.isEmpty) {
                          return 'මෙම තොරතුරු අවශ්‍යයි';}
                        else if (int.parse(value)<18) {
                          return 'වයස අවුරුදු 18ට වැඩි විය යුතුයි';}
                        else if (int.parse(value) > 99) {
                          return 'සැබෑ වයසක් ඇතුළත් කරන්න';}
                        else {
                          return null;}},
                      onSaved: (value) => _age = value),
                ),
                Padding(
                  padding: const EdgeInsets.fromLTRB(10, 0, 10, 0),
                  child: TextFormField(
                      decoration: InputDecoration(
                          labelText: 'ජාතික හැඳුනුම්පත් අංකය'),
                      validator: (value) {
                        if (value.isEmpty) {
                          return 'මෙම තොරතුරු අවශ්‍යයි';}
                        //TODO finish regexp
                        String p =  r'(^[0-9]v|V|x|X$)';
                        RegExp regExp = new RegExp(p);
                        if (regExp.hasMatch(p) && value.length == 10 ) {
                          return null;}
                        else
                          return 'ඇතුළත් කල ජාතික හැඳුනුම්පත් අංකය වලංගු නොවේ';},
                      onSaved: (value) => _nic = value),
                ),
                Padding(
                  padding: const EdgeInsets.fromLTRB(10, 10, 10, 0),
                  child: Row(
                    children:[
                      SizedBox(
                        width: 100.0,
                        child: Text('ස්ත්‍රී / පුරුෂ භාවය :',
                          style: TextStyle(
                              color: Colors.black54,
                              fontSize: 16.0),),
                      ),
                      Expanded(
                        child: ListTile(
                          leading:Radio<String>(
                            value:'male',
                            groupValue: _sex,
                            activeColor: Colors.teal,
                            onChanged: (value) {
                              setState(() {_sex = value;});},),
                          title: const Text('පුරුෂ'),),
                      ),
                      Expanded(
                        child:  ListTile(
                        leading:Radio<String>(
                          value:'female',
                          groupValue: _sex,
                          activeColor: Colors.teal,
                          onChanged: (value) {setState(() {_sex = value;});},),
                        title: const Text('ස්ත්‍රී'),),),
                    ],
                  ),
                ),

                Padding(
                  padding: const EdgeInsets.fromLTRB(10, 0, 10, 0),
                  child: TextFormField(
                      decoration: InputDecoration(
                          labelText: 'දුරකථන අංකය'),
                      validator: (value) {
                        String pattern = r'^[0-9]{10}$';
                        RegExp regExp = new RegExp(pattern);
                        if (value.length == 0) {
                          return 'මෙම තොරතුරු අවශ්‍යයි';}
                        else if (!regExp.hasMatch(value)) {
                          return 'ඉලක්කම් 10ක් සහිත 0න් ආරම්භ වන වලංගු දුරකථන අංකයක් \n ඇතුළත් කරන්න';}
                        else {return null;}},
                      onSaved: (value) => _telephone = value),
                ),
                Padding(
                  padding: const EdgeInsets.fromLTRB(10, 0, 10, 0),
                  child: TextFormField(
                      decoration: InputDecoration(
                          labelText: 'ලිපිනය'),
                      validator: (value) {
                        if (value.isEmpty) {
                          return 'මෙම තොරතුරු අවශ්‍යයි';}
                        else {return null;}},
                      onSaved: (value) => _address = value),
                ),
                Padding(
                  padding: const EdgeInsets.fromLTRB(10, 0, 10, 0),
                  child: TextFormField(
                      decoration: InputDecoration(
                          labelText: 'විද්‍යුත් ලිපිනය (තිබේනම්)'),
                      keyboardType: TextInputType.emailAddress,
                      validator: (value) {
                        String p = "[a-zA-Z0-9\+\.\_\%\-\+]{1,256}" +
                            "\\@" + "[a-zA-Z0-9][a-zA-Z0-9\\-]{0,64}" + "(" + "\\." +
                            "[a-zA-Z0-9][a-zA-Z0-9\\-]{0,25}" + ")+";
                        RegExp regExp = new RegExp(p);
                        if (value.isNotEmpty && !regExp.hasMatch(value)) {
                          return 'ඇතුළත් කල විද්‍යුත් ලිපිනය වලංගු නොවේ';}
                        else
                          return null;},
                      onSaved: (value) => _email = value)
                ),
                Padding(
                  padding: const EdgeInsets.fromLTRB(10, 0, 10, 0),
                  child: TextFormField(
                      decoration: InputDecoration(
                          labelText: 'අමතර කරුණු / විමසීම්'),
                      onSaved: (value) => _inquiry = value),
                ),

                Padding(padding: const EdgeInsets.fromLTRB(0, 0, 0, 25),),

                **DropdownButton<String>(
                  hint:Text ('ඔබට ළඟම බැංකු ශාඛාව මෙතනින් තෝරන්න.'),
                  icon: Icon(Icons.arrow_downward),
                  iconSize: 24, elevation: 16, style: TextStyle(color: Colors.teal),
                  underline: Container(height: 2, color: Colors.teal,),
                  onChanged: (String value) {setState(() {_branch = value;});},
                  items: <String>['Matara', 'Colombo','Galle'].map<DropdownMenuItem<String>>((String value){
                    return DropdownMenuItem<String>(value:value,
                        child: Text(value, style: TextStyle(fontSize: 20.0), textAlign: TextAlign.center,));}).toList(),),**
                Padding(padding: const EdgeInsets.fromLTRB(0, 0, 0, 45),),
                ElevatedButton (
                  onPressed: () {
                    if (_sex.isEmpty){
                      final message = 'ස්ත්‍රි පුරුෂ බව ඇතුළත් කරන්න';
                      final snackBar =  SnackBar(
                        content: Text(message),
                        backgroundColor:Colors.redAccent,
                        duration: Duration(milliseconds: 3000),);
                      ScaffoldMessenger.of(context).showSnackBar(snackBar);}
                    else
                    if (formKey.currentState.validate()){
                      formKey.currentState.save();
                      final message = '$_name, විමසීම සාර්ථකයි.';
                      final snackBar =  SnackBar(
                        content: Text(message),
                        backgroundColor:Colors.blue,
                        duration: Duration(milliseconds: 3000),);
                      ScaffoldMessenger.of(context).showSnackBar(snackBar);
                      return http.post(
                        Uri.parse('http://10.0.2.2:5000/api/userdata'),
                        headers: <String, String>{
                          'Content-Type': 'application/json; charset=UTF-8',},
                          body: jsonEncode(<String, String>{
                            'name': _name,
                            'age': _age,
                            'NIC': _nic,
                            'sex': _sex,
                            'tel': _telephone,
                            'addr': _address,
                            'email': _email,
                            'inquiry': _inquiry,
                            'branch': _branch
                          })
                      );
                    }},
                  child: Text('ඔබේ විමසීම මෙතැනින් අප වෙත යොමුකරන්න.'),
                )
               ]
              ),
            ),
      ));}

I tried assigining _branch with 'value' of the button and reversing the names, it did not work. Then When I assigned _branch to the value attribute of teh drop down button it seemed to work but an error came on when the screen was reloaded

  • I recommend translating all native language code into english. That makes it easier for everybody reading through it. It should only cost you a couple of seconds anyways. – TheUltimateOptimist Mar 31 '22 at 11:55

2 Answers2

0

This might help you out:


DropdownButton(
  hint: Text('ඔබට ළඟම බැංකු ශාඛාව මෙතනින් තෝරන්න.'),
  icon: Icon(Icons.arrow_downward),
  iconSize: 24,
  value: _branch,
  elevation: 16,
  style: TextStyle(color: Colors.teal),
  underline: Container(
    height: 2,
    color: Colors.teal,
  ),
  onChanged: (value) async {
    setState(() {
      _branch = value;
      debugPrint(value);
    });
  },
  items: <String>['Matara', 'Colombo', 'Galle']
      .map<DropdownMenuItem<String>>((String value) {
    return DropdownMenuItem<String>(
        value: value,
        child: Text(
          value,
          style: TextStyle(fontSize: 20.0),
          textAlign: TextAlign.center,
        ));
  }).toList(),
),

You'vent declared the "value" inside the DropdownButton widget, if you want your text to appear soon as you choose an option from the Dropdown you must use it like this. I guess if there's a problem after you change it maybe it's not related to dropdownbutton.

Marco
  • 1
  • 3
  • Hi, when I use value: attribute, it spits out an error as follows: There should be exactly one item with [DropdownButton]'s value: . Either zero or 2 or more [DropdownMenuItem]s were detected with the same value 'package:flutter/src/material/dropdown.dart': – Akila Ariyathilaka Apr 07 '22 at 07:26
  • May you share that piece of code once again? What changes have you made? – Marco Apr 07 '22 at 14:06
  • I have replaced the entire DropdownButton in the code in the question with your solution code. Then the error comes. But if I remove "value: _branch," from there it works, and debug console print comes as well. – Akila Ariyathilaka Apr 08 '22 at 01:25
  • To present a initial value in DropdownButton you must use the "_branh" assigned to the propertie "value". It all runs perfectly to me, I guess I'm not getting what you need. If you want you can share the full code so I can replicate the error to understand the problem. – Marco Apr 11 '22 at 16:22
0

This could be very helpful

final List<String> _items = ['Matara', 'Colombo','Galle'];
late String _branch = _items[0]; //Default selected value


DropdownButton(
    hint: Text('ඔබට ළඟම බැංකු ශාඛාව මෙතනින් තෝරන්න.'),
    icon: Icon(Icons.arrow_downward),
    iconSize: 24,
    value: _branch,
    elevation: 16,
    style: TextStyle(color: Colors.teal),
    underline: Container(
       height: 2,
       color: Colors.teal,
    ),
    onChanged: (value) async {
       setState(() {
           _branch = value;
           debugPrint(value);
       });
    },
    items:_items.map<DropdownMenuItem<String>>((String value) {
    return DropdownMenuItem<String>(
             value: value,
             child: Text(
                 value,
                 style: TextStyle(fontSize: 20.0),
                 textAlign: TextAlign.center,
               )
            );
    }).toList(),
),
saytoonz
  • 186
  • 6
  • Error ======================================================= The following assertion was thrown building CustomerForm(dirty, state: CustomerFormState#fe956): There should be exactly one item with [DropdownButton]'s value: . Either zero or 2 or more [DropdownMenuItem]s were detected with the same value 'package:flutter/src/material/dropdown.dart': Failed assertion: line 894 pos 15: 'items == null || items.isEmpty || value == null || items.where((DropdownMenuItem item) { return item.value == value; }).length == 1' – Akila Ariyathilaka Apr 07 '22 at 07:15