HELP ! Problème avec textformfield et controller

Bonjour,

Voila ce que je veux faire me semble simple mais flutter galère comme jamais. J’ai un formulaire avec des champs que je préremplis avec des valeurs venant d’un appel http (php/mysql), j’utilise un futurebuilder pour ça et donc je remplis les valeurs des champ.

Si je tente de modifier une valeur d’un des champs le clavier s’ouvre je change la valeur et quand je sors il me réinitialise la valeur du champ avec la valeur de départ qui était vide donc il me vide tout…

Je pense qu’il rebuild le widget et remplit les champs avec les anciennes valeurs et efface donc mes nouvelles valeurs.

Est-ce que quelqu’un a déja rencontré ce problème ? Je suppose que oui car c’est très basique mais rien sur internet pour expliquer comment corriger ce genre de souci.

Je suis à 2 doigts d’arrêter flutter et dart car vraiment trop compliqué, tout ce bordel pour faire un truc hyper simple ça me fatigue sévère

Il ne faut un bout de ton code pour qu’on puisse t’aider. Aussi les variables ne doivent pas être déclaré après le build context

import ‹ package:flutter/material.dart ›;

import ‹ dart:convert ›;

import ‹ package:http/http.dart › as http;

import ‹ dart:async ›;

import ‹ menu_member.dart ›;

import ‹ globals.dart › as globals;

import ‹ appbar_draw.dart ›;

import ‹ package:awesome_dialog/awesome_dialog.dart ›;

import ‹ package:easy_localization/easy_localization.dart ›;

class Affiche_Profil extends StatefulWidget {

@override

_Affiche_Profil_State createState() {

return _Affiche_Profil_State();

}

}

// Create a corresponding State class.

// This class holds data related to the form.

