使用FutureBuilder onPressed prefixIcon后如何更新TextFormField内容?

时间:2020-08-13 01:47:36

标签: flutter

我刚刚开始了一个小型的flutter项目。我在suffixIcon里面有一个onPressed属性,而onPressed本身里面有一个FutureBuilder。未来的函数是异步的(我正在使用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;
              },
            ),

这是应用程序的完整代码

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;
}

2 个答案:

答案 0 :(得分:1)

您可以在下面复制粘贴运行完整代码
您使用FutureBuilder的方式不正确。您可以直接使用async await
代码段

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

工作演示

enter image description here

完整代码

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;
}

答案 1 :(得分:0)

使用setState应该可以完成工作

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