gpt4 book ai didi

Flutter - 如何在 TextField 中获取光标的坐标?

转载 作者:行者123 更新时间:2023-12-04 12:18:20 45 4
gpt4 key购买 nike

需要知道TextField中当前光标位置的dx和dy坐标。这是实现提及/标签功能所必需的,其中需要在 TextField 光标下方几个像素处显示一个弹出窗口。

最佳答案

您可以使用 FocusNode获取文本字段本身的偏移量。然后使用 TextPainter类来计算布局宽度,如此处所示 post并使用它来定位您的标签。然后也许使用一些覆盖逻辑来显示标签,如图所示 here .

  • 创建一个 FocusNode对象并将其附加到文本字段。
  • 然后在 onChanged回调或其 TextEditingController的回调继续使用 FocusNode.offset.dx 定位标签的逻辑。和 FocusNode.offset.dy .
  • FocusNode仅提供边界矩形偏移。所以你需要一个 TextPainter实例来计算新输入文本的宽度。为此,您将需要 TextStyle提前定义。
  • 使用 2 和 3 中的值计算标签的位置,并为视觉美感增加一些额外的偏移量。

  • 以下代码是使用上述技术的示例。此解决方案的实时版本可在此 dartpad 中获得.

    // Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
    // for details. All rights reserved. Use of this source code is governed by a
    // BSD-style license that can be found in the LICENSE file.

    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<MyHomePage> {

    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

    showOverlaidTag(BuildContext context, String newText) async {

    TextPainter painter = TextPainter(
    textDirection: TextDirection.ltr,
    text: TextSpan(
    style: _textFieldStyle,
    text: newText,
    ),
    );
    painter.layout();


    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 + 10,

    // Tag code.
    child: 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: 500));
    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,
    onChanged: (String nextText) {
    showOverlaidTag(context, nextText);
    },
    ),
    width: 400.0,
    ),
    ),
    );
    }
    }


    下面显示了其外观的屏幕截图。如果您要使用它,您必须调整位置以满足您的需要以及覆盖的持续时间/可见性逻辑。

    enter image description here

    关于Flutter - 如何在 TextField 中获取光标的坐标?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59243627/

    45 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com