Understanding the Jank happening AlertDialog with TextField and DropdownButton - flutter

I have AlertDilaog with TextField and DropDownButton.
Problem:
As soon as, I launch the dialog and clicks on textfield, the alertdialog shifts up and label animation in textfield happens. But while happening this I see jank.
And I did profiling and I am still trying to understand the why it is happening.
Here is the screenshot
And here is the profiling file: https://filebin.net/7wulbm9j88m6jjt3
Can anyone help me in understanding what is this VsyncProcessCallback and whatever happening in selected section(brackets)?
I am just trying to find the root cause of the Jank and remove it.
Thank you in advance.
Code of TextField:
Widget _addProtocolTextField(BuildContext context) {
return Container(
height: 7.h,
width: 70.w,
child: TextField(
controller: _protocolNameController,
style: TextStyle(
color: Theme.of(context).textColor,
fontSize: 13.sp,
),
textAlign: TextAlign.left,
maxLines: 1,
decoration: InputDecoration(
labelText: Strings.protocol_name_lable,
labelStyle: TextStyle(color: ColorConstants.primaryColor),
enabledBorder: _getBorder(),
disabledBorder: _getBorder(),
focusedBorder: _getBorder(),
border: _getBorder(),
),
),
);
}
OutlineInputBorder _getBorder() {
return OutlineInputBorder(
borderSide: BorderSide(color: ColorConstants.primaryColor),
);
}

Since this much code is not enough to provide the real solution, you can refer to the following tips:
Don't make Widget with Function, Prefer to make a separate stateless or stateful widget as per your requirement
You can try this on release build to see if it helps: https://flutter.dev/docs/perf/rendering/shader

Related

How to use a responsive text form field widget in flutter?

I'm using "maxLine" as a length for the text form field but it does not fit in different size of phones, what should I put in order to make the length responsive.
The box border should fit on the size of the phone. https://i.stack.imgur.com/Wisa6.png. Here's my code, I'm using onTap in gesture detector to call that widget
Widget buildDescription() => TextFormField(
maxLines: MediaQuery.of(context).size.height.toInt(),
initialValue: widget.description,
style: TextStyle(color: Colors.black, fontSize: 18),
decoration: InputDecoration(
hintText: 'Tell us what you feel',
hintStyle: TextStyle(color: Colors.black54),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(15.0),
borderSide: BorderSide(
color: Colors.grey.shade500,
width: 2,
style: BorderStyle.solid))),
validator: (description) => description != null && description.isEmpty
? "I'm here to listen. Don't hesitate to open up when you're ready"
: null,
onChanged: widget.onChangedDescription,
);
}
The following should make the TextFormField fill the screen and also make the number of lines unlimited.
Expanded(
child: TextFormField(
maxLines: null,
keyboardType: TextInputType.multiline,
expands: true,
),
)
You can put your TextFormField inside an Expanded widget, which will stretch it over the remaining screen space.
// expanded should be used inside rows or columns
return Column(
children: [
DateMarker(...),
HowDidIFailField(...),
// the expanded stretches the view over the remaining space
Expanded(
child: TextFormField(),
),
]
);
A thing to note is that when the keyboard appears, less space is available and the widget will shrink further. Make sure to test with that as well.

WillPopScope does not work from another widget

I have multiple widgets in my flutter app. If I click at another widget, onWillPopScope method which is defined at the top of Widget build(BuildContext context) does not working. Could you give me advice how to fix it? Thanks
See below code:
ExpansionTile(
initiallyExpanded: false,
title:
Text('Solution', style: basicAlertBlack),
children: <Widget>[
Container(
color: Colors.amber.shade50,
height:
MediaQuery
.of(context)
.size
.height /
7,
child: _solutionTextField(),
)
],
),
Code of second widget:
Widget _solutionTextField() {
return TextField(
focusNode: myFocusNode,
keyboardType: TextInputType.multiline,
maxLines: null,
style: solution,
controller: solutionController,
decoration: new InputDecoration(
contentPadding: EdgeInsets.all(8),
focusedBorder: InputBorder.none,
enabledBorder: InputBorder.none,
errorBorder: InputBorder.none,
disabledBorder: InputBorder.none,
hintText: 'Enter a solution'));
}
Can you provide more context, please?
As documentations says:
WillPopScope class
Registers a callback to veto attempts by the user to dismiss the enclosing ModalRoute.
It means that it will be called on pop actions. It could be called from android navigation by clicking the return arrow or iOS by swiping from edge left side to right. And every other pop method that you call via Navigator. So it doesn't have a connection with clicking at Widget.

How do I layer the text box hint in a Flutter text book like in the mock below?

