如何在不使用 Flutter 中的任何其他 hack 的情况下将选择的日期从 showDatePicker() 传递到 textField?

How to pass the picked date from showDatePicker() to a textField without using any other hacks in Flutter?

我想从 textField 小部件内的 calendarIcon(使用 showDatePicker() 实现)中选择一个日期并将其提供给 textField。但它不起作用。我想使用 Provider 管理 UI 状态。我在下面显示我的代码。我做错了吗?或者还有其他方法吗?

我尝试了以下方法:

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

class SignUp extends StatelessWidget {
  Widget build(BuildContext context) {
    final validator = Provider.of<SignUpController>(context);
    return Scaffold(
      appBar: AppBar(
        title: Text("Demo FormValidation Provider"),
      ),
      body: Padding(
          padding: EdgeInsets.all(8.0),
          child: ListView(children: <Widget>[
            TextField(
              controller: TextEditingController()..text = "Enter DOB",
              onChanged: (text) => {validator.date},
              decoration: InputDecoration(
                suffixIcon: IconButton(
                  icon: Icon(Icons.calendar_today_sharp),
                  onPressed: () => {validator.showCalender(context)},
                ),
              ),
            )
          ])),
    );
  }
}

class SignUpController with ChangeNotifier {
  Future<DateTime> showCalender(BuildContext context) {
    notifyListeners();
    return showDatePicker(
      context: context,
      initialDate: DateTime.now(),
      firstDate: DateTime(2000),
      lastDate: DateTime.now(),
    );
  }

  var date = DateTime.now().toString().split(' ')[0];
  void getDate(BuildContext context) async {
    var dateL = await showCalender(context);
    date = (dateL.toLocal()).toString().split(' ')[0];
    notifyListeners();
  }
}


定义一个 TextEditingController,然后像这样将数据传递给它:

//define
TextEditingController text = TextEditingController(text:'');

//pass data
text = TextEditingController(text:data);

首先,让你的小部件有状态,然后添加它会监听的 didChangeDependencies() 方法。

  void didChangeDependencies() {
    super.didChangeDependencies();
    setState(() {
      getImages();
    });
  }

  
  Future getImages() async {
    //get ur data here from provider
  }

已解决!!!

终于做到了..

参考:For more information refer to this medium.com article by Pinkesh Darji

解决方案

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

// UI class
class SignUp extends StatelessWidget {
  Widget build(BuildContext context) {
    final validator = Provider.of<SignUpController>(context);

    return Scaffold(
      appBar: AppBar(
        title: Text("Demo FormValidation Provider"),
      ),
      body: Padding(
        padding: EdgeInsets.all(8.0),
        child: ListView(
          children: <Widget>[
            TextField(
              controller: TextEditingController(
                  text: validator.selectedDate == null
                      ? "Enter Date Of Birth"
                      : "${validator.selectedDate}".split(' ')[0]),
              onChanged: (String value) {
                validator.changeDOB(value);
              },
              decoration: InputDecoration(
                labelText: "yyyy-mm-dd",
                errorText: validator.dob.error,
                suffixIcon: IconButton(
                  icon: Icon(Icons.calendar_today_sharp),
                  onPressed: () => {validator.selectDate(context)},
                ),
              ),
            ),
            SizedBox(
              height: 10,
            ),
            ElevatedButton(
              // The ElevatedButton inherits the color of the app.
              child: Text("Submit"),
              style: ElevatedButton.styleFrom(
                padding: EdgeInsets.all(10),
                textStyle: TextStyle(
                  fontSize: 20,
                ),
              ),
              onPressed: () {
                print("Date: " + "${validator.selectedDate}".split(' ')[0]);
              },
            ),
          ],
        ),
      ),
    );
  }
}

// Controller Class
class SignUpController with ChangeNotifier {
  ValidationItem _dob = ValidationItem(null, null);

  // Getters
  ValidationItem get dob => _dob;
  // making the showDatePicker method
  DateTime selectedDate;
  selectDate(BuildContext context) async {
    DateTime picked = await showDatePicker(
      context: context,
      initialDate: DateTime.now(),
      firstDate: DateTime(2000),
      lastDate: DateTime.now(),
      // initialDatePickerMode: DatePickerMode.year,
    );
    if (picked != null && picked != selectedDate) {
      selectedDate = picked;
    }
    notifyListeners();
  }

  // Setters
  void changeDOB(String value) {
    try {
      // converting the DateTime data type into a String data type and only getting the
      // Date(discarding the time)
      value = selectedDate.toString().split(' ')[0];
      _dob = ValidationItem(value, null);
    } catch (error) {
      _dob = ValidationItem(null, "Use Correct Format");
    }
    notifyListeners();
  }
}

// Model Class
class ValidationItem {
  final String value;
  final String error;

  ValidationItem(this.value, this.error);
}


注意01: 你可以为提供者使用多个消费者(或者不可以??)

注意02: 以上答案不会使初始文本(TextEditingController) 可编辑。它可以使用 EditableText 小部件或其他一些功能来实现。试试吧。