import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_form_builder/flutter_form_builder.dart';
import 'package:paylater/res/asset_strings.dart';
import 'package:paylater/res/motito_colors.dart';
import 'package:paylater/res/string_en.dart';
import 'package:paylater/res/style.dart';
import 'package:paylater/screens/motito_stepper.dart';
import 'package:paylater/screens/reset_password_verify.dart';
import 'package:paylater/util/validator.dart';
import 'package:paylater/widget/motito_dialog.dart';
import 'package:paylater/widget/motito_flat_button.dart';
class Resetsteps extends StatefulWidget {
@override
_ResetstepsState createState() => _ResetstepsState();
}
class _ResetstepsState extends State<Resetsteps> {
final _formKey = GlobalKey<FormBuilderState>();
final _phoneController = TextEditingController();
bool phoneFieldEmpty = true;
@override
Widget build(BuildContext context) {
MotitoDialog md = MotitoDialog(
context,
isDismissible: false,
);
md.style(
borderRadius: 8.0,
messageTextStyle: CustomTextStyles.kBody.copyWith(
color: MotitoColors.kNeutralsGrey4,
fontSize: 14.0,
),
);
return MotitoStepper(
step: 1,
total: 3,
leading: GestureDetector(onTap: () {}, child: Icon(CupertinoIcons.arrow_left),),
helpMessage: 'I need help on the forgot my password page',
body: SingleChildScrollView(
child: FormBuilder(
key: _formKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(height: 50.0),
Text(
'Forgot my Password',
style: CustomTextStyles.kHeader3.copyWith(
color: MotitoColors.kSecondaryTextColor1,
),
),
SizedBox(height: 2.0),
Text(
'Please type in your phone number and we will send you a 6 digit code',
style: CustomTextStyles.kBody.copyWith(
color: MotitoColors.kNeutralsGrey5,
fontSize: 14.0,
),
),
SizedBox(height: 32.0),
textFieldLabel(
StringEn.kPhoneNumber,
required: true,
),
TextFormField(
textInputAction: TextInputAction.next,
inputFormatters: [
FilteringTextInputFormatter.digitsOnly,
],
controller: _phoneController,
keyboardType: TextInputType.phone,
decoration: inputDecoration(
context,
hint: StringEn.kPhoneHint,
prefixText: '( 233)',
),
onChanged: (phone) {
if (phone != null && phone.isNotEmpty) {
setState(() {
phoneFieldEmpty = false;
});
} else {
setState(() {
phoneFieldEmpty = true;
});
}
},
validator: FormBuilderValidators.compose([
FormBuilderValidators.minLength(context, 9,
errorText: AssetStrings.kInvalidPhone),
FormBuilderValidators.maxLength(context, 10,
errorText: AssetStrings.kInvalidPhone),
Validator.leadingZeroValidator,
]),
),
SizedBox(height: 8.0),
SizedBox(height: 120.0),
I am a junior intern and was assigned a task to add a new feature on an existing app. I am all done with the UI but cant get a particular function on my code to work here is the code for the button and I want the text to change on the button to "Loading...".
What can I do to achieve that?
MotitoFlatButton(
label: StringEn.kContinue,
enabled: !phoneFieldEmpty,
onTap: () {
if (_formKey.currentState.validate()) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ResetPasswordVerify()));
}
},
),
SizedBox(height: 56.0),
],
),
),
),
);
}
}
Here is also the code for the button widget.
import 'package:flutter/material.dart';
import 'package:paylater/res/motito_colors.dart';
import 'package:paylater/res/style.dart';
const _buttonRadius = 8.0;
class MotitoFlatButton extends StatelessWidget {
final String label;
final VoidCallback onTap;
final Color bg;
final Color textColor;
final Color disabledBg;
final Color disabledTextColor;
final double width;
final bool enabled;
const MotitoFlatButton({
@required this.label,
@required this.onTap,
this.bg = MotitoColors.kMotitoBlue,
this.textColor = Colors.white,
this.disabledBg = MotitoColors.kButtonDisabled,
this.disabledTextColor = MotitoColors.kButtonDisabledText,
this.width = double.infinity,
this.enabled = true,
});
@override
Widget build(BuildContext context) {
return Material(
borderRadius: BorderRadius.circular(_buttonRadius),
child: InkWell(
onTap: enabled ? onTap : null,
borderRadius: BorderRadius.circular(_buttonRadius),
child: Ink(
padding: const EdgeInsets.symmetric(vertical: 16.0),
width: width,
decoration: BoxDecoration(
color: enabled ? bg : disabledBg,
borderRadius: BorderRadius.circular(_buttonRadius),
),
child: Center(
child: Text(
label,
style: CustomTextStyles.kBody
.copyWith(color: enabled ? textColor : disabledTextColor),
),
),
),
),
);
}
}
I have tried my best and can't get it to work.
CodePudding user response:
You could try to wrap the Button with a GestureDetector and set the State of the String you give threw to the Button Widget with setState, this should work:
GestureDetector(
onTap:(){
setState(() {
yourString = "Loading..."
});
},
child: YourButton(yourstring),
)
CodePudding user response:
Whenever you want to make UI changes you have to call setState
Calling setState notifies the framework that the internal state of this object has changed in a way that might impact the user interface in this subtree, which causes the framework to schedule a build for this State object
So in your particular case I would change that button to a Statefull widget (right click on Stateless and Refactor) and then on your onTap function you can just put:
child: ElevatedButton(
onPressed: () {
setState(
() {
isLoading = true;
},
);
},
child: isLoading ? Text('Loading...') : Text('Click me'),
),
So now whenever you click your button it's state will change and your UI should be updated
Also you could put a loading indicator there instead of just text like this:
child: ElevatedButton(
onPressed: () {
setState(
() {
isLoading = true;
},
);
},
child: isLoading
? Text('Loading...')
: Center(
child: CircularProgressIndicator(
strokeWidth: 2.0,
),
),
),
Hope that helps! ^^