From b4ca0d2b1d1ebedd0f92e060b1abf289d431160f Mon Sep 17 00:00:00 2001 From: Vishesh Handa Date: Thu, 22 Oct 2020 19:07:53 +0200 Subject: [PATCH] Experiment with trying to render an autocomplete box --- lib/main_autocomplete.dart | 133 +++++++++++++++++++++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 lib/main_autocomplete.dart diff --git a/lib/main_autocomplete.dart b/lib/main_autocomplete.dart new file mode 100644 index 00000000..4a46bd12 --- /dev/null +++ b/lib/main_autocomplete.dart @@ -0,0 +1,133 @@ +import 'package:flutter/material.dart'; + +void main() => runApp(MyApp()); + +class MyApp extends StatelessWidget { + @override + Widget build(BuildContext context) { + return MaterialApp( + title: 'Flutter Show Text Tag Demo', + debugShowCheckedModeBanner: false, + theme: ThemeData( + primarySwatch: Colors.blue, + ), + home: MyHomePage(title: 'Flutter Show Text Tag demo'), + ); + } +} + +class MyHomePage extends StatefulWidget { + MyHomePage({Key key, this.title}) : super(key: key); + + final String title; + + @override + _MyHomePageState createState() => _MyHomePageState(); +} + +class _MyHomePageState extends State { + FocusNode _focusNode = FocusNode(); + GlobalKey _textFieldKey = GlobalKey(); + TextStyle _textFieldStyle = TextStyle(fontSize: 20); + + @override + void initState() { + super.initState(); + } + + // Code reference for overlay logic from MTECHVIRAL's video + // https://www.youtube.com/watch?v=KuXKwjv2gTY + + // I need to paint it exactly where the cursor is + + void showOverlaidTag(BuildContext context, String newText) async { + print('showOverlaidTag: $newText'); + + RenderBox renderBox = _textFieldKey.currentContext.findRenderObject(); + print("render Box: ${renderBox.size}"); + + TextPainter painter = TextPainter( + textDirection: TextDirection.ltr, + text: TextSpan( + style: _textFieldStyle, + text: newText, + ), + maxLines: null, + ); + painter.layout(maxWidth: renderBox.size.width); + + print("Focus Node Offset dx: ${_focusNode.offset.dx}"); + print("Focus Node Offset dy: ${_focusNode.offset.dy}"); + + print("Painter ${painter.width} ${painter.height}"); + + OverlayState overlayState = Overlay.of(context); + OverlayEntry suggestionTagoverlayEntry = OverlayEntry(builder: (context) { + return Positioned( + // Decides where to place the tag on the screen. + top: _focusNode.offset.dy + painter.height + 3, + left: _focusNode.offset.dx + painter.width, + + // Tag code. + child: const Material( + elevation: 4.0, + color: Colors.lightBlueAccent, + child: Text( + 'Show tag here', + style: TextStyle( + fontSize: 20.0, + ), + )), + ); + }); + overlayState.insert(suggestionTagoverlayEntry); + + // Removes the over lay entry from the Overly after 500 milliseconds + await Future.delayed(Duration(milliseconds: 5000)); + suggestionTagoverlayEntry.remove(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text(widget.title), + ), + body: Center( + child: Container( + child: TextField( + focusNode: _focusNode, + key: _textFieldKey, + style: _textFieldStyle, + maxLines: null, + onChanged: (String nextText) { + if (nextText.endsWith('[[')) { + showOverlaidTag(context, nextText); + } + }, + ), + width: 400.0, + ), + ), + ); + } +} + +class Editor extends StatefulWidget { + @override + _EditorState createState() => _EditorState(); +} + +class _EditorState extends State { + @override + Widget build(BuildContext context) { + return Container(); + } +} +// https://pub.dev/packages/rich_input +// https://levelup.gitconnected.com/flutter-medium-like-text-editor-b41157f50f0e + +// https://pub.dev/packages/autocomplete_textfield +// https://pub.dev/packages/flutter_typeahead + +// https://stackoverflow.com/questions/59243627/flutter-how-to-get-the-coordinates-of-the-cursor-in-a-textfield