簡體   English   中英

如何向 flutter 中的文本字段添加小部件,如芯片或容器

[英]How to add a widget, like a chip or container, to a textfield in flutter

我有一個將由用戶填寫的文本字段小部件。 問題是除了填寫文本之外,用戶還應該能夠從可以添加到文本之間(或結尾)的標簽列表中進行選擇,示例如圖所示(圖中我有使用了兩個文本小部件和一個芯片,在實際情況下它將是一個文本字段而不是文本小部件)。

在此處輸入圖像描述

這里的解決方案不滿足要求,因為它只添加了籌碼而不是文本。 我還檢查了擴展文本字段package 它也沒有解決。 知道如何解決這個問題嗎?

使用 package extended_text_field package。

結果

只要有@符號,它就會在Chip中:

在此處輸入圖像描述

您需要擴展SpecialTextSpanBuilder並覆蓋build

class MySpecialTextSpanBuilder extends SpecialTextSpanBuilder {
  @override
  TextSpan build(String data,
      {TextStyle? textStyle, SpecialTextGestureTapCallback? onTap}) {
    final lookingFor = "@";
    final splitData = data.split(" ");
    final spans = splitData.map((e) {
      if (e == lookingFor) {
        return WidgetSpan(
          child: Chip(
            label: Text(e),
          ),
        );
      } else {
        return TextSpan(
          text: e,
          style: TextStyle(color: Colors.red),
        );
      }
    }).toList();
    return TextSpan(children: spans, style: textStyle);
  }

  @override
  SpecialText? createSpecialText(String flag,
      {TextStyle? textStyle,
      SpecialTextGestureTapCallback? onTap,
      required int index}) {
    // TODO: implement createSpecialText
    throw UnimplementedError();
  }
}

在此代碼中,如果文本包含@符號,那么我們將使用該數據創建一個Chip ,否則,我們將添加實際文本。

要使用創建的MySpecialTextSpanBuilder class:

Scaffold(
          backgroundColor: Colors.blue,
          body: ExtendedTextField(
            style: TextStyle(color: Colors.red),
            decoration: InputDecoration(
              border: OutlineInputBorder(),
            ),
            specialTextSpanBuilder: MySpecialTextSpanBuilder(),
          ),
        )

完整的可運行片段:

import 'package:extended_text_field/extended_text_field.dart';
import 'package:flutter/material.dart';

const Color darkBlue = Color.fromARGB(255, 18, 32, 47);

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(
        dividerColor: Colors.green,
        scaffoldBackgroundColor: darkBlue,
      ),
      debugShowCheckedModeBanner: false,
      home: SafeArea(
        child: Scaffold(
          backgroundColor: Colors.blue,
          body: ExtendedTextField(
            cursorColor: Colors.black,
            style: TextStyle(color: Colors.red),
            decoration: InputDecoration(
              border: OutlineInputBorder(),
            ),
            specialTextSpanBuilder: MySpecialTextSpanBuilder(),
          ),
        ),
      ),
    );
  }
}

class MySpecialTextSpanBuilder extends SpecialTextSpanBuilder {
  @override
  TextSpan build(String data,
      {TextStyle? textStyle, SpecialTextGestureTapCallback? onTap}) {
    final lookingFor = "@";
    final splitData = data.split(" ");
    final spans = splitData.map((e) {
      if (e == lookingFor) {
        return WidgetSpan(
          child: Chip(
            label: Text(e),
          ),
        );
      } else {
        return TextSpan(
          text: e,
          style: TextStyle(color: Colors.red),
        );
      }
    }).toList();
    return TextSpan(children: spans, style: textStyle);
  }

  @override
  SpecialText? createSpecialText(String flag,
      {TextStyle? textStyle,
      SpecialTextGestureTapCallback? onTap,
      required int index}) {
    // TODO: implement createSpecialText
    throw UnimplementedError();
  }
}

使用Text小部件

您可以將RichTextWidgetSpan作為子項一起使用:

內嵌在文本中的不可變小部件。

結果

在此處輸入圖像描述

代碼

RichText(
      text: TextSpan(
        children: [
          TextSpan(
            text: "one",
          ),
          WidgetSpan(
            child: Chip(
              label: Text("two"),
            ),
          ),
          TextSpan(
            text: "three",
          ),
        ],
      ),
    )

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM