I am engaged on a TextField
in Flutter and attempting to realize the next:
- Prefix Textual content Alignment: I would like the prefix textual content (e.g., “To:”) to be seen always, even when the consumer hasn’t targeted on the
TextField
. - Cursor Alignment: I would like the cursor to seem on the identical line because the prefix textual content, not increased or decrease than the prefix.
- Trace Textual content: I additionally need the trace textual content (e.g., “Title, $Cashtag, Cellphone, Electronic mail”) to stay seen when the
TextField
is empty, however I do not need the cursor or trace textual content to overlap with the prefix textual content.
What I’ve Tried:
- Utilizing
prefixText
to show the prefix textual content, however this works solely when theTextField
is targeted and would not align properly with the cursor. - Utilizing
prefixIcon
withPadding
andAlign
to try to alter the alignment, however it causes the cursor and trace textual content to vanish. - I’ve additionally tried setting
cursorColor
,border: InputBorder.none
, and adjusting the padding to no avail.
Code:
TextField(
cursorColor: Colours.inexperienced, // Set the cursor colour
ornament: InputDecoration(
hintText: 'Title, $Cashtag, Cellphone, Electronic mail',
border: InputBorder.none, // Take away the border
prefixText: 'To ', // Prefix textual content earlier than enter
prefixStyle: TextStyle(
colour: Colours.black, // Prefix textual content colour
fontSize: 18, // Prefix textual content measurement
fontWeight: FontWeight.daring, // Prefix textual content weight
),
),
)
Full code (For Context):
// payment_details_screen.dart
import 'package deal:cashapp/utilities/colours.dart';
import 'package deal:flutter/materials.dart';
import 'package deal:flutter_screenutil/flutter_screenutil.dart';
class PaymentDetailsScreen extends StatelessWidget {
const PaymentDetailsScreen({tremendous.key});
@override
Widget construct(BuildContext context) {
return Scaffold(
backgroundColor: Colours.white,
physique: SafeArea(
youngster: Column(
youngsters: [
SizedBox(
height: 8.h,
),
// Header with amount and bank selection
Padding(
padding: EdgeInsets.only(right: 12.w),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
IconButton(
icon: const Icon(
Icons.close,
color: Colors.black,
size: 30,
),
onPressed: () => Navigator.pop(context),
),
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text(
'$7,000',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
Padding(
padding: EdgeInsets.only(left: 16.w),
child: InkWell(
onTap: () {
// Show bank selection
},
child: Row(
children: const [
Text(
'Cash Balance',
style: TextStyle(
color: gray2,
fontSize: 14,
),
),
Icon(Icons.keyboard_arrow_down,
color: Colors.grey),
],
),
),
),
],
),
ElevatedButton(
onPressed: () {
// Deal with fee
},
fashion: ElevatedButton.styleFrom(
elevation: 0.0,
padding:
EdgeInsets.symmetric(horizontal: 24, vertical: 10),
backgroundColor: green3,
form: RoundedRectangleBorder(
borderRadius: BorderRadius.round(100),
),
minimumSize:
Measurement(60, 32), // Set width to 60 and top to 32
),
youngster: const Textual content(
'Pay',
fashion: TextStyle(colour: Colours.white, fontSize: 18),
),
),
],
),
),
Divider(
colour: gray5,
thickness: 1.5,
top: 32.h,
),
// Enter fields
const SizedBox(width: 16),
TextField(
cursorColor: green3, // Set the cursor colour to inexperienced
ornament: InputDecoration(
hintText: 'Title, $Cashtag, Cellphone, Electronic mail',
hintStyle: TextStyle(
colour: Colours.gray), // Elective, for trace textual content colour
border: InputBorder.none, // Take away the border
prefixText: 'To ', // Prefix textual content earlier than enter
prefixStyle: TextStyle(
colour: Colours.black, // Prefix textual content colour
fontSize: 18, // Prefix textual content measurement
fontWeight: FontWeight.daring, // Prefix textual content weight
),
),
),
Divider(
colour: gray5,
thickness: 1.5,
top: 32.h,
),
// Enter fields
TextField(
cursorColor: green3, // Set the cursor colour to inexperienced
ornament: InputDecoration(
hintText: 'Title, $Cashtag, Cellphone, Electronic mail',
border: InputBorder.none, // Take away the border
prefixText: 'For ', // Prefix textual content earlier than enter
prefixStyle: TextStyle(
colour: Colours.black, // Prefix textual content colour
fontSize: 18, // Prefix textual content measurement
fontWeight: FontWeight.daring, // Prefix textual content weight
),
),
),
// Fee sort selector
SingleChildScrollView(
scrollDirection:
Axis.horizontal, // Make the row scrollable horizontally
youngster: Row(
youngsters: [
const Text('Send as'),
const SizedBox(width: 16),
ElevatedButton(
onPressed: () {},
style: ElevatedButton.styleFrom(
backgroundColor: const Color(0xFF24CE84),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
),
),
child: const Text('Cash'),
),
const SizedBox(width: 8),
OutlinedButton(
onPressed: () {},
style: OutlinedButton.styleFrom(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
),
),
child: Row(
children: const [
Text('Gift Card'),
Icon(Icons.keyboard_arrow_down),
],
),
),
const SizedBox(width: 8),
OutlinedButton(
onPressed: () {},
fashion: OutlinedButton.styleFrom(
form: RoundedRectangleBorder(
borderRadius: BorderRadius.round(20),
),
),
youngster: Row(
youngsters: const [
Text('Stock'),
Icon(Icons.keyboard_arrow_down),
],
),
),
const SizedBox(width: 8),
OutlinedButton(
onPressed: () {},
fashion: OutlinedButton.styleFrom(
form: RoundedRectangleBorder(
borderRadius: BorderRadius.round(20),
),
),
youngster: Row(
youngsters: const [
Text('Stock'),
Icon(Icons.keyboard_arrow_down),
],
),
),
],
),
),
// Urged contacts
Column(
crossAxisAlignment: CrossAxisAlignment.begin,
youngsters: [
const Text(
'SUGGESTED',
style: TextStyle(
color: Colors.grey,
fontSize: 12,
),
),
const SizedBox(height: 16),
_buildContactTile(
'J',
'Jay Z',
'$sc',
Colors.brown,
isSelected: true,
),
_buildContactTile(
'D',
'Diego',
'$dm',
Colors.purple,
),
_buildContactTile(
'S',
'Sandy G.',
'$sandy',
Colors.deepOrange,
),
_buildContactTile(
'J',
'Diego Martinez',
'$dm',
Colors.purple,
),
],
),
],
),
),
);
}
Widget _buildContactTile(
String preliminary,
String title,
String tag,
Shade avatarColor, {
bool isSelected = false,
}) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0),
youngster: Row(
youngsters: [
SizedBox(
width: 24,
height: 24,
child: Checkbox(
value: isSelected,
onChanged: (value) {},
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(4),
),
),
),
const SizedBox(width: 12),
CircleAvatar(
backgroundColor: avatarColor,
child: Text(
initial,
style: const TextStyle(color: Colors.white),
),
),
const SizedBox(width: 12),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
name,
style: const TextStyle(fontWeight: FontWeight.bold),
),
Text(
tag,
style: const TextStyle(color: Colors.grey),
),
],
),
),
const Icon(Icons.person_outline),
],
),
);
}
}
What I am attempting to realize:
enter picture description right here
Full Display(For context):
Downside:
- The prefix textual content would not keep seen when the
TextField
is targeted, and when it does seem, it is not correctly aligned with the cursor. - The cursor will not be showing on the similar degree because the prefix textual content, inflicting misalignment.
How can I correctly align the prefix textual content with the cursor, and make sure the prefix textual content stays seen even when the consumer will not be targeted on the TextField
?