class _Affiche_Profil_State extends State<Affiche_Profil> {

@override

final _formKey = GlobalKey();

var _CoinbaseController = TextEditingController();

var _FaucetPayController = TextEditingController();

Future profil;

Future Display_Profil () async {

// SERVER LOGIN API URL

var url = 'https://www.bemyfaucet.com/app/info_profil.php';

var data = {

  'id_membre': globals.id_membre,

};

var data_encode = jsonEncode(data);

// Starting Web API Call.

var response = await http.post(url,body: data_encode,headers: {'content-type': 'application/json','accept': 'application/json','authorization': globals.token});

// Getting Server response into variable.

var jsondata = json.decode(response.body);

print(response.body);

user profile=user(jsondata["mail"],jsondata["balance"],jsondata["coinbase"],jsondata["faucetpay"]);

return profile;

}

void initState() {

super.initState();

profil = Display_Profil();

}

@override

Widget build(BuildContext context) {

print('build');

return Stack(

    children: <Widget>[

      Positioned.fill(

        child: Image( image: AssetImage('assets/img/background.jpg'), fit : BoxFit.fill, ),

      ),

      Scaffold(

        resizeToAvoidBottomInset: false,   //new line

          appBar: drawappbar(true),

          backgroundColor: Colors.transparent,

          drawer: new DrawerOnly(className: Affiche_Profil()),

          body:

          Container(

              height: MediaQuery

                  .of(context)

                  .size

                  .height,

              width: MediaQuery

                  .of(context)

                  .size

                  .width,

              margin: const EdgeInsets.only(top: 10.0,bottom:10,right:10,left:10),

              decoration: BoxDecoration(

                color: Color(0xddb84a).withOpacity(0.9),

                border: Border.all(

                  color: Colors.white,

                  width: 3,

                ),

                borderRadius: BorderRadius.circular(25),

              ),

              child:

                FutureBuilder(

                    future: profil,

                    builder: (BuildContext context, AsyncSnapshot snapshot) {

                      switch (snapshot.connectionState) {

                        case ConnectionState.waiting:

                          return new Center(

                            child: new CircularProgressIndicator(),);

                        default:

                          if (snapshot.hasError) {

                            return new Center(

                              child: new Text('Error: ${snapshot.error}'),);

                          }

                          else {

                            user values = snapshot.data;

                            if (snapshot.hasData==false) {

                              return Container(

                                  child: Center(

                                      child: Text("No_Data".tr(),style: TextStyle(color: Colors.white))

                                  )

                              );

                            }

                            else {

                              globals.bmf=num.parse(values.bmf);

                              _CoinbaseController.text=values.coinbase;

                              _FaucetPayController.text=values.faucetpay;

                              return

                                Form(

                                  key: _formKey,

                                    autovalidateMode: AutovalidateMode.always,

                                  child:

                                ListView(

                                    padding: EdgeInsets.only(left: 24.0, right: 24.0),

                                  children: <Widget>[

                                    Center(

                                      child: Container(

                                          margin: const EdgeInsets.only(top: 20.0),

                                          child: Text("Vos_Infos".tr(),textAlign: TextAlign.center,style: TextStyle(fontSize: 30.0,color: Colors.white))

                                      ),

                                    ),

                                    Padding(

                                    padding: const EdgeInsets.only(top:30.0),

                                    child:

                                    TextFormField(

                                      readOnly: true,

                                      obscureText: false,

                                      initialValue: values.mail,

                                      decoration: InputDecoration(

                                        border: OutlineInputBorder(

                                            borderRadius: BorderRadius.circular(32.0)

                                        ),

                                        fillColor: Colors.white, filled: true,

                                        icon: Icon(Icons.email,color: Colors.white),

                                        hintText: "Enter_Email".tr(),

                                        contentPadding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0),

                                        hintStyle: TextStyle(color: Colors.grey[500],fontSize: 10),

                                      ),

                                    ),

                                    ),

                                    Padding(

                                      padding: const EdgeInsets.only(top:30.0),

                                      child:

                                      TextFormField(

                                        autofocus: true,

                                        controller: _CoinbaseController,

                                        obscureText: false,

                                        decoration: InputDecoration(

                                          border: OutlineInputBorder(

                                              borderRadius: BorderRadius.circular(32.0)

                                          ),

                                          fillColor: Colors.white, filled: true,

                                          icon: Icon(Icons.email,color: Colors.white),

                                          hintText: "Enter_Coinbase".tr(),

                                          contentPadding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0),

                                          hintStyle: TextStyle(color: Colors.grey[500],fontSize: 10),

                                        ),

                                      ),

                                    ),

                                    Padding(

                                      padding: const EdgeInsets.only(top:30.0),

                                      child:

                                      TextFormField(

                                        controller: _FaucetPayController,

                                        obscureText: false,

                                        decoration: InputDecoration(

                                          border: OutlineInputBorder(

                                              borderRadius: BorderRadius.circular(32.0)

                                          ),

                                          fillColor: Colors.white, filled: true,

                                          icon: Icon(Icons.email,color: Colors.white),

                                          hintText: "Enter_FaucetPay".tr(),

                                          contentPadding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0),

                                          hintStyle: TextStyle(color: Colors.grey[500],fontSize: 10),

                                        ),

                                      ),

                                    ),

                                    Padding(

                                    padding: const EdgeInsets.only(top:30.0),

                                    child :

                                    Center(

                                      child: Container(

                                        width:MediaQuery.of(context).size.width,

                                        height:45,

                                        child: ElevatedButton(

                                          style : ElevatedButton.styleFrom(

                                              primary: Colors.green,

                                              textStyle: TextStyle(

                                                  fontSize: 20,

                                                  color: Colors.white,

                                                  fontWeight: FontWeight.bold)),

                                          child : Text('Modifier'.tr()),

                                          onPressed: () {

                                            // Validate returns true if the form is valid, or false

                                            // otherwise.

                                            if (_formKey.currentState.validate()) {

                                              _formKey.currentState.save();

                                              ModifyInfos();

                                            }

                                            else {

                                              return null;

                                            }

                                          },

                                        ),

                                      ),

                                    ),

                                    ),//    <-- label

                                  ]

                              )

                              );

                            }

                          }

                      }

                    }

                )

              )

          )

    ]

);

}

