Flutter圆角背景文本插件rounded_background_text的使用

发布于 1周前 作者 bupafengyu 来自 Flutter

Flutter圆角背景文本插件rounded_background_text的使用

内容目录

Features

  • ✅ Highlight Text
  • ✅ Highlight Text Field
  • ✅ Highlight Text Span

Getting started

要开始使用rounded_background_text,首先需要导入这个包:

import 'package:rounded_background_text/rounded_background_text.dart';

Usage

Highlight a simple text

你可以通过RoundedBackgroundText来创建一个带有圆角背景的简单文本。以下是一个简单的例子:

RoundedBackgroundText(
  'A cool text to be highlighted',
  style: const TextStyle(fontWeight: FontWeight.bold),
  backgroundColor: Colors.white,
),

支持多行文本:

RoundedBackgroundText(
  'A cool text to be highlighted\nWith two lines or more',
  style: const TextStyle(fontWeight: FontWeight.bold),
  backgroundColor: Colors.amber,
),

Highlight a text field

对于文本框,你必须使用TextEditingController来控制输入内容,并且可以通过RoundedBackgroundTextField来实现圆角背景高亮效果。

RoundedBackgroundTextField(
  backgroundColor: Colors.blue,
  style: const TextStyle(fontWeight: FontWeight.bold),
  textAlign: TextAlign.center,
),

用户输入时文本会自动被高亮显示:

Highlight a text span

如果你想只对一段文本中的部分内容进行高亮,可以使用RoundedBackgroundTextSpan

RichText(
  text: TextSpan(
    text: 'Start your text and ',
    children: [
      RoundedBackgroundTextSpan(
        text: 'highlight something',
        backgroundColor: Colors.blue,
      ),
      const TextSpan(text: ' when necessary'),
    ],
  ),
),

You may like to know

Change the corner radius

你可以通过设置innerRadiusouterRadius来自定义圆角大小:

RoundedBackgroundText(
  'A cool text to be highlighted',
  style: const TextStyle(fontWeight: FontWeight.bold),
  backgroundColor: Colors.white,
  innerRadius: 15.0,
  outerRadius: 10.0,
),

最大允许值为20.0,最小为0.0。

Deep dive

RoundedBackgroundText不直接使用Flutter的Text组件,而是通过自定义绘制器在文本下方绘制背景。它根据文本的行度量信息(line metrics)计算出每一行的位置和尺寸,然后基于这些信息绘制出合适的背景形状。这确保了即使在多行或不同宽度的情况下也能正确地应用圆角背景。

Contribution

如果你发现了问题或者有改进建议,欢迎提交issue或pull request。所有贡献都是受欢迎的!

示例Demo

为了更直观地理解如何使用rounded_background_text,下面提供了一个完整的示例代码,展示了如何创建一个包含多种类型文本高亮的应用程序:

import 'dart:math';

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

final _primaryAndAccentColors = [...Colors.primaries, ...Colors.accents];

