How to make Duration picker package works fine?

98 Views Asked by At

I'm using this package in my project : Duration picker and I added a new file to edit that duration with textfield and keyboard , but as soon as I go back to the wheel part , the movement of the wheel become wrong , I want to keep using this package , this is my code :


import 'package:duration_picker/duration_picker.dart';

import 'package:flutter/material.dart';



void main() {

  runApp(MyApp());

}



class MyApp extends StatelessWidget {

  @override

  Widget build(BuildContext context) {

    return MaterialApp(

      title: 'Flutter App',

      theme: ThemeData(

        primarySwatch: Colors.blue,

      ),

      home: MyHomePage(),

    );

  }

}



class MyHomePage extends StatelessWidget {

  @override

  Widget build(BuildContext context) {

    return Scaffold(

      appBar: AppBar(

        title: Text('Flutter App'),

      ),

      body: Center(

          child: ElevatedButton(

        onPressed: () {

          activityDurationDialog(context);

        },

        child: Text('click'),

      )),

    );

  }

}



Future<void> activityDurationDialog(BuildContext context, {double topBottomPadding = 10}) async {

  Duration _duration = Duration(hours: 0, minutes: 0);

  TextEditingController _hourController = TextEditingController(text: _duration.inHours.toString());

  TextEditingController _minuteController = TextEditingController(text: _duration.inMinutes.remainder(60).toString());

  bool isAddedManually = false;



  void setIsAddedManually(bool newValue) {

    isAddedManually = newValue;

  }



  await showDialog<void>(

    context: context,

    barrierDismissible: true,

    builder: (BuildContext context) {

      return StatefulBuilder(

        builder: (context, setState) {

          return AlertDialog(

            title: Text('duration'),

            content: SingleChildScrollView(

              child: Padding(

                padding: const EdgeInsets.all(16.0),

                child: Column(

                  children: [

                    Divider(color: Colors.black),

                    Padding(

                      padding: const EdgeInsets.only(top: 25.0),

                      child: DurationPicker(

                        width: MediaQuery.of(context).size.width * 0.9,

                        duration: _duration,

                        onChange: (val) {

                          setState(() {

                            if (isAddedManually == false) {

                              _duration = val;

                              _hourController.text = _duration.inHours.toString();

                              _minuteController.text = _duration.inMinutes.remainder(60).toString();

                            } else {

                              _duration = _duration + val;

                              _hourController.text = _duration.inHours.toString();

                              _minuteController.text = _duration.inMinutes.remainder(60).toString();

                            }

                          });

                        },

                        snapToMins: 5.0,

                      ),

                    ),

                  ],

                ),

              ),

            ),

            actions: <Widget>[

              Row(

                mainAxisAlignment: MainAxisAlignment.spaceBetween,

                crossAxisAlignment: CrossAxisAlignment.center,

                children: [

                  Padding(

                    padding: const EdgeInsets.only(left: 8.0),

                    child: IconButton(

                      icon: Icon(

                        Icons.keyboard,

                        size: 30,

                      ),

                      onPressed: () {

                        activityDurationEditingDialog(

                          context,

                          _hourController,

                          _minuteController,

                          _duration,

                          setIsAddedManually,

                          (newDuration) {

                            setState(() {

                              _duration = newDuration;

                              _hourController.text = _duration.inHours.toString();

                              _minuteController.text = _duration.inMinutes.remainder(60).toString();

                            });

                          },

                        );

                      },

                    ),

                  ),

                ],

              ),

            ],

          );

        },

      );

    },

  );

}



Future<void> activityDurationEditingDialog(

  BuildContext context,

  TextEditingController _hourController,

  TextEditingController _minuteController,

  Duration _duration,

  Function(bool) setIsAddedManually,

  Function(Duration) onUpdate, {

  double topBottomPadding = 10,

}) async {

  return showDialog<void>(

    context: context,

    barrierDismissible: true,

    builder: (BuildContext context) {

      return StatefulBuilder(

        builder: (context, setState) {

          return AlertDialog(

            title: Text('edit'),

            content: SingleChildScrollView(

              child: Column(

                children: [

                  Divider(color: Colors.black),

                  SizedBox(

                    height: 10,

                  ),

                  Row(

                    mainAxisAlignment: MainAxisAlignment.spaceAround,

                    children: [

                      Column(

                        children: [

                          Text('hour'),

                          SizedBox(

                            height: 10,

                          ),

                          Container(

                            width: 100,

                            child: TextField(

                              decoration: InputDecoration(

                                border: OutlineInputBorder(),

                              ),

                              maxLength: 3,

                              controller: _hourController,

                              keyboardType: TextInputType.number,

                              textAlign: TextAlign.center,

                              onChanged: (value) {

                                int hours = int.tryParse(value) ?? 0;

                                setState(() {

                                  _duration = Duration(

                                    hours: hours,

                                    minutes: _duration.inMinutes.remainder(60),

                                  );

                                });

                              },

                            ),

                          ),

                        ],

                      ),

                      Column(

                        children: [

                          Text('minute'),

                          SizedBox(

                            height: 10,

                          ),

                          Container(

                            width: 100,

                            child: TextField(

                              decoration: InputDecoration(

                                border: OutlineInputBorder(),

                              ),

                              maxLength: 2,

                              controller: _minuteController,

                              keyboardType: TextInputType.number,

                              textAlign: TextAlign.center,

                              onChanged: (value) {

                                int minutes = int.tryParse(value) ?? 0;

                                setState(() {

                                  _duration = Duration(

                                    hours: _duration.inHours,

                                    minutes: minutes,

                                  );

                                });

                              },

                            ),

                          ),

                        ],

                      ),

                    ],

                  ),

                ],

              ),

            ),

            actions: <Widget>[

              Row(

                mainAxisAlignment: MainAxisAlignment.spaceBetween,

                crossAxisAlignment: CrossAxisAlignment.center,

                children: [

                  Padding(

                    padding: const EdgeInsets.only(left: 8.0),

                    child: IconButton(

                      icon: Icon(

                        Icons.access_time,

                        size: 30,

                      ),

                      onPressed: () {

                        setIsAddedManually(true);

                        onUpdate(_duration);

                        Navigator.of(context).pop();

                      },

                    ),

                  ),

                ],

              ),

            ],

          );

        },

      );

    },

  );

}

please give it a try , I'm stuck there for 2 days , thanks

1

There are 1 best solutions below

0
pixel On

See, i didn't understood your code and it's really weird i will come to it later first the issue, i found the solution.

The issue is with you call back function setIsAddedManually of activityDurationEditingDialog as you pass true in it, it makes the isAddedManually variable of activityDurationDialog to true and which leads to your else part of onChange of DurationPicker. Which making the duration to exponential growth, pass false setIsAddedManually(false) solve the exponential growth issue.

Still you need to check why the DurationPicker won't update on pop of your manual duration entry dialog.

About the code, You can ignore it if you want:

See i don't know why you're using the high functions, but you should not do it with flutter, as flutter stack up all your function and this can lead to memory wastage, rather you can define StateLess widgets having content of your dialogs simple. And i don't found why you are using SetIsAddedManually callback and isAddedManually variable either.