You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中如何复制保留文本样式的内容?

解决Flutter复制带字体样式文本丢失格式的问题

问题描述

我实现了一个展示多种Google Fonts字体样式文本的列表,每个列表项配有复制按钮,但复制后只能得到纯文本,原有的字体样式完全丢失(比如带<strong>标签的文本复制后仅保留example_text)。

原因分析

当前代码仅通过ClipboardData(text: ...)向剪贴板写入纯文本数据,没有携带任何样式信息。大部分支持富文本粘贴的应用(如Word、网页编辑器、社交软件)会读取剪贴板中的HTML格式数据来保留样式,而纯文本模式无法传递样式。

解决方案

Flutter 3.3及以上版本的ClipboardData新增了html参数,我们可以同时向剪贴板写入纯文本(作为兼容 fallback)和HTML格式的富文本,以此保留字体样式。

修改后的核心代码

将列表项中复制按钮的onPressed逻辑替换为以下代码:

onPressed: () async {
  // 生成带字体样式的HTML内容
  String fontFamily = _fontFamilies[index];
  // 处理带空格的字体名称,用引号包裹
  String safeFontFamily = fontFamily.contains(' ') ? '"$fontFamily"' : fontFamily;
  String htmlContent = '<span style="font-family: $safeFontFamily, sans-serif; font-size: 30px;">${_textController.text}</span>';

  // 同时写入纯文本和HTML格式到剪贴板
  await Clipboard.setData(ClipboardData(
    text: _textController.text, // 兼容仅支持纯文本的应用
    html: htmlContent, // 传递富文本样式
  ));

  ScaffoldMessenger.of(context).showSnackBar(
    const SnackBar(content: Text('已复制到剪贴板')),
  );
},

完整修改后的代码

import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:google_fonts/google_fonts.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: '字体样式示例',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const FontStylesScreen(),
    );
  }
}

class FontStylesScreen extends StatefulWidget {
  const FontStylesScreen({Key? key});

  @override
  _FontStylesScreenState createState() => _FontStylesScreenState();
}

class _FontStylesScreenState extends State<FontStylesScreen> {
  final TextEditingController _textController = TextEditingController();
  List<String> _fontFamilies = [];

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

  void _getAvailableFonts() {
    final fonts = GoogleFonts.asMap().keys.toList();
    setState(() {
      _fontFamilies = fonts;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('字体样式示例'),
      ),
      body: Column(
        crossAxisAlignment: CrossAxisAlignment.stretch,
        children: [
          Padding(
            padding: const EdgeInsets.all(8.0),
            child: TextField(
              controller: _textController,
              decoration: const InputDecoration(
                labelText: '输入文本',
                border: OutlineInputBorder(),
              ),
              onChanged: (_) {
                setState(() {});
              },
            ),
          ),
          Expanded(
            child: ListView.builder(
              itemCount: _fontFamilies.length,
              itemBuilder: (context, index) {
                return ListTile(
                  title: Text(
                    _textController.text,
                    style: GoogleFonts.getFont(_fontFamilies[index], fontSize: 30),
                  ),
                  trailing: IconButton(
                    icon: const Icon(Icons.copy),
                    onPressed: () async {
                      // 生成带字体样式的HTML内容
                      String fontFamily = _fontFamilies[index];
                      String safeFontFamily = fontFamily.contains(' ') ? '"$fontFamily"' : fontFamily;
                      String htmlContent = '<span style="font-family: $safeFontFamily, sans-serif; font-size: 30px;">${_textController.text}</span>';

                      // 同时写入纯文本和HTML格式到剪贴板
                      await Clipboard.setData(ClipboardData(
                        text: _textController.text,
                        html: htmlContent,
                      ));

                      ScaffoldMessenger.of(context).showSnackBar(
                        const SnackBar(content: Text('已复制到剪贴板')),
                      );
                    },
                  ),
                );
              },
            ),
          ),
        ],
      ),
    );
  }
}

注意事项

  • 该方案依赖目标应用支持HTML格式粘贴,若目标应用仅支持纯文本,仍会显示无样式的文本,但不会影响原有功能。
  • 如果需要添加更多样式(如加粗、斜体、颜色),只需扩展HTML标签的style属性即可,例如:<span style="font-family: ...; font-weight: bold; color: red;">...</span>。

内容的提问来源于stack exchange,提问作者Dhobi Dhruv

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 15:07:31