Future ModifyInfos() async{

// Getting value from Controller

var url = 'https://www.bemyfaucet.com/app/modify_profil.php';

// Store all data with Param Name.

var data = {'id_membre':globals.id_membre,'coinbase':_CoinbaseController.text,'faucetpay':_FaucetPayController.text,'lang': context.locale.toString()};

var data_encode=jsonEncode(data);

// Starting Web API Call.

var response = await http.post(url, body: data_encode,headers: {'content-type': 'application/json','accept': 'application/json','authorization': globals.token});

print(response.body);

Map <String,dynamic> map = json.decode(response.body);

if(map["status"] == 1)

{

  AwesomeDialog(context: context,

      useRootNavigator: true,

      dialogType: DialogType.SUCCES,

      animType: AnimType.BOTTOMSLIDE,

      tittle: 'Modification_Profil'.tr(),

      desc: map["libelle"],

      btnOkOnPress: () {

        setState(() {

          profil = Display_Profil();

          if (map["solde_bmf"]!="") {

            globals.bmf=num.parse(map["solde_bmf"]);

          }

        });

      }).show();

}else{

  // If Email or Password did not Matched.

  // Showing Alert Dialog with Response JSON Message.

  AwesomeDialog(context: context,

      useRootNavigator: true,

      dialogType: DialogType.INFO,

      animType: AnimType.BOTTOMSLIDE,

      tittle: 'Information_No_Change'.tr(),

      desc: map["libelle"],

      btnOkOnPress: () {

        setState(() {

          profil = Display_Profil();

          if (map["solde_bmf"]!="") {

            globals.bmf=num.parse(map["solde_bmf"]);

          }

        });

      }).show();

}

}

}

class user {

final String mail;

final String bmf;

final String coinbase;

final String faucetpay;

const user(this.mail,this.bmf,this.coinbase,this.faucetpay);

}

d’abord tu utilises mal tes controllers et textFormField. A ets controller tu ne dois pas faire _FaucetPayController.text=values.faucetpay;

Aussi avec le textFormField, il faut utiliser le paramètre onSaved

_FaucetPayController.text=values.faucetpay;

C’est fait pour initialiser la valeur du textformfield FAUCETPAY avec comme valeur celle qui vient de la base de données

2 problemes.
tu es parti à l’envers. on fait d’abord une interface hyper light avec des valeurs de base fixées pour tester le comportement effectif des composants sans etre noyé sous une tonne de code qui ne servent qu’à la decoration.
revient au code minimal fonctionnel. mets de cote, les requetes serveur, les decorations, les centrages et autres inutiles, seulement le code fonctionnel.
ensuite, deuxieme erreur. dart n’est pas compliqué, il nécessite une autre approche que celles que tu connaissais…et donc de bien lire les docs. et s’inspirer d’exemples simples qui fonctionnent,
j’ai fait pareil, un login password, .
masi je valide individuellement chaque saisie dans chaque champs pour etre sur de ce qui se passe vraiment… avec initialvalue, validator, on changed, sur chaque champ.
essaye avec juste un champs, code hyper minimaliste, et ensuite, rajoute des champs.
et teste la validation de l’ensemble…
et quand ca marchera , la tu remets effectivement des parties de requetes serveur…et les decorations…
mais pas tout d’un coup… sinon, à la moindre merde tu sauras pas vraiment d’ou ca vient…
tu peux pas esperer poser un monolithe et que ca marche comme ca. sans meme comprendre ce que ca fait vraimetn et pourquoi.
la base de l’info c’est de diviser un probleme complexe en de minuscules problemes reglables et de les traiter un par un. tu l’as oublié.
au pire tu peux te raporter sur ca…Flutter Login/Sign-up Screen - Example
mais surtout, va ici. ca devrait te sortir du trou. TextFormField Flutter Examples | Handling User Input In Flutter pour revenir à la base du fonctionnement d’un TextFormField

Merci à toi j’ai trouvé le souci avec l’aide de benoni. Mon application fonctionne pas trop mal, il reste quelques petites choses pour lesquelles je galère encore pas mal. La gestion des tokens pour la sécurité de l’application et la gestion de l’espace membre une fois connecté pour passer les identifiants à travers l’application et déconnecter si le widget n’a pas l’autorisation