suppose you have a API and a key-value for this API is
"time": "22:05"
i want to show this time in a in a field and when i press the field the date time picker is pop up with time value and i change the time like 22:40 and the 22:05 will replace to 22:40
I have try this..
time = TimeOfDay.now();
final String hour = time.hour.toString().padLeft(2, '0');
final String minute = time.minute.toString().padLeft(2, '0');
GestureDetector(
onTap: () async {
TimeOfDay? pickTime = await showTimePicker(
context: context,
initialTime: time,
);
if (pickTime != null) {
setState(() => time = pickTime);
}
It always show my current system time
Here is a working example:
import 'package:flutter/material.dart';
const Color darkBlue = Color.fromARGB(255, 18, 32, 47);
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark().copyWith(
scaffoldBackgroundColor: darkBlue,
),
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Center(
child: MyWidget(),
),
),
);
}
}
class MyWidget extends StatefulWidget {
const MyWidget({ super.key });
#override
State<MyWidget> createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget> {
TimeOfDay? selectedTime;
#override
Widget build(BuildContext context) {
return
GestureDetector(
onTap : () async {
TimeOfDay? newTime = await showTimePicker(
initialTime: TimeOfDay.now(),
context: context,
);
setState((){
selectedTime = newTime;
});
},
child: Text(
selectedTime.toString(),
style: Theme.of(context).textTheme.headline4,
),
);
}
}
this is my usual way. with TextFormfied. so you can use validator if you need too.
TextFormField(
readOnly: true,
decoration: kInputDecor,
controller: _ctrl,
onTap: () async {
final selectedTime = await showTimePicker(
context: context,
initialTime: TimeOfDay.now(),
);
if (selectedTime != null) {
final String hour =
selectedTime.hour.toString().padLeft(2, '0');
final String minute =
selectedTime.minute.toString().padLeft(2, '0');
// _ctrl.text = selectedTime.format(context);
_ctrl.text = '${hour} :$minute';
}
},
),
result:
demo : https://dartpad.dev/?id=be4ccb0cad0930c9797bb4c2b63cd70e
Related
I am trying to displayed time selected from showTimePicker dialogue but after getting the value it becomes null again.
after debugging, it seems like the value returned from future function expried or something.
after the widgets onPress function it is back to null.
ElevatedButton(
child: const Text('Time'),
onPressed: () async {
vTimeSelected = await getTimeSelected(context);
setState(() {
// vStrToRndr = vTimeSelected.toString();
//print(vStrToRndr);
});
},
),
ElevatedButton(
child: const Text('Solid'),
onPressed: () {
setState(() {
vDetail.solid = !vDetail.solid;
});
},
),
],
),
),
if (vDetail.wet == true) Text('Nappy wet'),
if (vDetail.solid == true) Text('Nappy Solid'),
Text('Time: $vTimeSelected'),
[7:35 PM]
Future<TimeOfDay?> getTimeSelected(BuildContext context) async {
TimeOfDay vTime = TimeOfDay(hour: 0, minute: 0);
TimeOfDay? newTime =
await showTimePicker(context: context, initialTime: vTime);
return newTime;
//print($newTime);
}
//thanks for any help
Text('Time: $vTimeSelected') //<---- this is displaying null
You can follow this code structure. Make sure to declare variable outside the build method.
class TS extends StatefulWidget {
const TS({super.key});
#override
State<TS> createState() => _TSState();
}
class _TSState extends State<TS> {
TimeOfDay? vTimeSelected;
#override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButton: FloatingActionButton(onPressed: () async {
vTimeSelected = await getTimeSelected(context);
setState(() {});
}),
body: Text("${vTimeSelected}"),
);
}
}
On a page, I have a button. I am using the OnTap to display a bottom sheet. But the widget does not display on the screen. I don't know why. I have tried different option and even tried using other widget to check if they were displaying properly. It was working. But it is not with the bottom sheet. If you can explain to me what I am missing, it would be appreciated. Thank you.
I have tried also this, see code below, but it is not working properly because I can not use setstate.
ERROR : lost connection. It is killing the simulator.
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_sound/flutter_sound.dart';
import 'package:permission_handler/permission_handler.dart';
class Voice_Recording extends StatefulWidget {
const Voice_Recording({Key key}) : super(key: key);
#override
_Voice_RecordingState createState() => _Voice_RecordingState();
}
class _Voice_RecordingState extends State<Voice_Recording> {
final recorder = FlutterSoundRecorder();
#override
void initState(){
super.initState();
initRecorder();
}
#override
void dispose(){
recorder.closeRecorder();
super.dispose();
}
Future initRecorder() async{
final status = await Permission.microphone.request();
if(status != PermissionStatus.granted){
throw 'Microphone permission not granted!';
}
await recorder.openRecorder();
recorder.setSubscriptionDuration(Duration(milliseconds: 500 ));
}
Future record() async{
await recorder.startRecorder(toFile:'audio');
}
Future stop() async{
final path = await recorder.stopRecorder();
final audioFile = File(path);
print('recorded audio File :$audioFile');
}
#override
Widget build(BuildContext context) {
return BottomSheet(
builder: (context){
return Column(
children: [
StreamBuilder<RecordingDisposition>(
stream: recorder.onProgress,
builder: (context,snapshot){
final duration=snapshot.hasData?
snapshot.data.duration: Duration.zero;
String twoDigits(int n) => n.toString().padLeft(60);
final twoDigitsMinutes= twoDigits(duration.inMinutes.remainder(60));
final twoDigitsSeconds = twoDigits(duration.inSeconds.remainder(60));
return Text('$twoDigitsMinutes:$twoDigitsSeconds',
style: TextStyle(
fontSize: 80,
fontWeight: FontWeight.bold,
),);
},
),
Center(child:
ElevatedButton(child:Icon(recorder.isRecording? Icons.stop:Icons.mic,size:80),
onPressed: () async{
if(recorder.isRecording){
await stop();
}else{
await record();
}
setState(() {
});
},)
),
]);
});
}
}
New code. not working perfectly due to lost of SetState()
showDialogVoiceRecording(BuildContext context, {String myText = 'Record and speak !'}) {
showModalBottomSheet<void>(
context: context,
isDismissible: false,
builder: (BuildContext context) {
context = context;
return Column(
children: [
StreamBuilder<RecordingDisposition>(
stream: recorder.onProgress,
builder: (context,snapshot){
final duration=snapshot.hasData?
snapshot.data.duration: Duration.zero;
String twoDigits(int n) => n.toString().padLeft(60);
final twoDigitsMinutes= twoDigits(duration.inMinutes.remainder(60));
final twoDigitsSeconds = twoDigits(duration.inSeconds.remainder(60));
return Text('$twoDigitsMinutes:$twoDigitsSeconds',
style: TextStyle(
fontSize: 80,
fontWeight: FontWeight.bold,
),);
},
),
Center(child:
ElevatedButton(child:Icon(recorder.isRecording? Icons.stop:Icons.mic,size:80),
onPressed: () async{
if(recorder.isRecording){
await stop();
}else{
await record();
}
/* setState(() {
});*/
},)
),
],
);
}
);
}
I'm new to Flutter and I'm making a To Do app. I want to be able to open a showModalBottomSheet widget when I click an ElevatedButton that belongs to another widget. Ideally it would open when the user clicks "Edit" belonging to one of the ToDo widgets.
Worst case I could probably use another showModalBottomSheet for the edit action but I'd love to be able to reuse my existing showModalBottomSheet for edits as well as new to do's since it's already in place. All I need to do is trigger it to reopen when the user selects "Edit".
Here is my code in MyApp. I can include code for NewToDo if requested but I feel like that code isn't the issue.
import 'package:flutter/material.dart';
import './todoitem.dart';
import './todolist.dart';
import 'classes/todo.dart';
import './newtodo.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'To Do Homie',
theme: ThemeData(
primarySwatch: Colors.deepPurple,
),
home: const MyHomePage(title: "It's To Do's My Guy"),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({
Key? key,
required this.title,
}) : super(key: key);
final String title;
#override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
String content = '';
String title = '';
int maxId = 0;
ToDo? _todo;
final titleController = TextEditingController();
final contentController = TextEditingController();
List<ToDo> _todos = [];
void _addTodo(){
final todo = ToDo (
title: title,
id: maxId,
isDone: false,
content: content
);
if (_todo != null){
setState(() {
_todos[_todos.indexOf(_todo!)] = todo;
});
} else {
setState(() {
_todos.add(todo);
});
}
setState(() {
content = '';
maxId = maxId++;
title = '';
_todo = null;
});
contentController.text = '';
titleController.text = '';
}
#override
void initState() {
super.initState();
titleController.addListener(_handleTitleChange);
contentController.addListener(_handleContentChange);
}
void _handleTitleChange() {
setState(() {
title = titleController.text;
});
}
void _handleContentChange() {
setState(() {
content = contentController.text;
});
}
void _editTodo(ToDo todoitem){
setState(() {
_todo = todoitem;
content = todoitem.content;
title = todoitem.title;
});
contentController.text = todoitem.content;
titleController.text = todoitem.title;
}
void _deleteToDo(ToDo todoitem){
setState(() {
_todos = List.from(_todos)..removeAt(_todos.indexOf(todoitem));
});
}
void _clear(){
contentController.text = '';
titleController.text = '';
setState(() {
content = '';
title = '';
_todo = null;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: SingleChildScrollView(
child: Center(
child: Container(
alignment: Alignment.topCenter,
child: ToDoList(_todos, _editTodo, _deleteToDo)
),
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
showModalBottomSheet<void>(
context: context,
builder: (BuildContext context) {
return ValueListenableBuilder(
valueListenable: titleController,
builder: (context, _content, child) {
return NewToDo(titleController, contentController, _addTodo, _clear, _todo);
});
});
},
child: const Icon(Icons.add),
backgroundColor: Colors.deepPurple,
),
);
}
}
Try extracting the showModalBottomSheet in its own method and pass it to the onPressed like this:
floatingActionButton: FloatingActionButton(
onPressed: _triggerBottomSheet,
// then create the method
void _triggerBottomSheet(){
showModalBottomSheet<void>(
context: context,
builder: (BuildContext context) {
return ValueListenableBuilder(
valueListenable: titleController,
builder: (context, _content, child) {
return NewToDo(titleController, contentController, _addTodo, _clear, _todo);
});
});
I am new to flutter and I am having the following problem.
I am trying to use the progressDialog in in a listview, I make the query to my database, I extract the list and pass it to the listview, I am trying to use the progressDialog so when I start loading the list it will run and tell the user to wait, and when I finish loading the list then the progressDialog is hidden, so far it works for me by bringing me the list and the progressDialog is executed saying to wait, but when I put the progressDialog.hide where the loading of the list ends I this is not accepting that line of code (progressDialog .hidde)
image:
enter image description here
import 'dart:convert';
import 'package:fluterproyecto1/Modulos/DetalleUser.dart';
import 'package:flutter/material.dart';
import 'package:progress_dialog/progress_dialog.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:http/http.dart' as http;
String username2 = '';
String profesion = '';
String name = '';
class MemberPage extends StatefulWidget {
MemberPage({Key key}) : super(key: key);
#override
_MemberPageState createState() => _MemberPageState();
}
class _MemberPageState extends State<MemberPage> {
Map data;
List userData;
ProgressDialog progressDialog;
String name = '';
Future getData() async {
http.Response response =
await http.get("http://masciudad.com.co/flutter/getdata.php");
data = json.decode(response.body);
//setState(() {
//progressDialog.show();
userData = data["data"];
//progressDialog.hide();
//});
}
#override
void initState() {
super.initState();
getData();
}
#override
Widget build(BuildContext context) {
progressDialog = ProgressDialog(context, type: ProgressDialogType.Normal);
progressDialog.style(message: 'Por favor espere...');
progressDialog.show();
setState(() {
obtenerPreferencias();
});
return Scaffold(
appBar: AppBar(
title: Text("Bienvenido $username2"),
),
body: ListView.builder(
itemCount: userData == null ? 0 : userData.length,
itemBuilder: (BuildContext context, int index) {
return InkWell(
child: Padding(
padding: const EdgeInsets.all(10.0),
child: Row(
children: <Widget>[
Image.asset(
"assets/128.jpg",
width: 30.0,
height: 30.0,
),
//CircleAvatar(
///cuando la imagen es de interntet
//backgroundImage: NetworkImage(
// "https://s3.amazonaws.com/uifaces/faces/twitter/follettkyle/128.jpg"),
//),
Padding(
padding: const EdgeInsets.all(10.0),
child: Text(
"${userData[index]["username"]} - ${userData[index]["profesion"]}",
style: TextStyle(
fontSize: 20.0,
fontWeight: FontWeight.w700,
),
),
)
],
),
),
onTap: () => Navigator.push(
context,
new MaterialPageRoute(
builder: (BuildContext context) =>
new DetalleUser(name: userData[index]["username"]))),
);
},
),
//Navigator.of(context).push(MaterialPageRoute(
// builder: (BuildContext context) => MyHomePage()));
//Navigator.pushReplacementNamed(context, "/MyHomePage");
);
}
Future obtenerPreferencias() async {
SharedPreferences preferences = await SharedPreferences.getInstance();
setState(() {
username2 = preferences.get("username2") ?? "";
profesion = preferences.get("profesion") ?? "";
});
}
Future destruirPreferencias() async {
SharedPreferences preferences = await SharedPreferences.getInstance();
preferences.clear();
}
}
You can copy paste run full code below
You can use addPostFrameCallback and put logical in another function getRelatedData()
code snippet
void getRelatedData() async {
progressDialog = ProgressDialog(context, type: ProgressDialogType.Normal);
progressDialog.style(message: 'Por favor espere...');
progressDialog.show();
await getData();
await obtenerPreferencias();
progressDialog.hide();
}
#override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
getRelatedData();
});
}
working demo
full code
import 'package:flutter/material.dart';
import 'dart:convert';
import 'package:progress_dialog/progress_dialog.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:http/http.dart' as http;
String username2 = '';
String profesion = '';
String name = '';
class MemberPage extends StatefulWidget {
MemberPage({Key key}) : super(key: key);
#override
_MemberPageState createState() => _MemberPageState();
}
class _MemberPageState extends State<MemberPage> {
Map data;
List userData;
ProgressDialog progressDialog;
String name = '';
Future getData() async {
http.Response response =
await http.get("http://masciudad.com.co/flutter/getdata.php");
data = json.decode(response.body);
//setState(() {
//progressDialog.show();
userData = data["data"];
print("getData Done");
//progressDialog.hide();
//});
}
void getRelatedData() async {
progressDialog = ProgressDialog(context, type: ProgressDialogType.Normal);
progressDialog.style(message: 'Por favor espere...');
progressDialog.show();
await getData();
await obtenerPreferencias();
progressDialog.hide();
}
#override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
getRelatedData();
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Bienvenido $username2"),
),
body: ListView.builder(
itemCount: userData == null ? 0 : userData.length,
itemBuilder: (BuildContext context, int index) {
return InkWell(
child: Padding(
padding: const EdgeInsets.all(10.0),
child: Row(
children: <Widget>[
Image.network(
"https://picsum.photos/250?image=9",
width: 30.0,
height: 30.0,
),
//CircleAvatar(
///cuando la imagen es de interntet
//backgroundImage: NetworkImage(
// "https://s3.amazonaws.com/uifaces/faces/twitter/follettkyle/128.jpg"),
//),
Padding(
padding: const EdgeInsets.all(10.0),
child: Text(
"${userData[index]["username"]} - ${userData[index]["profesion"]}",
style: TextStyle(
fontSize: 20.0,
fontWeight: FontWeight.w700,
),
),
)
],
),
),
onTap: () {
/*Navigator.push(
context,
new MaterialPageRoute(
builder: (BuildContext context) =>
new DetalleUser(name: userData[index]["username"])));*/
});
},
),
//Navigator.of(context).push(MaterialPageRoute(
// builder: (BuildContext context) => MyHomePage()));
//Navigator.pushReplacementNamed(context, "/MyHomePage");
);
}
Future obtenerPreferencias() async {
SharedPreferences preferences = await SharedPreferences.getInstance();
setState(() {
username2 = preferences.get("username2") ?? "";
profesion = preferences.get("profesion") ?? "";
});
}
Future destruirPreferencias() async {
SharedPreferences preferences = await SharedPreferences.getInstance();
preferences.clear();
}
}
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MemberPage(),
);
}
}
Dear #Yeimer I would suggest read documentation carefully
https://pub.dev/packages/progress_dialog
Add the Package this
dependencies:
progress_dialog: ^1.2.4
1
Initialize your ProgressDialog object
final ProgressDialog prDialog = ProgressDialog(context);
//For normal dialog
prDialog = ProgressDialog(context,type: ProgressDialogType.Normal, isDismissible: true/false, showLogs: true/false);
2 Showing the progress dialog
await pr.show();
3
Dismissing the progress dialog
prDialog.hide().then((isHidden) {
print(isHidden);
});
// or simply
await prDialog.hide();
Here I want to validate the time picker. when I am going to select the time from the time picker it must only allow me to select the current time or before the current time. I am not supposed to allow select future time.
Here is the time picker snippet I've tried.
DateTimeField(
format: format,
autocorrect: true,
autovalidate: false,
controller: _serviceDate,
readOnly: true,
validator: (date) => (date == null || _serviceDate.text == '')
? 'Please enter valid date'
: null,
onShowPicker: (context, currentValue) async {
final date = await showDatePicker(
context: context,
firstDate: DateTime.now(),
initialDate: currentValue ?? DateTime.now(),
lastDate: DateTime(2100));
if (date != null) {
final time = await showTimePicker(
context: context,
initialTime: TimeOfDay.fromDateTime(
currentValue ?? DateTime.now(),
),
);
return DateTimeField.combine(date, time);
} else {
return currentValue;
}
},
);
You can enable autovalidateMode on DateTimeField then check the DateTime difference of the selected DateTime with the current DateTime. If the time difference is negative, this means the selected DateTime is in the past.
DateTimeField(
format: format,
autocorrect: true,
readOnly: true,
autovalidateMode: AutovalidateMode.onUserInteraction,
validator: (DateTime? selectedDateTime) {
if (selectedDateTime != null) {
// If the DateTime difference is negative,
// this indicates that the selected DateTime is in the past
if (selectedDateTime.difference(DateTime.now()).isNegative) {
debugPrint('Selected DateTime is in the past');
} else {
debugPrint('Selected DateTime is in the future');
}
}
},
onShowPicker: ...
),
Aside from that, you might also want to consider setting the lastDate on showDatePicker to DateTime.now() so future dates can't be selected.
Here's the complete sample that you can try out.
import 'package:datetime_picker_formfield/datetime_picker_formfield.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.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: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
#override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final format = DateFormat("yyyy-MM-dd HH:mm");
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
DateTimeField(
format: format,
autocorrect: true,
readOnly: true,
autovalidateMode: AutovalidateMode.onUserInteraction,
validator: (DateTime? selectedDateTime) {
if (selectedDateTime != null) {
// If the DateTime difference is negative,
// this indicates that the selected DateTime is in the past
if (selectedDateTime.difference(DateTime.now()).isNegative) {
debugPrint('Selected DateTime is in the past');
} else {
debugPrint('Selected DateTime is in the future');
}
}
},
onShowPicker: (context, currentValue) async {
final date = await showDatePicker(
context: context,
firstDate: DateTime(1900),
initialDate: DateTime.now(),
lastDate: DateTime.now());
if (date != null) {
final time = await showTimePicker(
context: context,
initialTime: TimeOfDay.fromDateTime(
currentValue ?? DateTime.now(),
),
);
return DateTimeField.combine(date, time);
} else {
return currentValue;
}
},
),
],
),
),
);
}
}