🚀 Flutter 富文本与按钮点击事件实践教程

在日常的 Flutter UI 开发中,我们经常会遇到需要展示多样式文本的场景,比如"部分文字高亮"、"点击某段文字触发操作"等。这篇文章将通过一个完整的示例,带你一步步了解如何在 Flutter 中使用 RichText 展示富文本,并结合各种按钮组件实现交互功能。demo地址


一、富文本 RichText 基础用法

Flutter 提供了 RichText 和 TextSpan 来支持多样式文本渲染。与普通 Text 不同,RichText 可以让你为一段文字中的不同部分设置不同的样式,甚至加入点击事件。

dart 复制代码
RichText(
  text: TextSpan(
    text: 'Hello ',
    style: TextStyle(color: Colors.black, fontSize: 20),
    children: <TextSpan>[
      TextSpan(
        text: 'Flutter ',
        style: TextStyle(
            color: Colors.blue,
            fontWeight: FontWeight.bold,
            fontSize: 22),
        recognizer: _tapRecognizer, // 添加点击事件
      ),
      TextSpan(
        text: 'World!',
        style: TextStyle(
            color: Colors.red, fontStyle: FontStyle.italic),
      ),
    ],
  ),
),

二、为富文本添加点击事件

我们可以使用 TapGestureRecognizer 来为 TextSpan 添加点击事件:

dart 复制代码
late TapGestureRecognizer _tapRecognizer;

@override
void initState() {
  super.initState();
  _tapRecognizer = TapGestureRecognizer()
    ..onTap = () {
      showDialog(
        context: context,
        builder: (context) => AlertDialog(
          title: Text("提示"),
          content: Text("你点击了 Flutter"),
          actions: [
            TextButton(
              onPressed: () => Navigator.pop(context),
              child: Text("确定"),
            ),
          ],
        ),
      );
    };
}

@override
void dispose() {
  _tapRecognizer.dispose(); // 释放资源,防止内存泄漏
  super.dispose();
}

三、按钮组件演示

Flutter 提供了多种按钮控件,这里我们展示了常见的四种,并实现了点击后更新文字:

  • ElevatedButton
  • TextButton
  • OutlinedButton
  • IconButton
dart 复制代码
ElevatedButton(
  onPressed: () => _handleButtonClick("ElevatedButton"),
  child: Text("ElevatedButton"),
),

TextButton(
  onPressed: () => _handleButtonClick("TextButton"),
  child: Text("TextButton"),
),

OutlinedButton(
  onPressed: () => _handleButtonClick("OutlinedButton"),
  child: Text("OutlinedButton"),
),

IconButton(
  onPressed: () => _handleButtonClick("IconButton"),
  icon: Icon(Icons.favorite, color: Colors.pink),
)

四、完整示例代码(可直接运行)

dart 复制代码
import 'package:flutter/material.dart';
import 'package:flutter/gestures.dart';

class ComponentDemoPage extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => _ComponentDemoPageState();
}

class _ComponentDemoPageState extends State<ComponentDemoPage> {
  String _message = "你还没有点击按钮";
  late TapGestureRecognizer _tapRecognizer;

  TextStyle blackStyle = TextStyle(fontWeight: FontWeight.normal, fontSize: 20, color: Colors.black);
  TextStyle redStyle = TextStyle(fontWeight: FontWeight.bold, fontSize: 20, color: Colors.red);

  @override
  void initState() {
    super.initState();
    _tapRecognizer = TapGestureRecognizer()
      ..onTap = () {
        showDialog(
          context: context,
          builder: (context) => AlertDialog(
            title: Text("提示"),
            content: Text("你点击了 Flutter"),
            actions: [
              TextButton(
                onPressed: () => Navigator.pop(context),
                child: Text("确定"),
              ),
            ],
          ),
        );
      };
  }

  @override
  void dispose() {
    _tapRecognizer.dispose();
    super.dispose();
  }

  void _handleButtonClick(String label) {
    setState(() {
      _message = "你点击了:$label";
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("富文本 & 按钮示例")),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            RichText(
              text: TextSpan(
                text: 'Hello ',
                style: TextStyle(color: Colors.black, fontSize: 20),
                children: <TextSpan>[
                  TextSpan(
                    text: 'Flutter ',
                    style: TextStyle(
                        color: Colors.blue,
                        fontWeight: FontWeight.bold,
                        fontSize: 22),
                    recognizer: _tapRecognizer,
                  ),
                  TextSpan(
                    text: 'World!',
                    style: TextStyle(
                        color: Colors.red, fontStyle: FontStyle.italic),
                  ),
                ],
              ),
            ),
            SizedBox(height: 20),

            Text.rich(
              TextSpan(
                children: [
                  TextSpan(text:'文本是视图系统中常见的控件,它用来显示一段特定样式的字符串,类似', style: redStyle),
                  TextSpan(text:'iOS', style: blackStyle),
                  TextSpan(text:'中的', style: redStyle),
                  TextSpan(text:'UILabel', style: blackStyle),
                ],
              ),
              textAlign: TextAlign.center,
            ),

            SizedBox(height: 30),

            ElevatedButton(
              onPressed: () => _handleButtonClick("ElevatedButton"),
              child: Text("ElevatedButton"),
            ),
            TextButton(
              onPressed: () => _handleButtonClick("TextButton"),
              child: Text("TextButton"),
            ),
            OutlinedButton(
              onPressed: () => _handleButtonClick("OutlinedButton"),
              child: Text("OutlinedButton"),
            ),
            IconButton(
              onPressed: () => _handleButtonClick("IconButton"),
              icon: Icon(Icons.favorite, color: Colors.pink),
            ),
            SizedBox(height: 20),

            Text(
              _message,
              style: TextStyle(fontSize: 16, color: Colors.green),
            ),
          ],
        ),
      ),
    );
  }
}

五、总结

这篇教程向您展示了:

  • 如何在 Flutter 中使用 RichText 和 TextSpan 渲染富文本;
  • 如何使用 TapGestureRecognizer 给文字添加点击事件;
  • 常见按钮组件的使用方法;
  • 如何通过 setState 更新状态和 UI。
相关推荐
棉花糖超人1 分钟前
【从0-1的HTML】第3篇:html引入css的3种方式
前端·css·html
前端付豪10 分钟前
网易推荐系统全揭秘:如何让用户越刷越上头?(附算法逻辑+特征样例+召回实测)
前端·后端·算法
lecepin11 分钟前
前端技术月刊-2025.6
前端·javascript·面试
子洋13 分钟前
半个小时,我开发了个短链接服务
前端·javascript·后端
楠目32 分钟前
安全-JAVA开发-第二天
java·开发语言·前端
我想说一句34 分钟前
React 初体验:从零开始构建你的第一个Web应用
前端·javascript·react.js
前端赵哈哈36 分钟前
允许“HBuilder”拨打电 话和管理通话吗?
前端·uni-app
lyc23333336 分钟前
鸿蒙VS安卓开发对比及迁移指南📱
前端
摆烂工程师36 分钟前
只需 1 美元 薅 ChatGPT Team 的教程,最高5个席位 人均 一块五,附上取消ChatGPT Team 计划 教程
前端·后端·程序员
wordbaby39 分钟前
React Teleporting Data(“数据传递”或“数据穿梭”)浅析
前端·react.js