Flutter自适应文本大小插件text_responsive的使用

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

Flutter自适应文本大小插件text_responsive的使用

Overview

TextResponsiveWidget 是一个用于处理防止文本溢出而不需要显式设置固定字体大小的场景。它会计算并调整所提供的 Text 小部件的字体大小,以适应父小部件定义的可用空间。

Usage

TextResponsiveWidget

将你的 Text 小部件包裹在 TextResponsiveWidget 中,以确保文本大小的响应性。可选地,提供一个 overflowCallback 回调函数,以便在检测到溢出时通知你并调整字体大小。

ParagraphTextWidget & InlineTextWidget

对于段落或行内文本场景,可以分别使用 ParagraphTextWidgetInlineTextWidget。这些小部件提供了相同的响应功能,并专注于它们特定的文本用例。

示例代码

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

const String paragraph =
    'In Flutter, the adaptability of a paragraph to its container is crucial for creating responsive and user-friendly applications. This flexibility ensures that text content optimally fits within varying screen sizes and orientations, enhancing readability and user experience. By automatically adjusting to the container, the paragraph prevents overflow issues and maintains a clean, professional layout. This adaptability is especially important in a mobile-first world, where users access content on a diverse range of devices with different screen dimensions. In summary, an adaptable paragraph in Flutter is key to delivering a seamless and accessible app interface.';

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Text responsive demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  const MyHomePage({super.key});

  @override
  Widget build(BuildContext context) {
    final Size size = MediaQuery.of(context).size;
    const Text text = Text(
      'Here we go!!!!!',
      style: TextStyle(fontSize: 60),
    );
    const Text textName = Text(
      'Jhon Emiliano Doe Belalcazar',
      style: TextStyle(fontSize: 60),
    );

    const Text ellipsisText = Text(
      'Here we go with a very long ellipsis text that maybe has error',
      overflow: TextOverflow.ellipsis,
      style: TextStyle(
        fontSize: 20,
        overflow: TextOverflow.ellipsis,
      ),
    );
    final bloodTypeText = Text(
      'O+',
      textAlign: TextAlign.center,
      style: TextStyle(
          fontSize: MediaQuery.of(context).devicePixelRatio * 100,
          color: Theme.of(context).canvasColor),
    );

    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: const Text('Text responsive demo'),
      ),
      body: ListView(
        children: <Widget>[
          const SizedBox(
            width: double.maxFinite,
            child: Text(
              'First case before: ',
            ),
          ),
          Container(
            width: 50.0,
            height: 50.0,
            color: Colors.orange,
            child: text,
          ),
          const Text(
            'First case after: ',
          ),
          Container(
            width: 500.0,
            height: 50.0,
            color: Colors.orange,
            child: const TextResponsiveWidget(
              child: text,
            ),
          ),
          const TextResponsiveWidget(
            child: Text('Before'),
          ),
          CardExampleWidget(
            textName: textName,
            bloodTypeText: bloodTypeText,
            ellipsisText: ellipsisText,
          ),
          const TextResponsiveWidget(
            child: Text('After: With TextResponsiveWidget'),
          ),
          CardExampleWidget(
            textName: const TextResponsiveWidget(
              child: textName,
            ),
            bloodTypeText: TextResponsiveWidget(child: bloodTypeText),
            ellipsisText: const TextResponsiveWidget(
              child: ellipsisText,
            ),
          ),
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
            children: [
              Container(
                color: Colors.orangeAccent,
                width: size.width * 0.4,
                height: size.height * 0.4,
                child: const Text(
                  paragraph,
                  maxLines: 10,
                  style: TextStyle(fontSize: 50),
                ),
              ),
              Container(
                color: Colors.green,
                width: size.width * 0.4,
                height: size.height * 0.4,
                child: const TextResponsiveWidget(
                  child: Text(
                    paragraph,
                    maxLines: 10,
                    style: TextStyle(fontSize: 50),
                  ),
                ),
              ),
            ],
          ),
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
            children: [
              SizedBox(
                width: size.width * 0.4,
                height: size.height * 0.4,
                child: const InlineTextWidget(
                  paragraph,
                  style: TextStyle(fontSize: 50),
                  overflow: TextOverflow.ellipsis,
                ),
              ),
              SizedBox(
                width: size.width * 0.4,
                height: size.height * 0.4,
                child: const ParagraphTextWidget(
                  paragraph,
                  maxLines: 10,
                  textAlign: TextAlign.justify,
                  style: TextStyle(fontSize: 50),
                ),
              ),
            ],
          ),
        ],
      ),
    );
  }
}

class CardExampleWidget extends StatelessWidget {
  const CardExampleWidget({
    super.key,
    required this.textName,
    required this.ellipsisText,
    required this.bloodTypeText,
  });

  final Widget textName;
  final Widget ellipsisText;
  final Widget bloodTypeText;

  @override
  Widget build(BuildContext context) {
    final Size size = MediaQuery.of(context).size;
    final double cardWidth = size.width * 0.4;
    final double cardHeight = size.height * 0.25;
    final innerWidth = cardWidth * 0.8;
    final innerContainer = cardHeight * 0.5;

    final color = Theme.of(context).canvasColor;
    return Card(
      child: SizedBox(
        width: cardWidth,
        height: cardHeight,
        child: Column(
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
          children: [
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceEvenly,
              children: [
                CircleAvatar(
                  child: Icon(
                    Icons.person,
                    color: color,
                  ),
                ),
                Container(
                  width: innerWidth,
                  height: 50,
                  color: Colors.orangeAccent,
                  child: textName,
                )
              ],
            ),
            SizedBox(
              height: cardHeight * 0.5,
              child: Row(
                mainAxisAlignment: MainAxisAlignment.end,
                children: [
                  const SizedBox(
                    width: 20.0,
                  ),
                  Expanded(
                      child: Container(
                    color: Colors.yellow,
                    child: ellipsisText,
                  )),
                  const SizedBox(
                    width: 20.0,
                  ),
                  const Icon(Icons.bloodtype),
                  const SizedBox(
                    width: 30.0,
                  ),
                  Container(
                    margin: const EdgeInsets.only(right: 25.0),
                    height: innerContainer,
                    width: innerContainer,
                    alignment: Alignment.center,
                    decoration: BoxDecoration(
                        color: Theme.of(context).primaryColorDark,
                        borderRadius: BorderRadius.circular(innerContainer)),
                    child: bloodTypeText,
                  ),
                ],
              ),
            )
          ],
        ),
      ),
    );
  }
}

Features

  • 自动调整字体大小以适应可用空间。
  • 防止文本溢出而不需要显式设置固定字体大小。
  • 可选的回调函数,当检测到溢出时通知你。

Installation

pubspec.yaml 文件中添加以下内容:

dependencies:
  text_responsive: ^latest_version

然后运行:

dart pub get

更多详细信息,请参阅安装指南。

API Reference

TextResponsiveWidget

Constructor

const TextResponsiveWidget({
  required this.child,
  this.overflowCallback,
  Key? key,
});

Parameters

  • child: 要显示并使其响应的文本。
  • overflowCallback: 可选的回调函数,当检测到溢出时调用。

Methods

  • calculateFontSizeToFit: 计算适合可用空间的字体大小。

Contributing

欢迎通过打开问题或提交拉取请求来贡献项目。

License

本项目采用 MIT 许可证,详情请参阅 LICENSE 文件。


更多关于Flutter自适应文本大小插件text_responsive的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter自适应文本大小插件text_responsive的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是一个关于如何在Flutter项目中使用text_responsive插件来实现文本自适应大小的示例代码。text_responsive插件允许你根据屏幕尺寸和布局约束自动调整文本大小。

首先,确保你已经在pubspec.yaml文件中添加了text_responsive依赖:

dependencies:
  flutter:
    sdk: flutter
  text_responsive: ^x.y.z  # 请将x.y.z替换为最新版本号

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

以下是一个完整的示例代码,展示了如何使用text_responsive插件:

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Text Responsive Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        appBar: AppBar(
          title: Text('Text Responsive Example'),
        ),
        body: Center(
          child: ResponsiveTextExample(),
        ),
      ),
    );
  }
}

class ResponsiveTextExample extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        // 使用 ResponsiveText 组件,设置最小和最大字体大小
        ResponsiveText(
          'This is a responsive text.',
          styles: TextStyles(
            min: TextStyle(fontSize: 12),  // 最小字体大小
            max: TextStyle(fontSize: 36),  // 最大字体大小
            stepGranularity: 1.0,          // 调整步长
          ),
          softWrap: true,                 // 是否自动换行
        ),
        SizedBox(height: 20),
        
        // 使用 ResponsiveText.builder 构建响应式文本
        ResponsiveText.builder(
          data: 'Another responsive text with builder.',
          stylesBuilder: (BuildContext context, double screenWidth) {
            return TextStyles(
              min: TextStyle(fontSize: screenWidth * 0.03), // 根据屏幕宽度动态计算最小字体大小
              max: TextStyle(fontSize: screenWidth * 0.1),  // 根据屏幕宽度动态计算最大字体大小
            );
          },
          softWrap: true,
        ),
      ],
    );
  }
}

代码解释

  1. 依赖导入

    • pubspec.yaml文件中添加text_responsive依赖。
  2. 主应用结构

    • 使用MaterialApp作为应用的基础结构。
    • home属性中设置了一个Scaffold,包含一个AppBar和一个居中的Column
  3. ResponsiveText组件

    • 使用ResponsiveText组件来显示响应式文本。
    • TextStyles类用于定义最小和最大字体大小,以及调整步长。
    • softWrap属性设置为true,使文本能够自动换行。
  4. ResponsiveText.builder

    • 使用ResponsiveText.builder方法,根据屏幕宽度动态计算最小和最大字体大小。
    • stylesBuilder回调函数接收一个BuildContext和一个double类型的screenWidth参数,返回TextStyles对象。

通过上述代码,你可以实现文本的自适应大小,使应用在不同设备和屏幕尺寸上表现更加一致和美观。

回到顶部