enum _HighlightTextType { field, text, span, selectableText }

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

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  late final ScrollController colorsController;
  final controller = TextEditingController();

  double fontSize = 20.0;
  double innerRadius = kDefaultInnerRadius;
  double outerRadius = kDefaultOuterRadius;

  TextAlign textAlign = TextAlign.center;
  FontWeight fontWeight = FontWeight.bold;
  _HighlightTextType type = _HighlightTextType.text;

  late Color selectedColor;

  @override
  void initState() {
    super.initState();

    final initialIndex = Random().nextInt(_primaryAndAccentColors.length);
    selectedColor = _primaryAndAccentColors[initialIndex];

    colorsController = ScrollController(
      initialScrollOffset: 40.0 * initialIndex,
    );
  }

  @override
  void dispose() {
    controller.dispose();
    colorsController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Rounded Background Showcase',
      theme: ThemeData(primarySwatch: Colors.blue, brightness: Brightness.dark),
      home: Scaffold(
        body: SafeArea(
          child: Column(children: [
            Material(
              child: Row(children: [
                const VerticalDivider(),
                Expanded(
                  child: DropdownButton<FontWeight>(
                    isExpanded: true,
                    value: fontWeight,
                    onChanged: (w) => setState(
                      () => fontWeight = w ?? FontWeight.normal,
                    ),
                    icon: const Icon(Icons.format_bold),
                    items: FontWeight.values.map((e) {
                      return DropdownMenuItem(
                        value: e,
                        child: Text('$e'.replaceAll('FontWeight.', '')),
                      );
                    }).toList(),
                  ),
                ),
                const VerticalDivider(),
                Expanded(
                  child: DropdownButton<TextAlign>(
                    value: textAlign,
                    onChanged: (align) => setState(
                      () => textAlign = align ?? TextAlign.center,
                    ),
                    icon: Icon(() {
                      switch (textAlign) {
                        case TextAlign.center:
                          return Icons.format_align_center;
                        case TextAlign.end:
                        case TextAlign.right:
                          return Icons.format_align_right;
                        case TextAlign.start:
                        case TextAlign.left:
                          return Icons.format_align_left;
                        default:
                          return null;
                      }
                    }()),
                    isExpanded: true,
                    items: const [
                      DropdownMenuItem(
                        value: TextAlign.start,
                        child: Text('Start'),
                      ),
                      DropdownMenuItem(
                        value: TextAlign.center,
                        child: Text('Center'),
                      ),
                      DropdownMenuItem(
                        value: TextAlign.end,
                        child: Text('End'),
                      ),
                    ],
                  ),
                ),
                const VerticalDivider(),
                Expanded(
                  child: DropdownButton<_HighlightTextType>(
                    value: type,
                    onChanged: (t) => setState(
                      () => type = t ?? _HighlightTextType.field,
                    ),
                    icon: const Icon(Icons.text_fields),
                    isExpanded: true,
                    items: const [
                      DropdownMenuItem(
                        value: _HighlightTextType.field,
                        child: Text('Field'),
                      ),
                      DropdownMenuItem(
                        value: _HighlightTextType.text,
                        child: Text('Text'),
                      ),
                      DropdownMenuItem(
                        value: _HighlightTextType.selectableText,
                        child: Text('Selectable Text'),
                      ),
                      DropdownMenuItem(
                        value: _HighlightTextType.span,
                        child: Text('Span'),
                      ),
                    ],
                  ),
                ),
                const VerticalDivider(),
              ]),
            ),
            Expanded(
              child: Padding(
                padding: const EdgeInsets.all(12.0),
                child: Center(
                  child: () {
                    final textColor = selectedColor.computeLuminance() > 0.5
                        ? Colors.black
                        : Colors.white;
                    switch (type) {
                      case _HighlightTextType.field:
                        return RoundedBackgroundTextField(
                          controller: controller,
                          backgroundColor: selectedColor,
                          textAlign: textAlign,
                          hint: 'Type your text here',
                          style: TextStyle(
                            fontSize: fontSize,
                            fontWeight: fontWeight,
                            color: textColor,
                          ),
                          innerRadius: innerRadius,
                          outerRadius: outerRadius,
                        );
                      case _HighlightTextType.text:
                        return RoundedBackgroundText(
                          '''Rounded Background Text Showcase
It handles well all font sizes and weights, as well as text alignments
Contributions are welcome!
Done with so much <3 by @bdlukaa''',
                          backgroundColor: selectedColor,
                          textAlign: textAlign,
                          style: TextStyle(
                            fontSize: fontSize,
                            fontWeight: fontWeight,
                            color: textColor,
                          ),
                          innerRadius: innerRadius,
                          outerRadius: outerRadius,
                        );
                      case _HighlightTextType.selectableText:
                        return RoundedBackgroundText.selectable(
                          '''Rounded Background Text Showcase

It handles well all font sizes and weights, as well as text alignments
Contributions are welcome!
Done with so much <3 by @bdlukaa''',
                          backgroundColor: selectedColor,
                          textAlign: textAlign,
                          style: TextStyle(
                            fontSize: fontSize,
                            fontWeight: fontWeight,
                            color: textColor,
                          ),
                          innerRadius: innerRadius,
                          outerRadius: outerRadius,
                        );
                      case _HighlightTextType.span:
                        return RichText(
                          textAlign: textAlign,
                          text: TextSpan(
                            text: 'You can use this to ',
                            style: TextStyle(
                              fontSize: fontSize,
                              fontWeight: fontWeight,
                              color: Colors.white,
                            ),
                            children: [
                              RoundedBackgroundTextSpan(
                                text: 'highlight important stuff inside a text',
                                backgroundColor: selectedColor,
                                innerRadius: innerRadius,
                                outerRadius: outerRadius,
                                textAlign: textAlign,
                                style: TextStyle(
                                  fontSize: fontSize,
                                  fontWeight: fontWeight,
                                  color: textColor,
                                ),
                              ),
                              const TextSpan(text: ' and stuff like that'),
                            ],
                          ),
                        );
                    }
                  }(),
                ),
              ),
            ),
            Row(children: [
              GestureDetector(
                onTap: () {
                  colorsController.animateTo(
                    (colorsController.position.pixels - 40),
                    duration: const Duration(milliseconds: 300),
                    curve: Curves.ease,
                  );
                },
                child: const Icon(Icons.chevron_left),
              ),
              const Spacer(),
              GestureDetector(
                onTap: () {
                  colorsController.animateTo(
                    (colorsController.position.pixels + 40),
                    duration: const Duration(milliseconds: 300),
                    curve: Curves.ease,
                  );
                },
                child: const Icon(Icons.chevron_right),
              ),
            ]),
            Material(
              child: SingleChildScrollView(
                controller: colorsController,
                padding: const EdgeInsets.only(left: 8.0, right: 8.0, top: 8.0),
                scrollDirection: Axis.horizontal,
                child: Wrap(
                  runSpacing: 10.0,
                  spacing: 10.0,
                  alignment: WrapAlignment.center,
                  children: _primaryAndAccentColors.map((color) {
                    return MouseRegion(
                      cursor: SystemMouseCursors.click,
                      child: GestureDetector(
                        onTap: () => setState(() => selectedColor = color),
                        child: AnimatedContainer(
                          duration: kThemeChangeDuration,
                          curve: Curves.bounceInOut,
                          height: 30.0,
                          width: 30.0,
                          decoration: BoxDecoration(
                            color: color,
                            borderRadius: BorderRadius.circular(2.0),
                            border: Border.all(
                              color: color.computeLuminance() > 0.5
                                  ? Colors.black
                                  : Colors.white,
                              width: 2.5,
                              style: selectedColor == color
                                  ? BorderStyle.solid
                                  : BorderStyle.none,
                            ),
                          ),
                        ),
                      ),
                    );
                  }).toList(),
                ),
              ),
            ),
            Material(
              child: Row(children: [
                Expanded(
                  child: Slider(
                    onChanged: (v) => setState(() => fontSize = v),
                    value: fontSize,
                    min: 8,
                    max: 30,
                    divisions: 30 - 8,
                    label: '${fontSize.toInt()}',
                  ),
                ),
                Expanded(
                  child: Slider(
                    onChanged: (v) => setState(() => innerRadius = v),
                    value: innerRadius,
                    min: 0,
                    max: 20,
                    label: '${innerRadius.toInt()}',
                    divisions: 20,
                  ),
                ),
                Expanded(
                  child: Slider(
                    onChanged: (v) => setState(() => outerRadius = v),
                    value: outerRadius,
                    min: 0,
                    max: 20,
                    label: '${outerRadius.toInt()}',
                    divisions: 20,
                  ),
                ),
              ]),
            ),
          ]),
        ),
      ),
    );
  }
}

