CupertinoDatePicker导致颤动的结果在日期选择器小部件执行之前被打印

时间:2019-08-31 22:43:04

标签: flutter datepicker

CupertinoDatePicker之后编写的代码在它之前执行。

我正在使用CupertinoDatePicker,并且遇到了这个问题。下面的代码是我创建的一个示例,用于询问问题并从Flutter专家那里找到解决方案。解决问题的任何帮助将不胜感激。

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

DateTime selectedDate = DateTime.now();

void main() => runApp(MyApp()); // Run class MyApp

// Context is where the widget is located in the app
class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Material',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      debugShowCheckedModeBanner: false,
      home: HomePage(),
    );
  }
}

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Cupertinio Datepicker'),
        actions: <Widget>[
          IconButton(
            icon: Icon(CupertinoIcons.add),
            tooltip: 'Add Date',
            onPressed: () {
              print('1. Date Before : ${selectedDate} ');
              setState(() {
                _showModalBottomSheet(context);
              });
              print('3. Date After : ${selectedDate} ');
              // Problem: I have to call another page here with the changed date but date remains same and SecondPage is called before _showModalBottomSheet
              //navigateToSecondPage(context, selectedDate);


            },
          ),
        ],
      ),
    );
  }
}

Widget _showModalBottomSheet(context){
  showModalBottomSheet(
      context: context,
      builder: (BuildContext context){
        return Container(
          height: MediaQuery.of(context).copyWith().size.height / 3,
          child: _showCuperTinoDatePicker(),
        );
      }
  );
}


Widget _showCuperTinoDatePicker() {
  return CupertinoDatePicker(
    initialDateTime: selectedDate,
    onDateTimeChanged: (DateTime newdate) {
      selectedDate = newdate;
      print('2. onDateTimeChanged : ${selectedDate}' );
    },
    minimumYear: 2010,
    maximumYear: 2050,
    mode: CupertinoDatePickerMode.date,
  );
}

预期结果:

I/flutter (13818): 1. Date Before : 2019-08-29 00:00:00.000 
I/flutter (13818): 2. on Date Time Changed : 2019-08-30 00:00:00.000
I/flutter (13818): 3. Date After : 2019-08-30 00:00:00.000 
// go to next page

实际结果:这是打印语句的输出

1. Date Before : 2019-08-29  [output of print statement]
3. Date After : 2019-08-29 [output of print statement]
// goes to next page, After closing the page, it comes back to first page and displays date picker
2. print 'on Date Time Changed' : 2019-08-30 00:00:00.000
2. print  'on Date Time Changed' : 2019-08-31 00:00:00.000

1 个答案:

答案 0 :(得分:0)

问题源于_showModalBottomSheet(),因为您在其中使用了showModalBottomSheet()并返回了Future,而flutter发现了一个异步函数,它将继续执行其他函数并在可用时显示结果。

您的问题的一种解决方案是使用Button移至下一个屏幕,因为CupertinoDatePicker没有处理选择的功能,只有onDateTimeChanged

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

DateTime selectedDate = DateTime.now();

void main() => runApp(MyApp()); // Run class MyApp

// Context is where the widget is located in the app
class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Material',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      debugShowCheckedModeBanner: false,
      home: HomePage(),
    );
  }
}

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Cupertinio Datepicker'),
        actions: <Widget>[
          IconButton(
            icon: Icon(CupertinoIcons.add),
            tooltip: 'Add Date',
            onPressed: () {
              print('1. Date Before : $selectedDate ');
              setState(() {
                _showModalBottomSheet(context);
              });
            },
          ),
        ],
      ),
      body: Center(
        child: RaisedButton(
          child: Text('Second Page'),
            onPressed: (){
              //navigateToSecondPage(context, selectedDate);
            }
        ),
      ),
    );
  }
}

Widget _showModalBottomSheet(context){
  showModalBottomSheet(
      context: context,
      builder: (BuildContext context){
        return Container(
          height: MediaQuery.of(context).copyWith().size.height / 3,
          child: _showCupertinoDatePicker(),
        );
      }
  );
}


Widget _showCupertinoDatePicker() {
  return CupertinoDatePicker(
    initialDateTime: selectedDate,
    onDateTimeChanged: (DateTime newDate) {
      selectedDate = newDate;
      print('2. onDateTimeChanged : $selectedDate' );
    },
    minimumYear: 2010,
    maximumYear: 2050,
    mode: CupertinoDatePickerMode.date,
  );
}