0

所以我有这个独特的要求,如下图所示,其中蓝色文本是用户输入。我一直在对此进行自己的研究,并找到了一些可行的解决方案,其中一种定制TextEditingController似乎最有希望。我还没有开始实施,但我想不到,我想我以后可能会遇到触摸和光标控件的一些问题。

现在我的问题是,有没有更好的方法我可能会忽略?有没有办法优雅地处理哪些区域是可触摸的,在删除时处理光标,以及移动到下一个焦点?

在此处输入图像描述

4

2 回答 2

2

正如@Andrey Gordeev 所建议的,我们可以使用Wrap Widgetachildren定义如下:

Wrap(
  alignment: WrapAlignment.center,
  runAlignment: WrapAlignment.center,
  children: [
    const Text('Hala, we\'re '),
    SizedBox(
      width: 50,
      height: 20,
      child: TextField(
        controller: TextEditingController.fromValue(
          const TextEditingValue(text: 'aryab'),
        ),
      ),
    ),
    const Text(' You? I\'m '),
    SizedBox(
      width: 150,
      height: 20,
      child: TextField(
        controller: TextEditingController.fromValue(
          const TextEditingValue(text: 'Someone Awesome'),
        ),
      ),
    ),
  ],
)

这呈现了所附屏幕截图的结果:

截屏

一个完整的示例片段可以在下面找到:

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      title: 'Demo',
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key}) : super(key: key);

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: 
        Wrap(
          alignment: WrapAlignment.center,
          runAlignment: WrapAlignment.center,
          children: [
            const Text('Hala, we\'re '),
            SizedBox(
              width: 50,
              height: 20,
              child: TextField(
                controller: TextEditingController.fromValue(
                  const TextEditingValue(text: 'aryab'),
                ),
              ),
            ),
            const Text(' You? I\'m '),
            SizedBox(
              width: 150,
              height: 20,
              child: TextField(
                controller: TextEditingController.fromValue(
                  const TextEditingValue(text: 'Someone Awesome'),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}
于 2021-10-28T13:09:39.193 回答
1

虽然有两种类型的小部件,<plainText,inputText>可以放在此处,我们需要关注从表单/文本中检索全文。

我认为,为小部件创建地图将是一个不错的选择。

  final Map<String, String?> _textsInForm = {
    "Hala, we're": null,
    "aryab": "groupName",
    ". You? I'm": null,
    "Someone Awysome": "myself",
    ",a": null,
    "Driver": "job",
  };

如您所见,我将key其用作主要值和value可空字符串。如果我们找到空字符串,它将只是Text小部件,否则TextFiled

RichText用来处理这种情况。

我们将为List<InlineSpan>RichText处理List<TextEditingController>输入文本创建列表。

我正在使用StatelessWidget,同时stateFullWidgetinitState.

有一个问题,它采用最小提示文本宽度。您可以尝试使用传递文本来TextEditingController代替。

在此处输入图像描述

import 'package:flutter/material.dart';

class SomeTextEditable extends StatelessWidget {
  SomeTextEditable({Key? key}) : super(key: key);

  final Map<String, String?> _textsInForm = {
    "Hala, we're": null,
    "aryab": "groupName",
    ". You? I'm": null,
    "Someone Awysome": "myself",
    ",a": null,
    "Driver": "job",
  };

  final TextStyle _hintTextStyle = const TextStyle(
    color: Colors.grey,
  );

  final TextStyle _textFiledStyle = const TextStyle(
    color: Colors.blue,
  );

  WidgetSpan _textFiled(TextEditingController controller, String hint) =>
      WidgetSpan(
        alignment: PlaceholderAlignment.middle, // set middle according to texts
        child: IntrinsicWidth(
          //flexiable size
          child: TextField(
            style: _textFiledStyle,
            controller: controller,
            decoration: InputDecoration(
              hintStyle: _hintTextStyle,
              hintText: hint,
              border: InputBorder.none,
            ),
          ),
        ),
      );

  @override
  Widget build(BuildContext context) {
    List<TextEditingController> controllers = [];

    List<InlineSpan> textSpans = [];

    _textsInForm.forEach((key, value) {
      if (value != null) {
        TextEditingController controller = TextEditingController();

        controllers.add(controller);
        textSpans.add(_textFiled(controller, key));
      } else {
        textSpans.add(TextSpan(text: "$key "));
      }
    });

    return Scaffold(
      body: Column(
        children: [
          RichText(
            text: TextSpan(children: textSpans),
          ),
          ElevatedButton(
            onPressed: () {
              String result = "";
              int i = 0;

              _textsInForm.forEach((key, value) {
                if (value != null) {
                  final textFromIcontroller = controllers[i++].text;
                  result += "$textFromIcontroller ";
                } else {
                  result += "$key ";
                }
              });

              print(result);
            },
            child: Text("Get Text"),
          ),
        ],
      ),
    );
  }
}

于 2021-10-28T14:18:31.740 回答