|
|
@@ -0,0 +1,85 @@ |
|
|
import 'package:flutter/material.dart'; |
|
|
|
|
|
void main() { |
|
|
runApp(MyApp()); |
|
|
} |
|
|
|
|
|
class MyApp extends StatelessWidget { |
|
|
@override |
|
|
Widget build(BuildContext context) { |
|
|
return MaterialApp( |
|
|
home: Scaffold( |
|
|
appBar: AppBar(title: Text('Sample App')), |
|
|
body: CustomEditableText(), |
|
|
), |
|
|
); |
|
|
} |
|
|
} |
|
|
|
|
|
class CustomEditableText extends StatefulWidget { |
|
|
@override |
|
|
_CustomEditableTextState createState() => _CustomEditableTextState(); |
|
|
} |
|
|
|
|
|
class _CustomEditableTextState extends State<CustomEditableText> { |
|
|
final NoUnderlineTextEditingController _controller = |
|
|
NoUnderlineTextEditingController(decorationColor: Colors.green); |
|
|
|
|
|
@override |
|
|
Widget build(BuildContext context) { |
|
|
return Padding( |
|
|
padding: const EdgeInsets.all(8.0), |
|
|
child: EditableText( |
|
|
controller: _controller, |
|
|
focusNode: FocusNode(), |
|
|
style: TextStyle(fontSize: 18, color: Colors.black), |
|
|
cursorColor: Colors.blue, |
|
|
backgroundCursorColor: Colors.grey, |
|
|
keyboardType: TextInputType.multiline, |
|
|
minLines: 1, |
|
|
maxLines: null, |
|
|
autocorrect: true, |
|
|
), |
|
|
); |
|
|
} |
|
|
} |
|
|
|
|
|
class NoUnderlineTextEditingController extends TextEditingController { |
|
|
final Color decorationColor; |
|
|
|
|
|
NoUnderlineTextEditingController({required this.decorationColor}); |
|
|
|
|
|
TextSpan buildTextSpan( |
|
|
{required BuildContext context, |
|
|
TextStyle? style, |
|
|
required bool withComposing}) { |
|
|
assert(!value.composing.isValid || |
|
|
!withComposing || |
|
|
value.isComposingRangeValid); |
|
|
final bool composingRegionOutOfRange = |
|
|
!value.isComposingRangeValid || !withComposing; |
|
|
|
|
|
if (composingRegionOutOfRange) { |
|
|
return TextSpan(style: style, text: text); |
|
|
} |
|
|
|
|
|
final TextStyle composingStyle = style?.merge(TextStyle( |
|
|
decoration: TextDecoration.underline, |
|
|
decorationColor: decorationColor, |
|
|
)) ?? |
|
|
TextStyle( |
|
|
decoration: TextDecoration.underline, |
|
|
decorationColor: decorationColor); |
|
|
return TextSpan( |
|
|
style: style, |
|
|
children: <TextSpan>[ |
|
|
TextSpan(text: value.composing.textBefore(value.text)), |
|
|
TextSpan( |
|
|
style: composingStyle, |
|
|
text: value.composing.textInside(value.text), |
|
|
), |
|
|
TextSpan(text: value.composing.textAfter(value.text)), |
|
|
], |
|
|
); |
|
|
} |
|
|
} |