I'm working on my onboarding screens for a Flutter mobile app I'm developing, and I want to make my textboxes look like the mock here below:
The desired goal
I have already created most of the text box, but I can't figure out how to make the hint move to the top of the textbox whenever there is text entered in the box. So far I have the below representation does anyone have a clue on how I could do that?
My current implementation
You can do it by
Container(
margin: EdgeInsets.all(20),
child: TextField(
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Full Name',
),
),
),
Samples:
If I understand your question correctly. What you want is called labelText with floatingLabelBehavior: FloatingLabelBehavior.auto
Example
TextField(
decoration: InputDecoration(
labelText: "Username *",
floatingLabelBehavior: FloatingLabelBehavior.auto,
border: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(8.0))
),
)
)

how can a method return 2 widgets which I would later use in a column

I am trying to create a method that returns a text and a TextInput, instead of using a container I want the widgets to be wrapped easily and sent back, I thought it could be achieved by wrapping the two widgets in ():
Widget customTextFormField(String hintText) {
return(
Align(
alignment: Alignment.centerLeft,
child: Text(
"Password",
style: TextStyle(
fontSize: 16.0
),
),
),
TextFormField(
style: TextStyle(color: Colors.grey),
controller: TextEditingController(text: ""),
autofocus: true,
cursorColor: Colors.blue,
decoration: new InputDecoration(
hintStyle: TextStyle(color: Colors.grey),
contentPadding: EdgeInsets.only(left: 15),
border: new OutlineInputBorder(
borderRadius: BorderRadius.circular(4.0),
),
focusedBorder: OutlineInputBorder(
borderSide: const BorderSide(color: Colors.grey, width: 1.0),
borderRadius: BorderRadius.circular(4.0),
),
),
));
}
I want this to be used in a Column widget. Using the above code doesn't work as () doesn't wrap the two widgets as one. I also used
Return a list of Widgets.
List<Widget> customTextFormField() {
return [
Container(),
TextFormField(),
];
}
Use spread operator inside the column
return Column(children: [
...customTextFormField()
]);
You either want them to return in a Column
return Column(children: [
Align(),
TextFormField()
];
or return a List, to be used in a column or listview for example
List<Widget> customTextFormField(String hintText) {
return [
Align(),
TextFormField(),
];
}
Edit: Returning widgets from methods is considered an anti-pattern. Check this out for more info (watch the video "Widgets vs helper methods"): https://api.flutter.dev/flutter/widgets/StatelessWidget-class.html
When trying to create a reusable piece of UI, prefer using a widget
rather than a helper method. For example, if there was a function used
to build a widget, a State.setState call would require Flutter to
entirely rebuild the returned wrapping widget. If a Widget was used
instead, Flutter would be able to efficiently re-render only those
parts that really need to be updated. Even better, if the created
widget is const, Flutter would short-circuit most of the rebuild work.

TextField with animated hint / label

I want to implement a form containing TextFields. Each field has a label / hint. I want the hint to animate and become a label when the user starts typing. This is a standard Material design pattern, so I expected it to be implemented by the standard Widgets.
Something like this:
It turns out to be very simple.
InputDecoration has a labelText parameter, which does what I wanted.
E.g.
TextField(decoration: InputDecoration(labelText: 'Full name')),
In Flutter, both hint and label are behaving in two different way that hintText will be shown as fixed but the labelText will be(double acting) shown as hint which is animating to the top when the cursor is getting focused.
TextField(decoration: InputDecoration
(
labelText: "Animatable hint",
hintText: "Inanimate hint"
)
)
Difference between labelText and HintText.
labelText : Shows label top of the input field, if it's empty or unfocused. When it get focus, labelText moves to above the input field.
hintText: just shows hint to the user.
TextField(decoration: InputDecoration(labelText: 'labelText'),),
TextField(decoration: InputDecoration(hintText: 'hintText'),),
TextField(decoration:InputDecoration(hintText: 'both', labelText: 'both'),),
more information - TextFormField placeholder
Also it's a good way to make your own Method or widget.(So you can reuse code later)
Example:
//your generator method or you can make your own widget class if you want that.
Widget _entryField(String title, {bool isPassword = false}) {
return Container(
margin: EdgeInsets.symmetric(vertical: 10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
title,
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 15),
),
SizedBox(
height: 10,
),
TextField(
obscureText: isPassword,
decoration: InputDecoration(
//labelText: title , // you can change this with the top text like you want
hintText: "Please enter your $title" ,
border: InputBorder.none,
fillColor: Color(0xfff3f3f4),
filled: true))
],
),
);
}
==============
Edit:
As mentioned by #Evin1_ below.
After reading this article Splitting widgets to methods is a performance antipattern/Iiro Krankka
I found it's better to use StatelessWidget to split your code and functions only for doing Operations.
the reason:
This way, you won’t be rebuilding your static widget trees multiple times for nothing but wasted CPU cycles.
If you really prefer building your widget trees with methods, you might want to take a look at a package called functional_widget by Remi Rousselet.
Also others comments for more information about this topic here difference between functions and classes to create reusable widgets