这段代码演示了如何动态改变字体样式、颜色、文本类型以及调整圆角半径等操作。希望对你有所帮助!


更多关于Flutter圆角背景文本插件rounded_background_text的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter圆角背景文本插件rounded_background_text的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter中使用rounded_background_text插件来创建圆角背景文本的示例代码。首先,确保你已经在pubspec.yaml文件中添加了rounded_background_text依赖项:

dependencies:
  flutter:
    sdk: flutter
  rounded_background_text: ^最新版本号  # 请替换为实际可用的最新版本号

然后,运行flutter pub get来安装依赖项。

以下是一个完整的Flutter应用示例,展示了如何使用rounded_background_text插件:

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Rounded Background Text Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Rounded Background Text Example'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            RoundedBackgroundText(
              text: 'Hello, Flutter!',
              style: TextStyle(color: Colors.white, fontSize: 24),
              backgroundColor: Colors.blue,
              cornerRadius: 20.0,
              padding: EdgeInsets.all(16.0),
              border: Border.all(color: Colors.white, width: 2.0),
            ),
            SizedBox(height: 20.0),
            RoundedBackgroundText(
              text: 'This is a longer text to see how it wraps inside the rounded background.',
              style: TextStyle(color: Colors.black, fontSize: 18),
              backgroundColor: Colors.lightGreen,
              cornerRadius: 15.0,
              padding: EdgeInsets.symmetric(horizontal: 20.0, vertical: 10.0),
              maxWidth: 250.0,  // Optionally set a max width
              border: Border.none,  // No border in this example
            ),
          ],
        ),
      ),
    );
  }
}

代码解释

  1. 依赖项导入

    import 'package:rounded_background_text/rounded_background_text.dart';
    
  2. 创建应用

    void main() {
      runApp(MyApp());
    }
    
  3. 主应用组件

    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Rounded Background Text Example',
          theme: ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: MyHomePage(),
        );
      }
    }
    
  4. 主页组件

    class MyHomePage extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text('Rounded Background Text Example'),
          ),
          body: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                RoundedBackgroundText(
                  text: 'Hello, Flutter!',
                  style: TextStyle(color: Colors.white, fontSize: 24),
                  backgroundColor: Colors.blue,
                  cornerRadius: 20.0,
                  padding: EdgeInsets.all(16.0),
                  border: Border.all(color: Colors.white, width: 2.0),
                ),
                SizedBox(height: 20.0),
                RoundedBackgroundText(
                  text: 'This is a longer text to see how it wraps inside the rounded background.',
                  style: TextStyle(color: Colors.black, fontSize: 18),
                  backgroundColor: Colors.lightGreen,
                  cornerRadius: 15.0,
                  padding: EdgeInsets.symmetric(horizontal: 20.0, vertical: 10.0),
                  maxWidth: 250.0,
                  border: Border.none,
                ),
              ],
            ),
          ),
        );
      }
    }
    

参数解释

  • text: 要显示的文本。
  • style: 文本的样式。
  • backgroundColor: 背景颜色。
  • cornerRadius: 圆角的半径。
  • padding: 文本周围的填充。
  • border: 边框样式。
  • maxWidth: 可选参数,设置文本的最大宽度。

这个示例展示了如何使用rounded_background_text插件来创建具有圆角背景的文本,并提供了自定义样式和属性的选项。你可以根据需要调整这些参数来适应你的应用设计。

回到顶部