I am using pin_code_text_field package to create pin code textfields. But when I was updating the bool value used to obscure text. Bool value is not updating in pin code fields until I click on textfields.
Code was added below:
bool pinWasObscured = true;
Row(
children: [
PinCodeTextField(
maxLength: 4,
hideCharacter: pinWasObscured,
highlight: true,
highlightAnimation: true,
highlightAnimationBeginColor: Colors.black,
highlightAnimationEndColor: Colors.white,
highlightAnimationDuration: Duration(seconds: 5),
highlightColor: Color(0xFFF37021),
pinBoxDecoration: ProvidedPinBoxDecoration.underlinedPinBoxDecoration,
maskCharacter: "*",
pinTextStyle: TextStyle(
fontSize: 15.sp,
fontWeight: FontWeight.bold,
),
pinBoxWidth: SizeConfig.blockSizeHorizontal! * 12,
pinBoxHeight: SizeConfig.blockSizeHorizontal! * 10,
autofocus: false,
controller: pinController,
defaultBorderColor: Colors.black26,
),
SizedBox(width: 10),
IconButton(
icon: pinWasObscured
? Icon(Icons.visibility_off_outlined)
: Icon(Icons.visibility_outlined),
onPressed: () {
setState(() {
pinWasObscured = !pinWasObscured;
});
},
),
],
),
the issue is that you are also updating the value of the "hideCharacter" on the click of item. you dont have to update the hideCharacter value everytime.
instead you have to set the value to true if you want to hide the character and false to show.
Related
On my flutter webapp I am trying to show the password if the user chose to show it. If I set my bool value to false it start by showing the normal text and then if I press the button to show or hide the password it will obscure the text but it will not un-obscure the text. I added a print function in one of my try's and it does change the bool value from false to true and back to false. I have it it a setState but no luck. I tryied many different examples online but can not get it to work with the web app.
The code
#override
Widget build(BuildContext context) {
c_width = MediaQuery.of(context).size.width*0.8;
return Scaffold(
appBar: AppBar(title: Text("App"),
),
body: signUpWidget(widget.signUpValue),
);
}
Widget signUpWidget(String? rl) {
switch(rl) {
case 'User': {
return SingleChildScrollView(
child: Container (
width: c_width,
padding: const EdgeInsets.all(16.0),
child: Column(
child: Column(
children: <Widget>[
TextFormField(
obscureText: isObscure,
decoration: InputDecoration(
suffix: TextButton(
child: isPasswordObscure
? Text(
'Show',
style: TextStyle(color: Colors.grey),
)
: Text(
'Hide',
style: TextStyle(color: Colors.grey),
),
onPressed: () {
setState(() {
isObscure = !isObscure;
isPasswordObscure = !isObscure;
});
},
),
),
),
Like I say it changes the text to hide and show and if I print the bool value it changes from true to false, but it does not unObscure the text in the field to show the password. Is it something to do with web? or am I missing something?
Thank you.
Actually you dont need to have two bool,
TextFormField(
obscureText: isObscure,
decoration: InputDecoration(
suffix: TextButton(
child: isObscure //< using
? Text(
'Show',
style: TextStyle(color: Colors.grey),
)
: Text(
'Hide',
style: TextStyle(color: Colors.grey),
),
onPressed: () {
setState(() {
isObscure = !isObscure;
// isPasswordObscure = !isObscure; // here it reverse the variable isPasswordObscure
});
},
),
),
)
It might be occurring due to this problem in setState((){}).
setState(() {
// assume isObscure is true initially
isObscure = !isObscure;
// now isObscure is false
isPasswordObscure = !isObscure;
// now isPasswordObscure is true, because isObscure's value has already changed.
});
To solve this, first save isObscure to a temporary variable.
setState(() {
var temp = isObscure;
isObscure = !temp;
isPasswordObscure = !temp;
});
Or,
Entirely avoid using two bools.
setState(() {
isObscure = !isObscure;
});
It seems like this occurs only in web.
Follow these steps to fix this,
https://github.com/flutter/flutter/issues/83695#issuecomment-1083537482
Or
Upgrade to the latest Flutter version.
I have used a package group_button 4.2.1 but once i select the textfields the radio buttons deselect and i have to select again, i have tried using the controller property of the Widget but i didn't get it to work.
I was thinking if i can make a container from scratch that is a radio button and can retain the value once i finish filling the form to be submitted to my firestore database.
You can use List of button text and keep tract of selectedIndex.
Run on dartPad
int? _selectedValueIndex;
List<String> buttonText = ["ForSale", "For rent"];
Widget button({required String text, required int index}) {
return InkWell(
splashColor: Colors.cyanAccent,
onTap: () {
setState(() {
_selectedValueIndex = index;
});
},
child: Container(
padding: const EdgeInsets.all(12),
color: index == _selectedValueIndex ? Colors.blue : Colors.white,
child: Text(
text,
style: TextStyle(
color: index == _selectedValueIndex ? Colors.white : Colors.black,
),
),
),
);
}
Inside build method to use this,
Row(
children: [
...List.generate(
buttonText.length,
(index) => button(
index: index,
text: buttonText[index],
),
)
],
),
I have a code whereby the genders of a pet is listed in two separate cards and when the user taps on one of them, it changes color to indicate that it has been selected and is saved in the database. However, the app is letting the user continue to the next page without choosing any one of the values. I want to do a validation whereby the user will have to choose one of the cards to be able to move forward. How can I do this please?
Here is my code:
Expanded(
child: GridView.count(
crossAxisCount: 2,
primary: false,
scrollDirection: Axis.vertical,
children: List.generate(petGenders.length, (index) {
return GestureDetector(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12.0)),
color:
selectedIndex == index ? primaryColor : null,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
petGenders[petKeys[index]],
SizedBox(
height: 15.0,
),
Text(
petKeys[index],
style: TextStyle(
color: selectedIndex == index
? Colors.white
: null,
fontSize: 18.0,
fontWeight: FontWeight.w600),
),
],
),
),
),
onTap: () {
setState(() {
widget.pet.gender = petKeys[index];
selectedIndex = index;
});
});
}),
),
),
The model:
Map<String, Image> genders() => {
"Male":
Image(image: AssetImage('Assets/images/male.png'), width: 50),
"Female":
Image(image: AssetImage('Assets/images/female.png'), width: 50)
};
Take one variable
bool isGenderSelected = false;
Then change its value to true on tap of card like
onTap: () {
setState(() {
isGenderSelected = true;
widget.pet.gender = petKeys[index];
selectedIndex = index;
});
});
Now check if it's true then only allow the user to go next page or show some message to the user
Scenario like this, I prefer using nullable selectedValue. In this case, I will create nullable int to hold and switch between selection.
int? selectedIndex;
And using color will be like
color: selectedIndex==index? SelectedColor:null,
you can replace null with inactive color.
For validation part, do null check on selectedIndex .
if(selectedIndex!=null){.....}
There is no cursor while entering OTP, How can add Cursor in pinFieldAutoFill. I am using the sms_autofill: ^1.2.5 package.
PinFieldAutoFill(
autofocus: true,
keyboardType: TextInputType.number,
decoration: UnderlineDecoration(
textStyle: TextStyle(
fontSize: 44.sp,
fontWeight: FontWeight.bold,
color: kDarkBlue),
colorBuilder: FixedColorBuilder(
Colors.grey),
),
currentCode: authService
.loginMobileOTP, // prefill with a code
onCodeSubmitted: (_) async {
authService.login(
context, _scaffoldKey);
},
onCodeChanged: (value) {
authService.loginMobileOTP =
value;
},
codeLength:
6 //code length, default 6
),
Please enable cursor option in "sms_autofill" package, class constructer "PinInputTextField".
Sharing reference code
return PinInputTextField(
pinLength: widget.codeLength,
decoration: widget.decoration,
cursor: Cursor(
width: 2,
height: 40,
color: Colors.red,
radius: Radius.circular(1),
enabled: true,
),
I have a list of expansion tiles and each of these tiles have 3 radio buttons each. I want to set some radio buttons checked by default when the page is loaded. How can I do this? Please help.
RadioButtonGroup(
activeColor: Color(ProjectColors.mainColor),
labelStyle: TextStyle(
fontFamily: "AN",
fontSize: 16,
fontWeight: FontWeight.w400,
color: Color(ProjectColors.secondaryColor),
),
labels: _role.values.map((x) => x.title).toList(),
)
Code is below:
String _picked = "Two"; //a variable _picked declared
RadioButtonGroup(
orientation: GroupedButtonsOrientation.HORIZONTAL,
margin: const EdgeInsets.only(left: 12.0),
onSelected: (String selected) => setState((){
_picked = selected;
}),
labels: <String>[
"One",
"Two",
],
picked: _picked,
itemBuilder: (Radio rb, Text txt, int i){
return Column(
children: <Widget>[
Icon(Icons.public),
rb,
txt,
],
);
},
),
Output: