Flutter -如何实现内联编辑?

wgeznvg7  于 2022-12-24  发布在  Flutter
关注(0)|答案(3)|浏览(136)

我在Safari上发现了类似的行为:

e3bfsja2

e3bfsja21#

问题陈述是,在点击正常文本时,文本字段应该是可编辑的,我们可以编辑文本。
Have an example
在这个场景中,我们可以看到点击初始文本时,可编辑文本字段是如何显示的,我们可以编辑文本。
我们先从流程开始:
首先,我们必须初始化变量。

bool _isEditingText = false;
TextEditingController _editingController;
String initialText = "Initial Text";

1._isEditingText是布尔变量,我们必须将其设置为false,因为当用户点击文本时,我们必须将其设置为true。

  1. TextEditingController -每当用户使用关联的TextEditingController修改文本字段时,文本字段进行编辑,控制器通知监听器。监听器然后可以读取用户键入并更新的文本和选择属性。基本上,文本编辑控制器用于从文本字段获取更新的值。
  2. initialText -初始值,设置为文本。
    当我们使用任何类型的控制器时,我们都必须初始化和处理控制器。
    因此,首先在init状态下初始化控制器。
@override
void initState() {
  super.initState();
  _editingController = TextEditingController(text: initialText);
}
@override
void dispose() {
  _editingController.dispose();
  super.dispose();
}

删除State对象时调用“dispose()”,该对象是永久性的。
此方法用于取消订阅和取消所有动画、流等。
当此状态对象将永远不会再次生成时,框架调用此方法。

@override
Widget build(BuildContext context) {

  return Scaffold(
    appBar: AppBar(
      title: Text("'Editable Text"),
    ),
    body: Center(
        child: _editTitleTextField(),
    ),
  );
}

在构建小部件中,我只是显示一个widget _editTitleTextField()。

Widget _editTitleTextField() {
  if (_isEditingText)
    return Center(
      child: TextField(
        onSubmitted: (newValue){
          setState(() {
            initialText = newValue;
            _isEditingText =false;
          });
        },
        autofocus: true,
        controller: _editingController,
      ),
    );
  return InkWell(
    onTap: () {
      setState(() {
        _isEditingText = true;
      });
    },
    child: Text(
  initialText,
  style: TextStyle(
    color: Colors.black,
    fontSize: 18.0,
  ),
 );
}

因此,_editTitleTextField()小部件的确切作用是,如果_isEditingText的值为false,则只显示文本,并在点击文本时将_isEditingText的值设置为true。
当_isEditingText为true时,_editTitleTextField返回文本字段。Textfield具有参数onSubmitted,因此在onSubmitted方法中,新值被分配给initialText,该值是从_editingController获取的更新值。
答答!这样我们使文本可编辑并更新文本的值!

ctrmrzij

ctrmrzij2#

这可以通过一个跟踪状态的StatefulWidget来实现,例如使用一个布尔值。假设这个布尔值名为editing。当editing == false时,您显示一个Text小部件,其中包含要显示的文本, Package 在tap的处理程序中,例如GestureDetector。当用户点击时,状态更改为editing = true。在此状态下,您将显示具有此值的TextField。您可以在此StatefulWidget中使用TextEditingController,并在此更新其值。这将允许您在用户点击并更改为编辑状态时选择所有文本

qgelzfjb

qgelzfjb3#

我相信这是正确的答案:

class InlineEditableText extends StatefulWidget {
  const InlineEditableText({
    Key? key,
    required this.text,
    required this.style,
  }) : super(key: key);

  final String text;
  final TextStyle style;

  @override
  State<InlineEditableText> createState() => _InlineEditableTextState();
}

class _InlineEditableTextState extends State<InlineEditableText> {
  var _isEditing = false;
  final _focusNode = FocusNode();
  late String _text = widget.text;
  late final TextStyle _style = widget.style;
  late TextEditingController _controller;

  @override
  void initState() {
    _controller = TextEditingController(text: _text);
    _focusNode.addListener(() {
      if (!_focusNode.hasFocus) {
        setState(() => _isEditing = false);
      } else {
        _controller.selection = TextSelection(
          baseOffset: 0,
          extentOffset: _controller.value.text.runes.length,
        );
      }
    });
    super.initState();
  }

  @override
  void dispose() {
    _controller.dispose();
    _focusNode.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onDoubleTap: () => setState(() {
        _isEditing = !_isEditing;
        _focusNode.requestFocus();
      }),
      child: TextField(
        maxLines: 1,
        style: _style,
        focusNode: _focusNode,
        controller: _controller,
        onSubmitted: (changed) {
          setState(() {
            _text = changed;
            _isEditing = false;
          });
        },
        showCursor: _isEditing,
        cursorColor: Colors.black,
        enableInteractiveSelection: _isEditing,
        decoration: InputDecoration(
          isDense: true,
          contentPadding: const EdgeInsets.symmetric(
            horizontal: 0,
            vertical: 4.4,
          ),
          border: _isEditing
              ? const OutlineInputBorder(
                  borderRadius: BorderRadius.all(Radius.circular(0)),
                )
              : InputBorder.none,
        ),
      ),
    );
  }
}

相关问题