I am trying to add a TextFormField in which while typing text if user want to edit previous typed text he can do so. I want to move the cursor to anywhere position in the typed text and add/remove text. This is Flutter desktop application currently, for which I am asking this question.
Column(children: [
Container(
margin: EdgeInsets.only(top: 10),
height: 140,
child: TextFormField(
controller: footer,
keyboardType: TextInputType.multiline,
cursorColor: Colors.grey[700],
validator: (value) {
if (value!.isEmpty)
return 'Please fill this field';
else
return null;
},
maxLines: 5,
onChanged: (value)
{
initText = footer.text;
globalKey.currentState!
.clearPreviousText(initText);
},
decoration: InputDecoration(
labelText: 'Footer Text',
labelStyle: TextStyle(color: Colors.grey[700]),
contentPadding: EdgeInsets.symmetric(
horizontal: 12, vertical: 15),
border: OutlineInputBorder(
borderSide: BorderSide(
color: Theme.of(context)
.focusColor
.withOpacity(0.2))),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Theme.of(context)
.focusColor
.withOpacity(0.5))),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Theme.of(context)
.focusColor
.withOpacity(0.2))),
),
onTap: () {
},
),
),
Container(
child: KeyboardWidget(
globalKey,
addLine: () {
},
keyboardText: (text) {
print('TEXT TYPED: $text');
setState(
() {
footer.text = text;
footer.selection = TextSelection.collapsed(
offset: footer.text.length);
},
);
},
bottomPadding: 10.0,
keyboardType: 'alphanumeric',
initialText: initText,
hide: false,
),
),
],
)
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:virtual_keyboard_multi_language/virtual_keyboard_multi_language.dart';
class KeyboardWidget extends StatefulWidget {
Function(String) keyboardText;
double bottomPadding;
String keyboardType;
String initialText;
bool hide;
VoidCallback addLine;
KeyboardWidget(
Key? key, {
required this.keyboardText,
required this.bottomPadding,
required this.keyboardType,
required this.initialText,
required this.hide,
required this.addLine,
}) : super(key: key);
@override
State<StatefulWidget> createState() {
// TODO: implement createState
return KeyboardWidgetState();
}
}
class KeyboardWidgetState extends State<KeyboardWidget>
with SingleTickerProviderStateMixin {
late AnimationController _controller;
late Animation<Offset> _offsetAnimation;
late String instructions;
bool shiftEnabled = false;
bool isNumericMode = true;
late bool showKeyboard;
bool capsLockOn = false;
@override
void initState() {
// TODO: implement initState
super.initState();
instructions = widget.initialText;
showKeyboard = false;
_controller = AnimationController(
duration: const Duration(milliseconds: 350),
vsync: this,
);
_offsetAnimation = Tween<Offset>(
begin: const Offset(0.0, 1.5),
end: const Offset(0.0, 0.0),
).animate(CurvedAnimation(
parent: _controller,
curve: Curves.easeInOut,
));
_controller.addStatusListener((status) {
if (status == AnimationStatus.dismissed) {
setState(() {
showKeyboard = false;
});
}
});
if (!widget.hide) {
showKeyboard = true;
_controller.forward();
}
}
void dispose() {
// TODO: implement dispose
_controller.dispose();
super.dispose();
}
_onKeyPress(VirtualKeyboardKey key) {
if (key.keyType == VirtualKeyboardKeyType.String) {
if (capsLockOn) {
instructions = instructions + (key.text!.toUpperCase());
} else {
instructions = instructions + (key.text ?? '');
}
widget.keyboardText(instructions);
} else if (key.keyType == VirtualKeyboardKeyType.Action) {
switch (key.action) {
case VirtualKeyboardKeyAction.Backspace:
if (instructions.isEmpty) break;
instructions = instructions.substring(0, instructions.length - 1);
widget.keyboardText(instructions);
break;
case VirtualKeyboardKeyAction.Space:
instructions = instructions + (key.text ?? '');
widget.keyboardText(instructions);
break;
case VirtualKeyboardKeyAction.Shift:
capsLockOn = !capsLockOn;
break;
case VirtualKeyboardKeyAction.Return:
instructions = instructions + '\n';
widget.keyboardText(instructions);
break;
default:
}
print('TEXT: $instructions');
}
}
clearPreviousText(String text) {
instructions = text;
}
animateKeyboard(value) async {
if (value) {
if (!showKeyboard) {
setState(() {
showKeyboard = value;
});
_controller.forward();
}
} else {
setState(() {
showKeyboard = value;
});
_controller.reverse();
}
}
@override
Widget build(BuildContext context) {
// TODO: implement build
return showKeyboard
? SlideTransition(
position: _offsetAnimation,
child: Container(
width: double.infinity,
margin: EdgeInsets.only(top: 10),
decoration: BoxDecoration(
color: Color(0XFFffffff),
borderRadius: BorderRadius.all(Radius.circular(10)),
boxShadow: [
BoxShadow(
color: Theme.of(context).focusColor.withOpacity(0.1),
blurRadius: 6,
offset: Offset(0, -5)),
],
),
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Container(
padding: EdgeInsets.only(top: 5),
child: ElevatedButton(
style: ElevatedButton.styleFrom(
shape: CircleBorder(side: BorderSide.none),
padding:
EdgeInsets.symmetric(vertical: 5, horizontal: 5),
primary: Colors.grey[300],
),
onPressed: () async {
_controller.reverse();
showKeyboard = false;
},
child: FittedBox(
fit: BoxFit.fill,
child: Icon(
Icons.keyboard_arrow_down,
color: Colors.grey[800],
size: 30,
),
),
),
),
Container(
child: VirtualKeyboard(
width: 600,
textColor: Colors.grey[800]!,
fontSize: 20,
type: widget.keyboardType == 'numeric'
? VirtualKeyboardType.Numeric
: VirtualKeyboardType.Alphanumeric,
onKeyPress: _onKeyPress,
),
),
],
),
),
)
: SizedBox();
}
}
This is my text field and I want to edit the text where cursor is placed right now.
header.selection = TextSelection.collapsed(offset: header.text.length);
This piece of code is only adding text at the end of line no matter where the cursor is placed.
Anyone help me please with this issue.
Thanks
