如何从一个类屏幕获取值到另一个类并在颤动中填充这些值?

Posted

技术标签:

【中文标题】如何从一个类屏幕获取值到另一个类并在颤动中填充这些值?【英文标题】:How to get values from one class screen to another class and populate those values in flutter? 【发布时间】:2021-12-09 19:32:03 【问题描述】:

我有一个主类和 TimePickerScreen 类,我试图将值从 TimePickerScreen 类获取到 Main 类 以填充这些值,我用 GestureDetector 包装了 FromTo 文本以在 bottomSheet 中调用 TimePickerScreen 类,然后选择时间并点击保存按钮值应该代替 select Time 填充,但我不知道如何获取这些值,下面我粘贴了我的代码和屏幕截图,谁能帮助我,在此先感谢。 主类

import 'package:flutter/material.dart';
import 'package:single_selection_horizontal/timedatepicker_screen.dart';

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

class MyApp extends StatelessWidget 

  @override
  Widget build(BuildContext context) 
    return MaterialApp(
      title: "custom time picker horizontal",
      home: SelectTimeDate(),
    );
  


class SelectTimeDate extends StatefulWidget 

  @override
  _SelectTimeDateState createState() => _SelectTimeDateState();


class _SelectTimeDateState extends State<SelectTimeDate> 
  String pfromTime ='';
  String ptoTime ='';
  //String fromDate='';
  //String toDate='';
  @override
  Widget build(BuildContext context) 
    return Scaffold(
      appBar: AppBar(
        title: Text('custom time picker horizontal'),
      ),
      body: Center(
        child: Container(
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.center,
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              GestureDetector(
                onTap: pickerBottomSheet,
                child: Container(
                  child: Column(
                    children: [
                      Text(" From ",style: TextStyle(fontSize: 20,color: Colors.black),),
                      Text(
                        pfromTime==''
                        ? "Select Time"
                        : "$pfromTime",style: TextStyle(fontSize: 15,color: Colors.grey),),
                    ],
                  ),
                ),
              ),
              SizedBox(height: 10,),
              GestureDetector(
                onTap: pickerBottomSheet,
                child: Container(
                  child: Column(
                    children: [
                      Text(" To ",style: TextStyle(fontSize: 20,color: Colors.black),),
                      Text(
                        ptoTime==''
                        ? "Select Time"
                        : "$ptoTime",style: TextStyle(fontSize: 15,color: Colors.grey),),
                    ],
                  ),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  

  pickerBottomSheet()
    showModalBottomSheet(
        context: context,
        isScrollControlled: true,
        isDismissible: true,
        builder: (BuildContext context)
          return TimePickerScreen();
        
        );
  

TimePickerScreen

import 'package:flutter/material.dart';

class TimePickerScreen extends StatefulWidget 

  @override
  _TimePickerScreenState createState() => _TimePickerScreenState();


class _TimePickerScreenState extends State<TimePickerScreen> 
  String selectedFromTime = " ";
  List<String> fromTimeList = ["0:00", "0:30", "1:00", "1:30", "2:00", "2:30", "3:00", "3:30", "4:00", "4:30", "5:00", "5:30", "6:00", "6:30"];
  List<bool> fromTimeListSelect =[false,false,false,false,false,false,false,false,false,false,false,false,false,false,];

  String selectedToTime =" ";
  List<String> toTimeList = ["0:00", "0:30", "1:00", "1:30", "2:00", "2:30", "3:00", "3:30", "4:00", "4:30", "5:00", "5:30", "6:00", "6:30"];
  List<bool> toTimeListSelect =[false,false,false,false,false,false,false,false,false,false,false,false,false,false,];

  @override
  Widget build(BuildContext context) 
    return Container(
      height: MediaQuery.of(context).size.height * 0.80,
      decoration: BoxDecoration(
        borderRadius: BorderRadius.only(
          topLeft: Radius.circular(10),
          topRight: Radius.circular(10),
        )
      ),
      child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            
            Container(
              padding: EdgeInsets.fromLTRB(50, 50, 50, 50),
                child: Text("Time Picker",style: TextStyle(fontSize: 40,color: Colors.purple),)),
            Divider(),
            Text("Select From Time",style: TextStyle(fontSize: 20,color: Colors.purple),),
            fromTime(),
            Divider(),
            Text("Select To Time",style: TextStyle(fontSize: 20,color: Colors.purple),),
            toTime(),
            FlatButton(onPressed: ()

            ,
                color: Colors.purple,
                padding: EdgeInsets.fromLTRB(15, 15, 15, 15),
                child: Text("Save",style: TextStyle(fontSize: 20,color: Colors.white),)),
            SizedBox(height: 100,),
            Text('From : $selectedFromTime To : $selectedToTime'),

          ],
        ),
    );

  
  Widget fromTime()
    return Expanded(
      child: ListView.builder(
        shrinkWrap: true,
        scrollDirection: Axis.horizontal,
        itemCount: fromTimeList.length,
        itemBuilder: (BuildContext context,int index)
          return GestureDetector(
            child: Container(
              padding: EdgeInsets.all(6),
              child: Center(
                  child: Text(fromTimeList[index],
                    style: TextStyle(color: fromTimeListSelect[index] ? Colors.white : Colors.black ,fontSize: 16),)),
              decoration: BoxDecoration(
                shape: BoxShape.circle,
                color: fromTimeListSelect[index] ? Colors.purple : Colors.white,
              ),
            ),
            onTap: ()
              setState(() 
                for(int i=0; i< fromTimeListSelect.length; i++)
                  fromTimeListSelect[i] = false;
                
                fromTimeListSelect[index] = !fromTimeListSelect[index];
                fromTimeListSelect[index] == true ? selectedFromTime =fromTimeList[index] : selectedFromTime= ' ';
                print(fromTimeListSelect[index]);
                print(fromTimeList[index]);
              );
            ,
          );

        ,),
    );
  

  Widget toTime()
    return Expanded(
      child: ListView.builder(
        shrinkWrap: true,
        scrollDirection: Axis.horizontal,
        itemCount: fromTimeList.length,
        itemBuilder: (BuildContext context,int index)
          return GestureDetector(
            child: Container(
              padding: EdgeInsets.all(6),
              child: Center(
                  child: Text(toTimeList[index],
                    style: TextStyle(color: toTimeListSelect[index] ? Colors.white : Colors.black ,fontSize: 16),)),
              decoration: BoxDecoration(
                shape: BoxShape.circle,
                color: toTimeListSelect[index] ? Colors.purple : Colors.white,
              ),
            ),
            onTap: ()
              setState(() 
                for(int i=0; i< toTimeListSelect.length;i++) 
                  toTimeListSelect[i] = false;
                
                toTimeListSelect[index] = !toTimeListSelect[index];
                toTimeListSelect[index] == true ? selectedToTime =toTimeList[index] : selectedToTime= ' ';
                print(toTimeListSelect[index]);
                print(toTimeList[index]);
              );
            ,
          );

        ,),
    );
  

【问题讨论】:

哇@Yeasin Sheikh 我很欣赏你的工作,我理解回调的工作非常感谢。 【参考方案1】:

在类级别上添加回调方法TimePickerScreen

 final Function callback;

并在Save button 上使用它

      onPressed: () 
                widget.callback(selectedFromTime, selectedToTime); //here
                Navigator.of(context).pop();
              ,

并使用TimePickerScreen 喜欢

  return TimePickerScreen(
            callback: (String from, String to) 
              print("From $from TO $to");
             setState(() 
                pfromTime = from;
                ptoTime = to;
              );
            ,
          );

制作可空字符串将是更好的选择,因为它取决于用户。

完整代码

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget 
  const MyApp(Key? key) : super(key: key);

  @override
  Widget build(BuildContext context) 
    return MaterialApp(
      title: "custom time picker horizontal",
      home: SelectTimeDate(),
    );
  


class SelectTimeDate extends StatefulWidget 
  @override
  _SelectTimeDateState createState() => _SelectTimeDateState();


class _SelectTimeDateState extends State<SelectTimeDate> 
  String pfromTime = '';
  String ptoTime = '';
  //String fromDate='';
  //String toDate='';
  @override
  Widget build(BuildContext context) 
    return Scaffold(
      appBar: AppBar(
        title: const Text('custom time picker horizontal'),
      ),
      body: Center(
        child: Container(
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.center,
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              GestureDetector(
                onTap: pickerBottomSheet,
                child: Container(
                  child: Column(
                    children: [
                      Text(
                        " From ",
                        style: TextStyle(fontSize: 20, color: Colors.black),
                      ),
                      Text(
                        pfromTime == '' ? "Select Time" : pfromTime,
                        style: TextStyle(fontSize: 15, color: Colors.grey),
                      ),
                    ],
                  ),
                ),
              ),
              SizedBox(
                height: 10,
              ),
              GestureDetector(
                onTap: pickerBottomSheet,
                child: Container(
                  child: Column(
                    children: [
                      Text(
                        " To ",
                        style: TextStyle(fontSize: 20, color: Colors.black),
                      ),
                      Text(
                        ptoTime == '' ? "Select Time" : ptoTime,
                        style: TextStyle(fontSize: 15, color: Colors.grey),
                      ),
                    ],
                  ),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  

  pickerBottomSheet() 
    showModalBottomSheet(
        context: context,
        isScrollControlled: true,
        isDismissible: true,
        builder: (BuildContext context) 
          return TimePickerScreen(
            callback: (String from, String to) 
              print("From $from TO $to");
            ,
          );
        );
  


class TimePickerScreen extends StatefulWidget 
  final Function callback;

  const TimePickerScreen(Key? key, required this.callback) : super(key: key);

  @override
  _TimePickerScreenState createState() => _TimePickerScreenState();


class _TimePickerScreenState extends State<TimePickerScreen> 
  String selectedFromTime = " ";
  List<String> fromTimeList = [
    "0:00",
    "0:30",
    "1:00",
    "1:30",
    "2:00",
    "2:30",
    "3:00",
    "3:30",
    "4:00",
    "4:30",
    "5:00",
    "5:30",
    "6:00",
    "6:30"
  ];
  List<bool> fromTimeListSelect = [
    false,
    false,
    false,
    false,
    false,
    false,
    false,
    false,
    false,
    false,
    false,
    false,
    false,
    false,
  ];

  String selectedToTime = " ";
  List<String> toTimeList = [
    "0:00",
    "0:30",
    "1:00",
    "1:30",
    "2:00",
    "2:30",
    "3:00",
    "3:30",
    "4:00",
    "4:30",
    "5:00",
    "5:30",
    "6:00",
    "6:30"
  ];
  List<bool> toTimeListSelect = [
    false,
    false,
    false,
    false,
    false,
    false,
    false,
    false,
    false,
    false,
    false,
    false,
    false,
    false,
  ];

  @override
  Widget build(BuildContext context) 
    return Container(
      height: MediaQuery.of(context).size.height * 0.80,
      decoration: const BoxDecoration(
          borderRadius: BorderRadius.only(
        topLeft: Radius.circular(10),
        topRight: Radius.circular(10),
      )),
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Container(
              padding: EdgeInsets.fromLTRB(50, 50, 50, 50),
              child: Text(
                "Time Picker",
                style: TextStyle(fontSize: 40, color: Colors.purple),
              )),
          Divider(),
          Text(
            "Select From Time",
            style: TextStyle(fontSize: 20, color: Colors.purple),
          ),
          fromTime(),
          Divider(),
          Text(
            "Select To Time",
            style: TextStyle(fontSize: 20, color: Colors.purple),
          ),
          toTime(),
          FlatButton(
              onPressed: () 
                widget.callback(selectedFromTime, selectedToTime); //here
                Navigator.of(context).pop();
              ,
              color: Colors.purple,
              padding: EdgeInsets.fromLTRB(15, 15, 15, 15),
              child: Text(
                "Save",
                style: TextStyle(fontSize: 20, color: Colors.white),
              )),
          SizedBox(
            height: 100,
          ),
          Text('From : $selectedFromTime To : $selectedToTime'),
        ],
      ),
    );
  

  Widget fromTime() 
    return Expanded(
      child: ListView.builder(
        shrinkWrap: true,
        scrollDirection: Axis.horizontal,
        itemCount: fromTimeList.length,
        itemBuilder: (BuildContext context, int index) 
          return GestureDetector(
            child: Container(
              padding: EdgeInsets.all(6),
              child: Center(
                  child: Text(
                fromTimeList[index],
                style: TextStyle(
                    color:
                        fromTimeListSelect[index] ? Colors.white : Colors.black,
                    fontSize: 16),
              )),
              decoration: BoxDecoration(
                shape: BoxShape.circle,
                color: fromTimeListSelect[index] ? Colors.purple : Colors.white,
              ),
            ),
            onTap: () 
              setState(() 
                for (int i = 0; i < fromTimeListSelect.length; i++) 
                  fromTimeListSelect[i] = false;
                
                fromTimeListSelect[index] = !fromTimeListSelect[index];
                fromTimeListSelect[index] == true
                    ? selectedFromTime = fromTimeList[index]
                    : selectedFromTime = ' ';
                print(fromTimeListSelect[index]);
                print(fromTimeList[index]);
              );
            ,
          );
        ,
      ),
    );
  

  Widget toTime() 
    return Expanded(
      child: ListView.builder(
        shrinkWrap: true,
        scrollDirection: Axis.horizontal,
        itemCount: fromTimeList.length,
        itemBuilder: (BuildContext context, int index) 
          return GestureDetector(
            child: Container(
              padding: EdgeInsets.all(6),
              child: Center(
                  child: Text(
                toTimeList[index],
                style: TextStyle(
                    color:
                        toTimeListSelect[index] ? Colors.white : Colors.black,
                    fontSize: 16),
              )),
              decoration: BoxDecoration(
                shape: BoxShape.circle,
                color: toTimeListSelect[index] ? Colors.purple : Colors.white,
              ),
            ),
            onTap: () 
              setState(() 
                for (int i = 0; i < toTimeListSelect.length; i++) 
                  toTimeListSelect[i] = false;
                
                toTimeListSelect[index] = !toTimeListSelect[index];
                toTimeListSelect[index] == true
                    ? selectedToTime = toTimeList[index]
                    : selectedToTime = ' ';
                print(toTimeListSelect[index]);
                print(toTimeList[index]);
              );
            ,
          );
        ,
      ),
    );
  


【讨论】:

嘿@yeasin 我提出了另一个问题,请您通过this link。谢谢。【参考方案2】:

您可以定义一个类来对底部工作表的结果进行建模:

class TimeSelectResult
  final String pFromTime;
  final String pToTime;

  TimeSelectResult(this.pFromTime, this.pToTime);

然后在底部表的代码中,当用户选择 2 次 from 和 to 时,您调用 Navigator.of(context).pop(timeSelectResult) 其中 timeSelectResult 是您的 _TimePickerScreen 的变量,其中填充了用户选择的结果。

所以你现在这样调用底部表:

 pickerBottomSheet() async 
    final TimeSelectResult? result = await showModalBottomSheet(
        context: context,
        isScrollControlled: true,
        isDismissible: true,
        builder: (BuildContext context) 
          return TimePickerScreen();
        );

    if (result != null) 
      setState(() 
        pfromTime = result.pFromTime;
        ptoTime = result.pToTime;
      );
    
  

【讨论】:

以上是关于如何从一个类屏幕获取值到另一个类并在颤动中填充这些值?的主要内容,如果未能解决你的问题,请参考以下文章

static_cast 从底层类型值到枚举类并切换以获取编译器帮助

如何在颤动中将列表数据从一个屏幕传递到另一个屏幕(StatefulWidget)

如何在颤动中将数据从一个小部件传递到另一个小部件?

如何从存储在数据库中的 Listview 获取值到另一个活动?使用 Android 和 Mysql

下拉不保存 - MVC C# 共享一个组合类并保存到另一个表中

如何在颤动的两个不同屏幕上使用相同的块?