【问题标题】:How to update TextFormField content after onPressed of a prefixIcon with FutureBuilder?如何在使用 FutureBuilder 对 prefixIcon 进行 onPressed 后更新 TextFormField 内容?
【发布时间】:2020-08-13 01:47:36
【问题描述】:

我刚刚开始了一个小的颤振项目。我在 suffixIcon 中有一个 onPressed 属性,并且 onPressed 本身在其中有一个 FutureBuilder 。 future 函数是异步的(我使用的是 geolocator 包),它返回设备的坐标。当用户按下 suffixIcon 但 TextFieldForm 没有被更新时,我想用这些坐标刷新 TextFieldForm 内容,尽管 onPressed 正在工作,因为我在函数中有一个打印来知道它是否正常工作。这是TextFormBuilder的代码,下面是完整的代码。任何帮助将不胜感激

TextFormField(
              controller: myController,
              decoration: InputDecoration(
                prefixIcon: IconButton(
                  icon: Icon(Icons.location_searching),
                  onPressed:(){
                    FutureBuilder<String>(
                      future: _obtenerUbicacion(),
                      builder: (context, snapshot) {
                        if (snapshot.hasData) {
                          myController.text =  snapshot.data;
                        } else if (snapshot.hasError) {
                          return Text("${snapshot.error}");
                        }
                        // By default, show a loading spinner.
                        return CircularProgressIndicator();
                      },
                    );
                  }
                  ,
                ),
                hintText: 'Ingrese su ubicación',
              ),
              validator: (value) {
                if (value.isEmpty) {
                  return 'Por favor ingrese su ubicación';
                }
                return null;
              },
            ),

这是App的完整代码

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'dart:async';
import 'dart:convert';
import 'package:geolocator/geolocator.dart';



void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        theme: ThemeData(primaryColor: Colors.deepOrangeAccent[100]),
        home: Localizador());
  }
}

class Localizador extends StatefulWidget {
  @override
  _LocalizadorState createState() => _LocalizadorState();
}

class _LocalizadorState extends State<Localizador> {
  final _formKey = GlobalKey<FormState>();
  Future<Serviciabilidad> futureServiciabilidad;
  final myController = TextEditingController();

  @override
  Widget _coordenadas() {
    return Padding(
      padding: const EdgeInsets.all(15.0),
      child: Form(
        key: _formKey,
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            TextFormField(
              controller: myController,
              decoration: InputDecoration(
                prefixIcon: IconButton(
                  icon: Icon(Icons.location_searching),
                  onPressed:(){
                    FutureBuilder<String>(
                      future: _obtenerUbicacion(),
                      builder: (context, snapshot) {
                        if (snapshot.hasData) {
                          myController.text =  snapshot.data;
                        } else if (snapshot.hasError) {
                          return Text("${snapshot.error}");
                        }
                        // By default, show a loading spinner.
                        return CircularProgressIndicator();
                      },
                    );
                  }
                  ,
                ),
                hintText: 'Ingrese su ubicación',
              ),
              validator: (value) {
                if (value.isEmpty) {
                  return 'Por favor ingrese su ubicación';
                }
                return null;
              },
            ),
            Padding(
              padding: const EdgeInsets.symmetric(vertical: 16.0),
              child: RaisedButton(
                onPressed: () {
                  // Validate will return true if the form is valid, or false if
                  // the form is invalid.
                  if (_formKey.currentState.validate()) {
                    futureServiciabilidad = obtenerServiciabilidad();
                  }
                },
                child: Text('Enviar'),
              ),
            ),
          ],
        ),
      ),
    );
  }

  Widget build(BuildContext context) {
    return Scaffold(appBar: AppBar(title: Text('MyAPP')), body: _coordenadas());
  }
}

Future<String> _obtenerUbicacion() async {
  Position position = await Geolocator()
      .getCurrentPosition(desiredAccuracy: LocationAccuracy.high);
  //print(position.toString());
  String pos = (position.latitude.toString())+ " " + (position.longitude.toString());
  print(pos);
  return pos;
}

【问题讨论】:

    标签: flutter


    【解决方案1】:

    您可以在下面复制粘贴运行完整代码
    您使用FutureBuilder 的方式不正确。在你的情况下,你可以直接使用async await
    代码sn-p

    prefixIcon: IconButton(
              icon: Icon(Icons.location_searching),
              onPressed: () async {
                var pos = await _obtenerUbicacion();
                setState(() {
                  myController.text = pos;
                });
              },
            ),
    

    工作演示

    完整代码

    import 'package:flutter/cupertino.dart';
    import 'package:flutter/material.dart';
    import 'dart:async';
    import 'dart:convert';
    import 'package:geolocator/geolocator.dart';
    
    void main() => runApp(MyApp());
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
            theme: ThemeData(primaryColor: Colors.deepOrangeAccent[100]),
            home: Localizador());
      }
    }
    
    class Localizador extends StatefulWidget {
      @override
      _LocalizadorState createState() => _LocalizadorState();
    }
    
    class _LocalizadorState extends State<Localizador> {
      final _formKey = GlobalKey<FormState>();
      //Future<Serviciabilidad> futureServiciabilidad;
      final myController = TextEditingController();
    
      @override
      Widget _coordenadas() {
        return Padding(
          padding: const EdgeInsets.all(15.0),
          child: Form(
            key: _formKey,
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: <Widget>[
                TextFormField(
                  controller: myController,
                  decoration: InputDecoration(
                    prefixIcon: IconButton(
                      icon: Icon(Icons.location_searching),
                      onPressed: () async {
                        var pos = await _obtenerUbicacion();
                        setState(() {
                          myController.text = pos;
                        });
                      },
                    ),
                    hintText: 'Ingrese su ubicación',
                  ),
                  validator: (value) {
                    if (value.isEmpty) {
                      return 'Por favor ingrese su ubicación';
                    }
                    return null;
                  },
                ),
                Padding(
                  padding: const EdgeInsets.symmetric(vertical: 16.0),
                  child: RaisedButton(
                    onPressed: () {
                      // Validate will return true if the form is valid, or false if
                      // the form is invalid.
                      if (_formKey.currentState.validate()) {
                        //futureServiciabilidad = obtenerServiciabilidad();
                      }
                    },
                    child: Text('Enviar'),
                  ),
                ),
              ],
            ),
          ),
        );
      }
    
      Widget build(BuildContext context) {
        return Scaffold(appBar: AppBar(title: Text('MyAPP')), body: _coordenadas());
      }
    }
    
    Future<String> _obtenerUbicacion() async {
      Position position = await Geolocator()
          .getCurrentPosition(desiredAccuracy: LocationAccuracy.high);
      //print(position.toString());
      String pos =
          (position.latitude.toString()) + " " + (position.longitude.toString());
      print(pos);
      return pos;
    }
    

    【讨论】:

    • 非常感谢,工作就像一个魅力。只是想知道我的代码是否因为我没有使用 initState 方法而不起作用。从flutter.dev/docs/cookbook/networking/… 在我的代码中获得了 FutureBuilder 实现,但没有使用 de initState
    • 需要重现,您能否将重现代码发布到新问题?谢谢。
    【解决方案2】:

    使用setState 应该可以完成这项工作

    if(snapshot.hasData) {
        setState(() => myController.text =  snapshot.data);
    }
    

    【讨论】:

      猜你喜欢
      • 2020-06-05
      • 2023-03-17
      • 2021-10-21
      • 2020-11-11
      • 1970-01-01
      • 2021-04-17
      • 1970-01-01
      • 2019-03-18
      • 1970-01-01
      相关资源
      最近更新 更多