简体   繁体   中英

Flutter Dropdownbutton state is not updated - Everything else works fine

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

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.

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(),
),

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM