@@ -30,6 +30,10 @@ class CardFormField extends StatefulWidget {
3030 this .disabled = false ,
3131 this .controller,
3232 this .preferredNetworks,
33+ this .numberHintText,
34+ this .expirationHintText,
35+ this .cvcHintText,
36+ this .postalCodeHintText,
3337 super .key,
3438 });
3539
@@ -93,6 +97,18 @@ class CardFormField extends StatefulWidget {
9397 /// This value will only be used if your user hasn't selected a network themselves.
9498 final List <CardBrand >? preferredNetworks;
9599
100+ /// Android only: Hint text for the card number field.
101+ final String ? numberHintText;
102+
103+ /// Android only: Hint text for the expiration date field.
104+ final String ? expirationHintText;
105+
106+ /// Android only: Hint text for the cvc field.
107+ final String ? cvcHintText;
108+
109+ /// Android only: Hint text for the postal code field.
110+ final String ? postalCodeHintText;
111+
96112 @override
97113 // ignore: library_private_types_in_public_api
98114 _CardFormFieldState createState () => _CardFormFieldState ();
@@ -207,6 +223,10 @@ class _CardFormFieldState extends State<CardFormField> {
207223 onFocus: widget.onFocus,
208224 countryCode: widget.countryCode,
209225 preferredNetworks: widget.preferredNetworks,
226+ numberHintText: widget.numberHintText,
227+ expirationHintText: widget.expirationHintText,
228+ cvcHintText: widget.cvcHintText,
229+ postalCodeHintText: widget.postalCodeHintText,
210230 );
211231 }
212232
@@ -232,6 +252,10 @@ class _MethodChannelCardFormField extends StatefulWidget {
232252 this .disabled = false ,
233253 this .preferredNetworks,
234254 this .countryCode,
255+ this .numberHintText,
256+ this .expirationHintText,
257+ this .cvcHintText,
258+ this .postalCodeHintText,
235259 }) : assert (constraints == null || constraints.debugAssertIsValid ()),
236260 constraints = (width != null || height != null )
237261 ? constraints? .tighten (width: width, height: height) ??
@@ -251,6 +275,10 @@ class _MethodChannelCardFormField extends StatefulWidget {
251275 final bool dangerouslyUpdateFullCardDetails;
252276 final String ? countryCode;
253277 final List <CardBrand >? preferredNetworks;
278+ final String ? numberHintText;
279+ final String ? expirationHintText;
280+ final String ? cvcHintText;
281+ final String ? postalCodeHintText;
254282
255283 // This is used in the platform side to register the view.
256284 static const _viewType = 'flutter.stripe/card_form_field' ;
@@ -312,6 +340,14 @@ class _MethodChannelCardFormFieldState
312340 Widget build (BuildContext context) {
313341 final style = resolveStyle (widget.style);
314342 // Pass parameters to the platform side.
343+ // Build placeholder map for hint text (Android only)
344+ final placeholder = < String , dynamic > {
345+ if (widget.numberHintText != null ) 'number' : widget.numberHintText,
346+ if (widget.expirationHintText != null ) 'expiration' : widget.expirationHintText,
347+ if (widget.cvcHintText != null ) 'cvc' : widget.cvcHintText,
348+ if (widget.postalCodeHintText != null ) 'postalCode' : widget.postalCodeHintText,
349+ };
350+
315351 final creationParams = < String , dynamic > {
316352 'cardStyle' : style.toJson (),
317353 'postalCodeEnabled' : widget.enablePostalCode,
@@ -326,6 +362,7 @@ class _MethodChannelCardFormFieldState
326362 .toList (),
327363 'disabled' : widget.disabled,
328364 'defaultValues' : {'countryCode' : widget.countryCode},
365+ if (placeholder.isNotEmpty) 'placeholders' : placeholder,
329366 };
330367
331368 Widget platform;
@@ -433,6 +470,20 @@ class _MethodChannelCardFormFieldState
433470 });
434471 }
435472 _lastStyle = style;
473+ // Handle placeholder/hint text changes (Android only)
474+ if (widget.numberHintText != oldWidget.numberHintText ||
475+ widget.expirationHintText != oldWidget.expirationHintText ||
476+ widget.cvcHintText != oldWidget.cvcHintText ||
477+ widget.postalCodeHintText != oldWidget.postalCodeHintText) {
478+ final placeholder = < String , dynamic > {
479+ if (widget.numberHintText != null ) 'number' : widget.numberHintText,
480+ if (widget.expirationHintText != null ) 'expiration' : widget.expirationHintText,
481+ if (widget.cvcHintText != null ) 'cvc' : widget.cvcHintText,
482+ if (widget.postalCodeHintText != null ) 'postalCode' : widget.postalCodeHintText,
483+ };
484+ // Use 'placeholders' as method name - Android delegate uses it as property name
485+ _methodChannel? .invokeMethod ('placeholders' , placeholder);
486+ }
436487 super .didUpdateWidget (oldWidget);
437488 }
438489
0 commit comments