In a brand new Flutter project, if I add a showTimePicker widget, then open the time picker in input mode, the height of the dialog is shorter than the input mode contents, so you have to scroll to see the OK and Cancel buttons. This, even though the input mode is half as tall as the dial mode contents, which doesn't require scrolling.
Question: Is there any way to add padding or a min-height to a Flutter dialog such as the showTimePicker?
I've seen answers that describe sizing a container outside of/around the picker, or using the builder method, and others mentioning custom styling, but nothing for the size of the picker dialog itself that might address this vertical cutoff.
Flutter 2.0.3 - Device: Pixel XL with Android 10.
Any insights appreciated.
TextButton(
onPressed: () async {
final _selectedTime = await showTimePicker(
context: context,
initialTime: TimeOfDay.now(),
initialEntryMode: TimePickerEntryMode.input,
);
if (_selectedTime != null) {
String thisHour = _selectedTime.hour <= 9
? '0${_selectedTime.hour}'
: '${_selectedTime.hour}';
String thisMin = _selectedTime.minute <= 9
? '0${_selectedTime.minute}'
: '${_selectedTime.minute}';
print('$thisHour:$thisMin');
}
},
child: Text(
'Test It',
style: TextStyle(
fontSize: 22,
),
),
),
I solved this question this adding this code in showTimePicker builder.
builder: (context, childWidget) {
return MediaQuery(
data: MediaQuery.of(context).copyWith(
textScaleFactor: 1),
});
The answer by zey is close to correct. This is a full working example:
await showTimePicker(
context: context,
initialTime: TimeOfDay.now(),
builder: (context, childWidget) {
return MediaQuery(
data: MediaQuery.of(context).copyWith(textScaleFactor: 1),
child: childWidget!,
);
},
);
The issue is described in this flutter issue, and is happening at least since version 2.2 (and is still happening on Flutter 3.0.2)
Related
I want to hide the first alert dialog when I call showDialog() from it. After that when I close the second dialog I want the first dialog was visible again. How I can achieve this?
Before you call second dialog, use Navigator.of(context).pop() to close first dialog. Then, in the second one, you have functions then((value) {...}) or whenComplete(() {...}), inside that you can use it to re-open first dialog.
That's strange that you want to close first one, why don't you just leave it alone and let the second lies on it?
You can create common dialog to show data. if its already showing then just update data only.
showDialog return a future and you can pass data from dialog. The concept is here passing some flag to open the second dialog.
onPressed: () async {
final data = await showDialog(
context: context,
builder: (context) {
return AlertDialog(
content: ElevatedButton(
onPressed: () {
Navigator.of(context)
.pop(true); // true for to show second dialog
},
child: Text("open Second dialog"),
),
);
});
if (data == true) {
showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: Text("Second dialog"),
);
});
}
},
I tried to put two conditions with the values of an email and a password in order to activate my button only if the two conditions are validated but it is not working because I think my syntax is written in a bad way.
Can you help me to resolve this problem please ?
Plus I have no error messages except the fact that the button doesn't navigate to the HomePage like it lost its fonction.
This is my code
child: FlatButton(
padding: EdgeInsets.symmetric(vertical: 14, horizontal: 40),
color: DarkTurquoise,
onPressed: _password.length < 6 ? null :() {
!emailRegex.hasMatch(_email) ? null : () {
if (_formKey.currentState!.validate()) {
print(_email);
print(_password);
}
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => HomeScreen(),
),
);
};
},
If you need to validate two conditions same time, use '&&' operator.
_password.length < 6 && !emailRegex.hasMatch(_email) ? <do something> : <do someting>
child: FlatButton(
padding: EdgeInsets.symmetric(vertical: 14, horizontal: 40),
color: DarkTurquoise,
onPressed: _password.length < 6 && !emailRegex.hasMatch(_email) ? null : () {
if (_formKey.currentState!.validate()) {
print(_email);
print(_password);
}
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => HomeScreen(),
),
);
},
),
use this:
onPressed: ()=>{
if (_formKey.currentState!.validate()) {
if(_password.length >= 6 && emailRegex.hasMatch(_email)){
// put your code here!
}
}
}
In flutter, if you want a button to be greyed out or not clickable, you give null to onPressed, which is what is happening in your case based on the condition saying if password < 6.
What happens is when the widget is build, it reaches the line of onPressed, applies the condition you gave it, and it discovers that indeed the password is <6, because no characters have been entered yet.
The widget is built now, and what is done is done.
After you start entering letters, the length becomes longer than 6, but the widget has already been built and you didn't trigger your UI to update and rebuild the button.
What you can do, is to move the null inside your logic, this will not grey out the button, but when you tap it and the conditions fails, nothing happens, like this:
onPressed: () {
if( _password.length >= 6) {
if(emailRegex.hasMatch(_email)){
if (_formKey.currentState!.validate()) {
print(_email);
print(_password);
//I moved the curly brace which was here to the end of the function,
//because I think you only want to navigate if the validation is true, not whenever it is pressed.
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => HomeScreen(),),
);
};
}, //<= new curly brace
}
This is not the right way.
Textfield validation in Flutter
Hope you can get your answer by referring to this article.
Also you can make one function for check password length and like that and create bool true or false and that bool is useful for enable and disable button as well.
I am working with a video player called 'flick video player'. I can play videos fairly okay with default functionality. The problem occurs when I scroll down the screen and the video continues to play in the background. I would like to pause it when it isn't visible, or when a user navigates to a different page on the project app.
The video player that I am using (flick_video_player) has video_player as its dependency.
Answers are much appreciated.
Regards
I think you can use visibility detector for the purpose-
VisibilityDetector(
key: ObjectKey(flickManager),
onVisibilityChanged: (visibility){
if (visibility.visibleFraction == 0 && this.mounted) {
flickManager?.flickControlManager?.pause();//pausing functionality
}
},
child: Container(
child: AspectRatio(
aspectRatio: 1280/720,
child: FlickVideoPlayer(
flickManager: flickManager
),
/*VideoPlayer(
video_controller
),*/
),
),
),
I was working on something similar. For more info like how to play it again and more you can refer this repo- https://github.com/GeekyAnts/flick-video-player/tree/master/example/lib/feed_player
Hope it helped!
Maybe this visibility detector package can help https://pub.dev/packages/visibility_detector
Wrap your list of videos with a NotificationListener and listen to whether the user has started or stopped scrolling. Use this value to either play or pause your video.
Edit: misread your question. This will work for pausing once the user scrolls. If you want to detect whether the video is within the current view, check out ScrollablePositionedList.
return NotificationListener(
onNotification: (notificationInfo) {
if (notificationInfo is ScrollStartNotification) {
// Set a state value to indicate the user is scrolling
}
if (notificationInfo is ScrollEndNotification) {
// Set a state value to indicate the user stopped scrolling
}
return true;
},
child: YourVideos(),
);
This is exactly what you need, inview_notifier_list:
InViewNotifierList(
isInViewPortCondition:
(double deltaTop, double deltaBottom, double vpHeight) {
return deltaTop < (0.5 * vpHeight) && deltaBottom > (0.5 * vpHeight);
},
itemCount: 10,
builder: (BuildContext context, int index) {
return InViewNotifierWidget(
id: '$index',
builder: (BuildContext context, bool isInView, Widget child) {
return Container(
height: 250.0,
color: isInView ? Colors.green : Colors.red,
child: Text(
isInView ? 'Is in view' : 'Not in view',
),
);
},
);
},
);
I have a Flutter app that is functioning properly in all respects except when I select a TextField (or TextFormField). When I select the TextField, the cursor blinks in the TextField, but I can't type anything AND all other buttons like the floatingActionButton and the back button in the AppBar quit working. Essentially, the app appears to be frozen, but I don't get any error messages.
After numerous attempts to fix the problem in two different pages that contain FocusNodes and TextEditingControllers, I went back to square one by incorporating a new page with code straight from Flutter's website, but the TextField in this barebones code still locks up the app.
import 'package:flutter/material.dart';
class EventDetailForm extends StatefulWidget {
static const String routeName = "/events/event-detail-form";
#override
_EventDetailFormState createState() => _EventDetailFormState();
}
class _EventDetailFormState extends State<EventDetailForm> {
final myController = TextEditingController();
#override
void dispose() {
myController.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Event Detail')),
body: Padding(
padding: const EdgeInsets.all(16),
child: TextField(
controller: myController,
)),
floatingActionButton: FloatingActionButton(
onPressed: () {
return showDialog(
context: context,
builder: (context) {
return AlertDialog(
content: Text(myController.text),
);
});
},
child: Icon(Icons.text_fields),
),
);
}
}
Unfortunately, I am not getting any error messages. The cursor just blinks in the TextField and everything else loses function and I have to quit and restart. I am not sure what else I should be considering. Does anyone have any ideas on what might be causing this?
Simulator -> Device -> Erase All Content And Settings works for me.
Had same problem when I upgraded Xcode to ios 13.1. I switched to a different simulator, and the problem went away.
This maybe late, but it happened to me too just today. I also changed the channel to beta but unfortunately did not work too. Apparently what worked for me is when I restarted the simulator after I put back the channel to stable.
I had the same bug, solved by switching to the beta channel of Flutter.
In your terminal use
flutter channel beta
flutter upgrade
About channels you can read here https://github.com/flutter/flutter/wiki/Flutter-build-release-channels
I did not change channel, a simple flutter upgrade was enough to fix this problem. I also closed Android Studio and all simulators and when I restarted, the problem was gone.
I think I am late to the party but the issue still exists in 2021.
I tried all the solutions but couldn't fix it. Whatever I was typing in TextField or TextFormField or autocomplete_textfield, the characters were not visible.
I fixed it by opening the Widget as a showGeneralDialog() instead of using Navigator.of(...). Here is the sample code.
await showGeneralDialog(
barrierColor: AppStyle.primaryColor.withOpacity(0.3),
transitionBuilder: (context, a1, a2, widget) {
return Transform.scale(
scale: a1.value,
child: Opacity(opacity: a1.value, child: WidgetScreenToOpen()),
);
},
transitionDuration: Duration(milliseconds: 500),
barrierDismissible: true,
barrierLabel: 'Label',
context: context,
pageBuilder: (context, animation1, animation2) {
return Container();
}).then((result) {
return result;
});
i am building a mobile app that allows the user to pick the date from a date picker,
when opening the picker screen it overflows from the button
i searched the problem and find the same problem here
https://github.com/flutter/flutter/issues/19744
it is mentioned in the solution that he modified the file " date_picker.dart "
how can i find this file and how to apply these changes
the code i used :
DateTime TodayDate = new DateTime.now();Future<Null> selectDate(BuildContext context) async{
final DateTime Picker = await showDatePicker(
context: context,
initialDate: TodayDate,
firstDate: TodayDate,
lastDate: new DateTime(2021),
);
if (Picker != null && Picker != TodayDate){
print('${TodayDate.toString()} تاريخ الرحلة : ');
setState(() {
TodayDate = Picker;
});
}}
inside the widget build
new RaisedButton(onPressed:(){selectDate(context);},
color: Colors.lightGreen,
textColor: Colors.grey[200],
child: const Text('اختيا تاريخ الرحلة'),
shape: new RoundedRectangleBorder(borderRadius: new BorderRadius.circular(30.0)),
),
Don't.
Editing the file directly is going to break (ie not have your customization) if anyone else tries to run this code on their own machine.
You'll break your own code if you ever update Flutter.
Look into overriding the showDatePicker build() method. Copying its content and adding your customization would be much preferable to actually editing the file. Although - even this still seems very sketchy though. Think about a year down the road when Flutter decides to change the implementation of showDatePicker.build(). Unless you are committed to maintaining this code with every Flutter update, you may be out of luck.
The ideal solution is to request a feature addition, or to do it yourself and try to get it integrated. Obviously if you need this functionality asap that isn't going to help you much.
Edit: There appears to be workaround that involves using a SingleChildScrollView to avoid the overflow - see https://github.com/flutter/flutter/issues/19744#issuecomment-493873347
DateTime dateTime = await showDatePicker(
context: context,
initialDate: DateTime(2000),
firstDate: DateTime(1950),
lastDate: DateTime(DateTime.now().year + 1),
builder: (context, child) {
return SingleChildScrollView(
child: Theme(
child: child,
data: ThemeData.light(),
),
);
});
In Android Studio, select showDatePicker, then press CTRL + F
The file date_picker.dart will open in a new tab. Around line 960 in the file is the ButtonBar you are looking for. Now when you try to edit it, a warning will pop up:
Just press OK and edit as you like. Beware that the changes might be overwritten when you run flutter upgrade. It might be better to copy the whole file into your project to create your own version of the date picker.